├── .gitignore
├── Template-Cloud-Functions.yml
├── templates
├── RHEL
│ ├── ifcfg-rhel.j2
│ ├── firstboot-rhel.sh.j2
│ ├── cloud-set-guest-sshkey-rhel.j2
│ ├── cloud-run-userdata-rhel.j2
│ └── cloud-set-guest-password-rhel.j2
├── Generic
│ ├── motd.j2
│ ├── motd-datapipe.j2
│ ├── cloud-set-guest-sshkey
│ ├── cloud-set-rhn-systemid
│ ├── cloud-common-functions.j2
│ ├── cloud-set-guest-password
│ └── cloud-get-userdata
├── upstart
│ ├── firstboot.upstart.j2
│ ├── run-userdata.upstart.j2
│ ├── set-guest-sshkey.upstart.j2
│ └── set-guest-password.upstart.j2
├── systemd
│ ├── run-userdata.systemd.j2
│ ├── firstboot.systemd.j2
│ ├── set-guest-sshkey.systemd.j2
│ └── set-guest-password.systemd.j2
├── FreeBSD
│ ├── firstboot-rc.j2
│ ├── cloud-userdata-rc.j2
│ ├── cloud-sshkey-rc.j2
│ ├── cloud-password-rc.j2
│ ├── cloud-set-guest-sshkey-freebsd.j2
│ ├── firstboot-freebsd.j2
│ ├── cloud-run-userdata-freebsd.j2
│ └── cloud-set-guest-password-freebsd.j2
├── Debian
│ ├── ifcfg-debian.j2
│ ├── cloud-set-guest-sshkey-debian.j2
│ ├── firstboot-debian.sh.j2
│ ├── cloud-run-userdata-debian.j2
│ └── cloud-set-guest-password-debian.j2
├── SLES
│ ├── cloud-set-guest-sshkey-sles.j2
│ └── cloud-set-guest-password-sles.j2
└── Ubuntu
│ ├── cloud-set-guest-sshkey-ubuntu.j2
│ └── cloud-set-guest-password-ubuntu.j2
├── Template-Test-Init-System.yml
├── Template-Packages-FreeBSD.yml
├── Template-Packages-SUSE.yml
├── Template-Networking.yml
├── Readme.md
├── Test-Init.yml
├── Template-Clean-Logs.yml
├── Template-Packages-RHEL.yml
├── .kitchen.yml
├── Template-Cloud-Firstboot.yml
├── Template-Cloud-Userdata.yml
├── hosts
├── Template-Packages-Debian.yml
├── Template-Cloud-SSH-Key.yml
├── Template-Cloud-Password.yml
├── Template.yml
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .kitchen/
2 | .kitchen.local.yml
3 | hosts
4 |
--------------------------------------------------------------------------------
/Template-Cloud-Functions.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: add cloud-common-functions script
3 | template: src=templates/Generic/cloud-common-functions.j2 dest=/usr/share/cloudstack/cloudstack-common-functions mode=0755
--------------------------------------------------------------------------------
/templates/RHEL/ifcfg-rhel.j2:
--------------------------------------------------------------------------------
1 | TYPE=Ethernet
2 | DEVICE={{adapter_name.stdout}}
3 | NAME={{adapter_name.stdout}}
4 | BOOTPROTO=dhcp
5 | DEFROUTE=yes
6 | PEERDNS=yes
7 | PEERROUTES=yes
8 | IPV4_FAILURE_FATAL=yes
9 | IPV6INIT=no
10 | ONBOOT=yes
11 | NM_CONTROLLED=yes
12 |
--------------------------------------------------------------------------------
/templates/Generic/motd.j2:
--------------------------------------------------------------------------------
1 | ___ _ _ __ _ _
2 | / __\ | ___ _ _ __| / _\ |_ __ _ ___| | __
3 | / / | |/ _ \| | | |/ _` \ \| __/ _` |/ __| |/ /
4 | / /___| | (_) | |_| | (_| |\ \ || (_| | (__| <
5 | \____/|_|\___/ \__,_|\__,_\__/\__\__,_|\___|_|\_\
6 |
7 |
--------------------------------------------------------------------------------
/templates/upstart/firstboot.upstart.j2:
--------------------------------------------------------------------------------
1 | # cloudstack-set-guest-sshkey
2 |
3 | description "Initial setup of instance."
4 |
5 | start on (startup and
6 | started networking and
7 | starting ssh)
8 |
9 | task
10 | exec /usr/share/cloudstack/cloudstack-firstboot start
11 |
--------------------------------------------------------------------------------
/templates/upstart/run-userdata.upstart.j2:
--------------------------------------------------------------------------------
1 | # cloudstack-set-guest-sshkey
2 |
3 | description "run userdata from CloudStack metadata"
4 |
5 | start on (startup and
6 | started networking and
7 | starting ssh)
8 |
9 | task
10 | exec /usr/share/cloudstack/cloudstack-run-userdata start
11 |
--------------------------------------------------------------------------------
/templates/upstart/set-guest-sshkey.upstart.j2:
--------------------------------------------------------------------------------
1 | # cloudstack-set-guest-sshkey
2 |
3 | description "set root sshkeys from CloudStack metadata"
4 |
5 | start on (startup and
6 | started networking and
7 | starting ssh)
8 |
9 | task
10 | exec /usr/share/cloudstack/cloudstack-set-guest-sshkey start
--------------------------------------------------------------------------------
/templates/upstart/set-guest-password.upstart.j2:
--------------------------------------------------------------------------------
1 | # cloudstack-set-guest-password
2 |
3 | description "set root password from CloudStack metadata"
4 |
5 | start on (startup and
6 | started networking and
7 | starting ssh)
8 |
9 | task
10 | exec /usr/share/cloudstack/cloudstack-set-guest-password start
--------------------------------------------------------------------------------
/templates/systemd/run-userdata.systemd.j2:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=CloudStack User Data
3 | After=network.target
4 |
5 | [Service]
6 | Type=oneshot
7 | ExecStart=/usr/share/cloudstack/cloudstack-run-userdata start
8 |
9 | [Install]
10 | WantedBy=multi-user.target
11 |
12 | # This service file runs the cloudstack userdata
13 |
--------------------------------------------------------------------------------
/templates/systemd/firstboot.systemd.j2:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=CloudStack First Boot
3 | After=network.target
4 | Before=sshd.service
5 |
6 | [Service]
7 | Type=oneshot
8 | ExecStart=/usr/share/cloudstack/cloudstack-firstboot
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
13 | # This service file runs the firstboot-cloudstack
14 |
--------------------------------------------------------------------------------
/templates/FreeBSD/firstboot-rc.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # PROVIDE: cloudstack_firstboot
3 | # REQUIRE: DAEMON networking
4 | # BEFORE: LOGIN
5 | # KEYWORD: nojail
6 |
7 | . /etc/rc.subr
8 |
9 | name=cloudstack_firstboot
10 | rcvar=cloudstack_firstboot_enable
11 |
12 | command="/usr/share/cloudstack/${name}"
13 |
14 | load_rc_config $name
15 | run_rc_command "$1"
--------------------------------------------------------------------------------
/templates/FreeBSD/cloud-userdata-rc.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # PROVIDE: cloudstack_run_userdata
3 | # REQUIRE: DAEMON networking
4 | # BEFORE: LOGIN
5 | # KEYWORD: nojail
6 |
7 | . /etc/rc.subr
8 |
9 | name=cloudstack_run_userdata
10 | rcvar=cloudstack_run_userdata_enable
11 |
12 | command="/usr/share/cloudstack/${name}"
13 |
14 | load_rc_config $name
15 | run_rc_command "$1"
--------------------------------------------------------------------------------
/templates/Generic/motd-datapipe.j2:
--------------------------------------------------------------------------------
1 | _____ _______ _____ _____ _____ ______
2 | | __ \ /\|__ __|/\ | __ \_ _| __ \| ____|
3 | | | | | / \ | | / \ | |__) || | | |__) | |__
4 | | | | |/ /\ \ | | / /\ \ | ___/ | | | ___/| __|
5 | | |__| / ____ \| |/ ____ \| | _| |_| | | |____
6 | |_____/_/ \_\_/_/ \_\_| |_____|_| |______|
7 |
8 |
9 |
--------------------------------------------------------------------------------
/templates/Debian/ifcfg-debian.j2:
--------------------------------------------------------------------------------
1 | # This file describes the network interfaces available on your system
2 | # and how to activate them. For more information, see interfaces(5).
3 |
4 | # The loopback network interface
5 | auto lo
6 | iface lo inet loopback
7 |
8 | # The primary network interface
9 | auto {{adapter_name.stdout}}
10 | iface {{adapter_name.stdout}} inet dhcp
11 |
--------------------------------------------------------------------------------
/templates/FreeBSD/cloud-sshkey-rc.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # PROVIDE: cloudstack_set_guest_sshkey
3 | # REQUIRE: DAEMON networking
4 | # BEFORE: LOGIN
5 | # KEYWORD: nojail
6 |
7 | . /etc/rc.subr
8 |
9 | name=cloudstack_set_guest_sshkey
10 | rcvar=cloudstack_set_guest_sshkey_enable
11 |
12 | command="/usr/share/cloudstack/${name}"
13 |
14 | load_rc_config $name
15 | run_rc_command "$1"
--------------------------------------------------------------------------------
/templates/FreeBSD/cloud-password-rc.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # PROVIDE: cloudstack_set_guest_password
3 | # REQUIRE: DAEMON networking
4 | # BEFORE: LOGIN
5 | # KEYWORD: nojail
6 |
7 | . /etc/rc.subr
8 |
9 | name=cloudstack_set_guest_password
10 | rcvar=cloudstack_set_guest_password_enable
11 |
12 | command="/usr/share/cloudstack/${name}"
13 |
14 | load_rc_config $name
15 | run_rc_command "$1"
--------------------------------------------------------------------------------
/templates/systemd/set-guest-sshkey.systemd.j2:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=CloudStack Guest SSH Key Reset
3 | After=network.target local-fs.target
4 | Before=sshd.service
5 |
6 | [Service]
7 | Type=oneshot
8 | ExecStart=/usr/share/cloudstack/cloudstack-set-guest-sshkey start
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
13 | # This service file runs the cloudstack-set-guest-password
14 |
--------------------------------------------------------------------------------
/templates/systemd/set-guest-password.systemd.j2:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=CloudStack Guest Password Reset
3 | After=network.target local-fs.target
4 | Before=sshd.service
5 |
6 | [Service]
7 | Type=oneshot
8 | ExecStart=/usr/share/cloudstack/cloudstack-set-guest-password start
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
13 | # This service file runs the cloudstack-set-guest-password
14 |
--------------------------------------------------------------------------------
/Template-Test-Init-System.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: test for systemd
3 | stat: path=/etc/systemd/system get_md5=no
4 | register: systemd
5 |
6 | - name: test for upstart
7 | stat: path=/lib/init/upstart-job get_md5=no
8 | register: upstart
9 |
10 | - name: test for FreeBSD
11 | when: ansible_os_family == "FreeBSD"
12 | stat: path=/etc/rc.conf get_md5=no
13 | register: fbsd
14 |
15 | # - debug: var=systemd
16 | # ignore_errors: true
17 | # - debug: var=upstart
18 | # ignore_errors: true
19 | # - debug: var=fbsd
20 | # ignore_errors: true
--------------------------------------------------------------------------------
/Template-Packages-FreeBSD.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install "core" packages (FreeBSD)
3 | when: ansible_os_family == "FreeBSD"
4 | pkgng: name={{ item }} state=present
5 | with_items:
6 | - vim
7 | - screen
8 | - tmux
9 | - curl
10 | - wget
11 | - lynx
12 | - links
13 | - sudo
14 | - bash
15 | - git
16 | - rsyslog
17 | - rsync
18 | - nmap
19 | - netcat
20 | - bind-tools
21 | - htop
22 | - linux_base-c6
23 | - name: update packages (FreeBSD)
24 | when: ansible_os_family == "FreeBSD"
25 | command: pkg upgrade -y
--------------------------------------------------------------------------------
/Template-Packages-SUSE.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install "core" packages (SUSE)
3 | when: ansible_os_family == "Suse"
4 | zypper: name={{ item }} state=latest
5 | with_items:
6 | - vim
7 | - screen
8 | - tmux
9 | - curl
10 | - wget
11 | - lynx
12 | - links
13 | - sudo
14 | - git
15 | - rsyslog
16 | - rsync
17 | - nmap
18 | - netcat-openbsd
19 | - strace
20 | - bind-utils
21 | - iotop
22 | - name: update system (SUSE)
23 | when: ansible_os_family == "Suse"
24 | command: zypper update -y
25 | - name: set timezone to UTC (SUSE)
26 | when: ansible_os_family == "Suse"
27 | shell: "rm -f /etc/localtime && ln -s /usr/share/zoneinfo/UTC /etc/localtime"
28 |
--------------------------------------------------------------------------------
/Template-Networking.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: register primary network adapter name
3 | when: ansible_os_family != "FreeBSD"
4 | shell: "ip link | grep UP | grep -v LOOPBACK | awk -F':' '{print $2}' | tr -d ' '"
5 | register: adapter_name
6 |
7 | - name: setup networking (RHEL)
8 | when: ansible_os_family == "RedHat"
9 | template: src=templates/RHEL/ifcfg-rhel.j2 dest=/etc/sysconfig/network-scripts/ifcfg-{{adapter_name.stdout}} mode=0644
10 |
11 | - name: remove udev network naming (RHEL)
12 | when: ansible_os_family == "RedHat"
13 | file: path=/etc/udev/rules.d/70-persistent-net.rules state=absent
14 |
15 | - name: setup networking (Debian)
16 | when: ansible_os_family == "Debian"
17 | template: src=templates/Debian/ifcfg-debian.j2 dest=/etc/network/interfaces mode=0644
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | CloudStack-Template
2 | ===================
3 |
4 | ## Ansible Playbook for creating CloudStack templates
5 |
6 | These plays have been tested and work against:
7 | * Red Hat Enterprise Linux (and derivatives [Scientific/Centos/Oracle])
8 | * 5
9 | * 6
10 | * 7
11 | * Debian Linux
12 | * 6
13 | * 7
14 | * Ubuntu Linux
15 | * 10.04 LTS
16 | * 12.04 LTS
17 | * 14.04 LTS
18 |
19 | To execute the Playbook, you need to have Ansible installed on the local workstation. Instructions for installing Ansible are available [here](http://docs.ansible.com/intro_installation.html).
20 |
21 | Once Ansible is installed, you will need to modify the hosts file to reflect the IP addresses, passwords, and possibly SSH ports needed to connect to the instance and perform the configuration.
22 |
23 | The Playbook is executed by having this directory as your current working directory and executing: ansible-playbook -i ./hosts ./Template.yml
24 |
25 | ### What this Playbook provides
26 |
27 | This playbook:
28 | * installs a suite of standard packages across all distributions, including curl, wget, lynx, screen, and tmux.
29 | * sets up new init scripts (which work under init and upstart. systemd support is coming soon.) for SSH keys, passwords, and user data execution.
30 | * sets up a new Firstboot script to set up networking, hostsfile, and set the hostname according to DHCP
31 | * cleans out old log files
32 | * cleans out old ssh host keys
33 | * sets a MOTD splash
34 |
--------------------------------------------------------------------------------
/Test-Init.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 | tasks:
4 | - name: create directory to store cloudstack client scripts
5 | file: state=directory mode=0755 path=/usr/share/cloudstack
6 |
7 | - name: register init system variables
8 | include: Template-Test-Init-System.yml
9 |
10 | - name: setup common functions for init scripts
11 | include: Template-Cloud-Functions.yml
12 |
13 | - name: setup cloudstack-set-guest-password
14 | include: Template-Cloud-Password.yml
15 | - name: setup cloudstack-set-guest-sshkey
16 | include: Template-Cloud-SSH-Key.yml
17 | - name: setup cloudstack-run-userdata
18 | include: Template-Cloud-Userdata.yml
19 | - name: setup cloudstack-firstboot
20 | include: Template-Cloud-Firstboot.yml
21 |
22 | - name: register upstart services
23 | when: upstart.stat.exists == true and systemd.stat.exists == false
24 | shell: initctl reload-configuration
25 | - name: register systemd services
26 | when: upstart.stat.exists == false and systemd.stat.exists == true
27 | shell: systemctl daemon-reload
28 |
29 | - name: enable cloudstack-password service
30 | service: name=cloudstack-set-guest-password enabled=yes
31 | - name: enable cloudstack-sshkey service
32 | service: name=cloudstack-set-guest-sshkey enabled=yes
33 | - name: enable cloudstack-userdata service
34 | service: name=cloudstack-run-userdata enabled=yes
35 | # - name: enable firstboot-cloudstack service
36 | # service: name=cloudstack-firstboot enabled=yes
37 |
--------------------------------------------------------------------------------
/templates/FreeBSD/cloud-set-guest-sshkey-freebsd.j2:
--------------------------------------------------------------------------------
1 | #!/usr/local/bin/bash
2 | # FreeBSD
3 | # Modify this line to specify the user (default is root)
4 | user=root
5 |
6 | WGET=/usr/local/bin/wget
7 |
8 | keys_received=0
9 | file_count=0
10 |
11 | . /usr/share/cloudstack/cloudstack-common-functions
12 | find_lease
13 |
14 | SSHKEY_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
15 |
16 | if [ -n $SSHKEY_SERVER_IP ]; then
17 | logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP"
18 |
19 | publickey=$($WGET -t 3 -T 20 -O - http://$SSHKEY_SERVER_IP/latest/public-keys 2>/dev/null)
20 |
21 | if [ $? -eq 0 ]; then
22 | logger -t "cloud" "Got response from server at $SSHKEY_SERVER_IP"
23 | keys_received=1
24 | fi
25 | else
26 | logger -t "cloud" "Could not find ssh key server IP in $LEASE_FILE"
27 | fi
28 |
29 | # did we find the keys anywhere?
30 | if [ "$keys_received" == "0" ]
31 | then
32 | logger -t "cloud" "Failed to get ssh keys from any server"
33 | exit 1
34 | fi
35 |
36 |
37 |
38 | # set ssh public key
39 | homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}')
40 | sshdir=$homedir/.ssh
41 | authorized=$sshdir/authorized_keys
42 |
43 |
44 | if [ ! -e $sshdir ]
45 | then
46 | mkdir $sshdir
47 | fi
48 |
49 | if [ ! -e $authorized ]
50 | then
51 | touch $authorized
52 | fi
53 |
54 | #cat $authorized|grep -v "$publickey" > $authorized
55 | #echo "$publickey" >> $authorized
56 | #To support user copied ssh keys
57 | if [ `grep -c "$publickey" $authorized` == 0 ]
58 | then
59 | echo "$publickey" >> $authorized
60 | fi
61 |
62 | exit 0
63 |
64 |
--------------------------------------------------------------------------------
/Template-Clean-Logs.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: clean old logs
3 | file: path={{ item }} state=absent
4 | with_items:
5 | - /var/log/auth.log
6 | - /var/log/boot
7 | - /var/log/boot.log
8 | - /var/log/btmp
9 | - /var/log/daemon.log
10 | - /var/log/debug
11 | - /var/log/dmesg
12 | - /var/log/dpkg.log
13 | - /var/log/faillog
14 | - /var/log/kern.log
15 | - /var/log/lastlog
16 | - /var/log/lpr.log
17 | - /var/log/mail.err
18 | - /var/log/mail.info
19 | - /var/log/mail.log
20 | - /var/log/mail.warn
21 | - /var/log/maillog
22 | - /var/log/messages
23 | - /var/log/pycentral.log
24 | - /var/log/secure
25 | - /var/log/syslog
26 | - /var/log/udev
27 | - /var/log/ufw.log
28 | - /var/log/user.log
29 | - /var/log/wtmp
30 | - /var/log/yum.log
31 | - /var/spool/mail/root
32 | - /root/*
33 | - /home/*
34 | - /root/.history
35 | - /root/.bash_history
36 | - name: clean really old logs
37 | shell: rm -Rf {{ item }}
38 | with_items:
39 | - /var/log/*old
40 | - /var/log/*0
41 | - /var/log/*.?
42 | - /var/log/user.log.?
43 | - /var/log/kern.log.?
44 | - /var/log/auth.log.?
45 | - /var/log/daemon.log.?
46 | - /var/log/upstart/*
47 | - /var/log/sa/*
48 | - /var/log/dmesg*
49 | - /var/log/*-201*
50 | - /var/log/*gz
51 | - /var/log/*bz?
52 | ignore_errors: true
53 |
54 | - name: recreate required logs
55 | file: path={{ item }} state=touch
56 | with_items:
57 | - /var/log/messages
58 | - /var/log/syslog
59 | - /var/log/lastlog
60 |
61 | - name: clean yum cache
62 | when: ansible_os_family == "RedHat"
63 | shell: yum clean all
--------------------------------------------------------------------------------
/Template-Packages-RHEL.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install EPEL (RHEL 5)
3 | when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 5
4 | shell: rpm -Uvh http://mirror.pnl.gov/epel/5/i386/epel-release-5-4.noarch.rpm
5 | ignore_errors: true
6 | - name: install EPEL (RHEL 6)
7 | when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 6
8 | yum: name=http://mirror.pnl.gov/epel/6/i386/epel-release-6-8.noarch.rpm state=present
9 | - name: install EPEL (RHEL 7)
10 | when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 7
11 | yum: name=http://mirror.pnl.gov/epel/7/x86_64/e/epel-release-7-5.noarch.rpm state=present
12 | - name: install "core" packages (RHEL)
13 | when: ansible_os_family == "RedHat"
14 | yum: name={{ item }} state=latest
15 | with_items:
16 | - openssh-clients
17 | - vim-enhanced
18 | - screen
19 | - tmux
20 | - curl
21 | - wget
22 | - lynx
23 | - links
24 | - sudo
25 | - libselinux-python
26 | - git
27 | - rsyslog
28 | - rsync
29 | - nmap
30 | - nc
31 | - strace
32 | - bind-utils
33 | - iotop
34 | - htop
35 | - name: update system (RHEL)
36 | when: ansible_os_family == "RedHat"
37 | command: yum upgrade -y
38 | - name: set selinux to permissive
39 | when: ansible_os_family == "RedHat"
40 | selinux: policy=targeted state=permissive
41 | - name: set timezone to UTC (RHEL)
42 | when: ansible_os_family == "RedHat"
43 | shell: "rm -f /etc/localtime && ln -s /usr/share/zoneinfo/UTC /etc/localtime"
44 | - name: install vmware tools (RHEL/vmware)
45 | yum: name=open-vm-tools state=latest
46 | when: ansible_os_family == "RedHat" and ansible_virtualization_type == "VMware"
--------------------------------------------------------------------------------
/.kitchen.yml:
--------------------------------------------------------------------------------
1 | ---
2 | driver:
3 | name: cloudstack
4 |
5 | driver_config:
6 | cloudstack_api_url: http://cloudstack.fifthecho.com:8080/client/api
7 | cloudstack_api_key: ycEWIN17Pjazd9AN5AVdpE0ObrTWJhBuAXxBkJvhLgKz6Caq0Vq9v0vhpNXraOhb72Pk8d4kRwjbAwv_3fxIyg
8 | cloudstack_secret_key: Uv6i5BIJYFKLfBM6rQli8oTlnHxP3G8kRv3kK1vDuOoaCtXsot0anPjYEpi2klvaaWaSuKZ9eqfm0gYDVGya1Q
9 | cloudstack_serviceoffering_id: d04b4fb7-e0c6-4acc-85da-56437b8b873a
10 | cloudstack_zone_id: b7ee7151-b539-4c82-85d9-841c8c2b405d
11 | cloudstack_security_group_id: 77876e01-44c8-11e4-ad1f-52540080ad25
12 | cloudstack_ssh_keypair_name: jmoody_fifthecho
13 |
14 | provisioner:
15 | name: ansible_playbook
16 | hosts: all
17 | playbook: Template.yml
18 | require_ansible_repo: true
19 | roles_path: roles
20 |
21 | platforms:
22 | - name: Centos-7
23 | driver:
24 | cloudstack_template_id: fdf69820-523b-4386-9930-f3765525dc9b
25 | - name: Centos-6
26 | driver:
27 | cloudstack_template_id: 7fba1bb5-d653-4674-a744-f6a456ad89a2
28 | - name: Centos-5
29 | driver:
30 | cloudstack_template_id: d17721e7-91f6-4296-8029-257fd8158d13
31 |
32 | - name: Ubuntu-14
33 | driver:
34 | cloudstack_template_id: c265f1ee-1802-4877-9809-e013ba8f057e
35 | - name: Ubuntu-12
36 | driver:
37 | cloudstack_template_id: 9ce0707c-915a-4956-a610-d25cb84d02c0
38 | - name: Ubuntu-10
39 | driver:
40 | cloudstack_template_id: bfb22313-cef0-492c-a368-09d3e2a652eb
41 |
42 | - name: Debian-7
43 | driver:
44 | cloudstack_template_id: 30aee694-e115-4e94-8553-7e20ff730853
45 | - name: Debian-6
46 | driver:
47 | cloudstack_template_id: 1fdf61bc-c9fe-4c14-8532-e5013c2a342d
48 |
49 |
50 | suites:
51 | - name: lab
--------------------------------------------------------------------------------
/Template-Cloud-Firstboot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: add cloud-firstboot script (RHEL)
3 | when: ansible_os_family == "RedHat"
4 | template: src=templates/RHEL/firstboot-rhel.sh.j2 dest=/usr/share/cloudstack/cloudstack-firstboot mode=0755
5 |
6 | - name: add cloud-firstboot script (Debian)
7 | when: ansible_os_family == "Debian"
8 | template: src=templates/Debian/firstboot-debian.sh.j2 dest=/usr/share/cloudstack/cloudstack-firstboot mode=0755
9 |
10 | - name: add cloud-firstboot script (FreeBSD)
11 | when: ansible_os_family == "FreeBSD"
12 | template: src=templates/FreeBSD/firstboot-freebsd.j2 dest=/usr/share/cloudstack/cloudstack_firstboot mode=0755
13 |
14 | - name: setup cloudstack-firstboot (init)
15 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
16 | file: state=link force=yes src=/usr/share/cloudstack/cloudstack-firstboot dest=/etc/init.d/cloudstack-firstboot mode=0755
17 |
18 | - name: setup cloudstack-firstboot (upstart)
19 | when: upstart.stat.exists == true and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
20 | template: src=templates/upstart/firstboot.upstart.j2 dest=/etc/init/cloudstack-firstboot.conf mode=0644
21 |
22 | - name: setup cloudstack-firstboot (systemd)
23 | when: upstart.stat.exists == false and systemd.stat.exists == true and ansible_os_family != "FreeBSD"
24 | template: src=templates/systemd/firstboot.systemd.j2 dest=/usr/lib/systemd/system/cloudstack-firstboot.service mode=0644
25 |
26 | - name: setup cloudstack-set-guest-sshkey (FreeBSD)
27 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family == "FreeBSD"
28 | template: src=templates/FreeBSD/firstboot-rc.j2 dest=/usr/local/etc/rc.d/cloudstack_firstboot mode=0755
29 |
30 | - name: clear init legacy
31 | when: ansible_os_family == "RedHat"
32 | shell: chkconfig --del cloudstack-firstboot
33 | ignore_errors: true
--------------------------------------------------------------------------------
/Template-Cloud-Userdata.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: add cloud-run-userdata script (RHEL)
3 | when: ansible_os_family == "RedHat"
4 | template: src=templates/RHEL/cloud-run-userdata-rhel.j2 dest=/usr/share/cloudstack/cloudstack-run-userdata mode=0755
5 |
6 | - name: add cloud-run-userdata script (Debian)
7 | when: ansible_os_family == "Debian"
8 | template: src=templates/Debian/cloud-run-userdata-debian.j2 dest=/usr/share/cloudstack/cloudstack-run-userdata mode=0755
9 |
10 | - name: add cloud-run-userdata script (FreeBSD)
11 | when: ansible_os_family == "FreeBSD"
12 | template: src=templates/FreeBSD/cloud-run-userdata-freebsd.j2 dest=/usr/share/cloudstack/cloudstack_run_userdata mode=0755
13 |
14 | - name: setup cloudstack-run-userdata (init)
15 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
16 | file: state=link src=/usr/share/cloudstack/cloudstack-run-userdata dest=/etc/init.d/cloudstack-run-userdata mode=0755 force=yes
17 |
18 | - name: setup cloudstack-run-userdata (upstart)
19 | when: upstart.stat.exists == true and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
20 | template: src=templates/upstart/run-userdata.upstart.j2 dest=/etc/init/cloudstack-run-userdata.conf mode=0644
21 |
22 | - name: setup cloudstack-run-userdata (systemd)
23 | when: upstart.stat.exists == false and systemd.stat.exists == true and ansible_os_family != "FreeBSD"
24 | template: src=templates/systemd/run-userdata.systemd.j2 dest=/usr/lib/systemd/system/cloudstack-run-userdata.service mode=0644
25 |
26 | - name: setup cloudstack-run-userdata (FreeBSD)
27 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family == "FreeBSD"
28 | template: src=templates/FreeBSD/cloud-userdata-rc.j2 dest=/usr/local/etc/rc.d/cloudstack_run_userdata mode=0755
29 |
30 | - name: clear init legacy
31 | when: ansible_os_family == "RedHat"
32 | shell: chkconfig --del cloudstack-run-userdata
33 | ignore_errors: true
34 |
--------------------------------------------------------------------------------
/templates/FreeBSD/firstboot-freebsd.j2:
--------------------------------------------------------------------------------
1 | #!/usr/local/bin/bash
2 | #
3 | # Flush all things not needed for a new VM and create default network environment
4 | #
5 |
6 | . /usr/share/cloudstack/cloudstack-common-functions
7 |
8 | echo "Initializing Virtual Machine..."
9 | logger -t "Setup" "Initializing Virtual Machine..."
10 | find_lease
11 |
12 | cat rc.conf | sed '/^hostname/d' > /etc/rc.conf
13 | HOST_NAME=`grep host-name $LEASE_FILE | awk '{print $NF}' | tr -d '\;' | tr -d '"' | uniq`
14 | echo "Setting hostname to $HOST_NAME"
15 | logger -t "Setup" "Setting hostname to $HOST_NAME"
16 | echo "hostname=\"$HOST_NAME\"" >> /etc/rc.conf
17 | /bin/hostname $HOST_NAME
18 |
19 | echo "# $FreeBSD: releng/10.1/etc/hosts 109997 2003-01-28 21:29:23Z dbaker $" > /etc/hosts
20 | echo "#" >> /etc/hosts
21 | echo "# Host Database" >> /etc/hosts
22 | echo "#" >> /etc/hosts
23 | echo "# This file should contain the addresses and aliases for local hosts that" >> /etc/hosts
24 | echo "# share this file. Replace 'my.domain' below with the domainname of your" >> /etc/hosts
25 | echo "# machine." >> /etc/hosts
26 | echo "#" >> /etc/hosts
27 | echo "# In the presence of the domain name service or NIS, this file may" >> /etc/hosts
28 | echo "# not be consulted at all; see /etc/nsswitch.conf for the resolution order." >> /etc/hosts
29 | echo "#" >> /etc/hosts
30 | echo "#" >> /etc/hosts
31 | echo "::1 localhost localhost.my.domain" >> /etc/hosts
32 | echo "127.0.0.1 localhost localhost.my.domain" >> /etc/hosts
33 |
34 | IP=`grep fixed-address $LEASE_FILE | awk '{print $NF}' | tr -d '\;' | uniq`
35 | echo "Setting up /etc/hosts for IP address $IP"
36 | logger -t "Setup" "Setting up /etc/hosts for IP address $IP"
37 | echo "$IP $HOST_NAME" >> /etc/hosts
38 |
39 | cat rc.conf | sed '/^cloud_firstboot/d' > /etc/rc.conf
40 | cat rc.conf | sed '/^linux/d' > /etc/rc.conf
41 | echo "linux_enable=\"YES\"" >> /etc/rc.conf
42 | if [ $(kldstat | grep linux | wc -l) -eq 0 ]; then
43 | kldload linux
44 | fi
--------------------------------------------------------------------------------
/hosts:
--------------------------------------------------------------------------------
1 | centos5-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.23 ansible_ssh_port=22
2 | centos6-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.225
3 | centos7-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.138
4 | debian6-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.226
5 | debian7-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.246
6 | debian8-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.89
7 | ubuntu10-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.45
8 | ubuntu12-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.60
9 | ubuntu14-kvm ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.75
10 | freebsd10-kvm ansible_python_interpreter=/usr/local/bin/python ansible_connection=paramiko ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.139
11 |
12 | centos5-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.81
13 | centos6-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.199
14 | centos7-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.79
15 | debian6-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.4
16 | debian7-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.147
17 | debian8-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.51
18 | ubuntu10-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.131
19 | ubuntu12-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.175
20 | ubuntu14-xen ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.77
21 | freebsd10-xen ansible_python_interpreter=/usr/local/bin/python ansible_connection=paramiko ansible_ssh_user=root ansible_ssh_pass=cloudstack ansible_ssh_host=10.20.1.83
22 |
--------------------------------------------------------------------------------
/Template-Packages-Debian.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install backports (Debian 6)
3 | when: ansible_distribution == "Debian" and ansible_distribution_major_version|int == 6
4 | apt_repository: repo='deb http://http.debian.net/debian-backports squeeze-backports main' state=present
5 | - name: install backports (Debian 7)
6 | when: ansible_distribution == "Debian" and ansible_distribution_major_version|int == 7
7 | apt_repository: repo='deb http://http.debian.net/debian wheezy-backports main' state=present
8 | - name: install backports (Debian 8)
9 | when: ansible_distribution == "Debian" and ansible_distribution_major_version|int == 8
10 | apt_repository: repo='deb http://http.debian.net/debian jessie-backports main' state=present
11 | - name: install git ppa (Ubuntu 10.04)
12 | when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version|int == 10
13 | apt_repository: repo='ppa:git-core/ppa' state=present
14 | - name: install "core" packages (Debian)
15 | when: ansible_os_family == "Debian"
16 | apt: name={{ item }} state=latest update_cache=yes
17 | with_items:
18 | - vim
19 | - screen
20 | - tmux
21 | - curl
22 | - wget
23 | - lynx
24 | - links
25 | - sudo
26 | - git
27 | - rsyslog
28 | - rsync
29 | - netcat
30 | - nmap
31 | - strace
32 | - dnsutils
33 | - iotop
34 | - htop
35 | - name: install latest hwe for Ubuntu 12.04
36 | apt: name={{ item }} state=latest update_cache=yes
37 | when: ansible_distribution == "Ubuntu" and ansible_distribution_major_version|int == 12
38 | with_items:
39 | - linux-generic-lts-trusty
40 | - linux-image-generic-lts-trusty
41 | - name: update system (Debian)
42 | when: ansible_os_family == "Debian"
43 | apt: upgrade=dist update_cache=yes
44 | - name: set timezone to UTC (Debian)
45 | when: ansible_os_family == "Debian"
46 | shell: "echo 'Etc/UTC' > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata"
47 | - name: cleanup old packages (Debian)
48 | when: ansible_os_family == "Debian"
49 | shell: "apt-get autoremove -y"
--------------------------------------------------------------------------------
/templates/SLES/cloud-set-guest-sshkey-sles.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Init file for SSH Public Keys Download Client
4 | #
5 | # chkconfig: 345 98 02
6 | # description: SSH Public Keys Download Client
7 |
8 | ### BEGIN INIT INFO
9 | # Provides: cloud-set-guest-sshkey
10 | # Required-Start: $network $syslog $local_fs
11 | # Required-Stop: $network $syslog $local_fs
12 | # Default-Start: 3 5
13 | # Default-Stop: 0 1 2 6
14 | # Short-Description: SSH Public Keys Download Client
15 | # Description: CloudStack SSH Public Keys Download Client
16 | ### END INIT INFO
17 |
18 | # Modify this line to specify the user (default is root)
19 | user=root
20 |
21 | # Add your DHCP lease folders here
22 | DHCP_FOLDERS="/var/lib/dhcpcd/*"
23 |
24 | keys_received=0
25 | file_count=0
26 |
27 | for DHCP_FILE in $DHCP_FOLDERS; do
28 | if [ -f $DHCP_FILE ]; then
29 | file_count=$((file_count+1))
30 | source $DHCP_FILE
31 | SSHKEY_SERVER_IP=$DHCPSIADDR
32 |
33 | if [ -n $SSHKEY_SERVER_IP ]; then
34 | logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP"
35 |
36 | publickey=$(wget -t 3 -T 20 -O - http://$SSHKEY_SERVER_IP/latest/public-keys 2>/dev/null)
37 |
38 | if [ $? -eq 0 ]; then
39 | logger -t "cloud" "Got response from server at $SSHKEY_SERVER_IP"
40 | keys_received=1
41 | break
42 | fi
43 | else
44 | logger -t "cloud" "Could not find ssh key server IP in $DHCP_FILE"
45 | fi
46 | fi
47 | done
48 |
49 | # did we find the keys anywhere?
50 | if [ "$keys_received" == "0" ]; then
51 | logger -t "cloud" "Failed to get ssh keys from any server"
52 | exit 1
53 | fi
54 |
55 | # set ssh public key
56 | homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}')
57 | sshdir=$homedir/.ssh
58 | authorized=$sshdir/authorized_keys
59 |
60 | if [ ! -e $sshdir ]; then
61 | mkdir $sshdir
62 | fi
63 |
64 | if [ ! -e $authorized ]; then
65 | touch $authorized
66 | fi
67 |
68 | #cat $authorized|grep -v "$publickey" > $authorized
69 | #echo "$publickey" >> $authorized
70 | #To support user copied ssh keys
71 | if [ `grep -c "$publickey" $authorized` == 0 ]; then
72 | echo "$publickey" >> $authorized
73 | fi
74 |
75 | exit 0
76 |
--------------------------------------------------------------------------------
/templates/RHEL/firstboot-rhel.sh.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Flush all things not needed for a new VM and create default network environment
4 | #
5 | # chkconfig: 235 49 02
6 | # description: Prepare new VM
7 | ### BEGIN INIT INFO
8 | # Provides: firstboot-cloudstack
9 | # Required-Start: $network $local_fs $remote_fs $syslog $all
10 | # Required-Stop: $network $local_fs $remote_fs $syslog $all
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: 0 1 6
13 | # Short-Description: Prepare new VM
14 | # Description: Prepare new VM by flushing old information and preparing network environment
15 | ### END INIT INFO
16 |
17 | . /usr/share/cloudstack/cloudstack-common-functions
18 |
19 | echo "Initializing Virtual Machine..."
20 | logger -t "Setup" "Initializing Virtual Machine..."
21 | find_lease
22 |
23 | HOST_NAME=`grep host-name $LEASE_FILE | awk '{print $NF}' | tr -d '\;' | tr -d '"' | uniq`
24 | echo "Setting hostname to $HOST_NAME"
25 | logger -t "Setup" "Setting hostname to $HOST_NAME"
26 | echo $HOST_NAME > /etc/hostname
27 | /bin/hostname $HOST_NAME
28 |
29 | echo "# Do not remove the following line, or various programs" > /etc/hosts
30 | echo "# that require network functionality will fail." >> /etc/hosts
31 | echo "127.0.0.1 localhost.localdomain localhost" >> /etc/hosts
32 | echo "# The following lines are desirable for IPv6 capable hosts" >> /etc/hosts
33 | echo "::1 ip6-localhost ip6-loopback" >> /etc/hosts
34 | echo "fe00::0 ip6-localnet" >> /etc/hosts
35 | echo "ff00::0 ip6-mcastprefix" >> /etc/hosts
36 | echo "ff02::1 ip6-allnodes" >> /etc/hosts
37 | echo "ff02::2 ip6-allrouters" >> /etc/hosts
38 | echo "::1 localhost6.localdomain6 localhost6" >> /etc/hosts
39 | IP=`grep fixed-address $LEASE_FILE | awk '{print $NF}' | tr -d '\;' | uniq`
40 | echo "Setting up /etc/hosts for IP address $IP"
41 | logger -t "Setup" "Setting up /etc/hosts for IP address $IP"
42 | echo "$IP $HOST_NAME" >> /etc/hosts
43 |
44 | /usr/bin/yum clean all
45 |
46 | chkconfig cloudstack-firstboot off
47 |
48 | if [ -f /usr/bin/systemd-run ]
49 | then
50 | systemctl disable cloudstack-firstboot
51 | fi
52 |
--------------------------------------------------------------------------------
/templates/Generic/cloud-set-guest-sshkey:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for SSH Public Keys Download Client
4 | #
5 | # chkconfig: 2345 98 02
6 | # description: SSH Public Keys Download Client
7 | ### BEGIN INIT INFO
8 | # Provides: cloud-set-guest-sshkey
9 | # Required-Start: $sshd $network
10 | # Required-Stop: $sshd $network
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: 0 1 6
13 | # Short-Description: Sets root ssh key
14 | # Description: Sets the ssh key for the root user based upon keys stored by the CloudStack RouterVM
15 | ### END INIT INFO
16 |
17 |
18 | # Modify this line to specify the user (default is root)
19 | user=root
20 | sleep 10
21 |
22 |
23 | # Add your DHCP lease folders here
24 | DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/* /var/lib/dhcp/* /var/lib/NetworkManager/*"
25 | keys_received=0
26 | file_count=0
27 |
28 | for DHCP_FILE in $DHCP_FOLDERS
29 | do
30 | if [ -f $DHCP_FILE ]
31 | then
32 | file_count=$((file_count+1))
33 | SSHKEY_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
34 |
35 | if [ -n $SSHKEY_SERVER_IP ]
36 | then
37 | logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP"
38 |
39 | publickey=$(wget -t 3 -T 20 -O - http://$SSHKEY_SERVER_IP/latest/public-keys 2>/dev/null)
40 |
41 | if [ $? -eq 0 ]
42 | then
43 | logger -t "cloud" "Got response from server at $SSHKEY_SERVER_IP"
44 | keys_received=1
45 | break
46 | fi
47 | else
48 | logger -t "cloud" "Could not find ssh key server IP in $DHCP_FILE"
49 | fi
50 | fi
51 | done
52 |
53 | # did we find the keys anywhere?
54 | if [ "$keys_received" == "0" ]
55 | then
56 | logger -t "cloud" "Failed to get ssh keys from any server"
57 | exit 1
58 | fi
59 |
60 |
61 |
62 | # set ssh public key
63 | homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}')
64 | sshdir=$homedir/.ssh
65 | authorized=$sshdir/authorized_keys
66 |
67 |
68 | if [ ! -e $sshdir ]
69 | then
70 | mkdir $sshdir
71 | fi
72 |
73 | if [ ! -e $authorized ]
74 | then
75 | touch $authorized
76 | fi
77 |
78 | cat $authorized|grep -v "$publickey" > $authorized
79 | echo "$publickey" >> $authorized
80 |
81 |
82 | exit 0
83 |
--------------------------------------------------------------------------------
/Template-Cloud-SSH-Key.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: add cloud-set-guest-sshkey script (RHEL)
3 | when: ansible_os_family == "RedHat"
4 | template: src=templates/RHEL/cloud-set-guest-sshkey-rhel.j2 dest=/usr/share/cloudstack/cloudstack-set-guest-sshkey mode=0755
5 |
6 | - name: add cloud-set-guest-sshkey script (Debian)
7 | when: ansible_distribution == "Debian"
8 | template: src=templates/Debian/cloud-set-guest-sshkey-debian.j2 dest=/usr/share/cloudstack/cloudstack-set-guest-sshkey mode=0755
9 |
10 | - name: add cloud-set-guest-sshkey script (Ubuntu)
11 | when: ansible_distribution == "Ubuntu"
12 | template: src=templates/Ubuntu/cloud-set-guest-sshkey-ubuntu.j2 dest=/usr/share/cloudstack/cloudstack-set-guest-sshkey mode=0755
13 |
14 | - name: add cloud-set-guest-sshkey script (FreeBSD)
15 | when: ansible_os_family == "FreeBSD"
16 | template: src=templates/FreeBSD/cloud-set-guest-sshkey-freebsd.j2 dest=/usr/share/cloudstack/cloudstack_set_guest_sshkey mode=0755
17 |
18 | - name: setup cloudstack-set-guest-sshkey (init)
19 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
20 | file: state=link src=/usr/share/cloudstack/cloudstack-set-guest-sshkey dest=/etc/init.d/cloudstack-set-guest-sshkey mode=0755 force=yes
21 |
22 | - name: setup cloudstack-set-guest-sshkey (upstart)
23 | when: upstart.stat.exists == true and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
24 | template: src=templates/upstart/set-guest-sshkey.upstart.j2 dest=/etc/init/cloudstack-set-guest-sshkey.conf mode=0644
25 |
26 | - name: setup cloudstack-set-guest-sshkey (systemd)
27 | when: upstart.stat.exists == false and systemd.stat.exists == true and ansible_os_family != "FreeBSD"
28 | template: src=templates/systemd/set-guest-sshkey.systemd.j2 dest=/usr/lib/systemd/system/cloudstack-set-guest-sshkey.service mode=0644
29 |
30 | - name: setup cloudstack-set-guest-sshkey (FreeBSD)
31 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family == "FreeBSD"
32 | template: src=templates/FreeBSD/cloud-sshkey-rc.j2 dest=/usr/local/etc/rc.d/cloudstack_set_guest_sshkey mode=0755
33 |
34 | - name: clear init legacy
35 | when: ansible_os_family == "RedHat"
36 | shell: chkconfig --del cloudstack-set-guest-sshkey
37 | ignore_errors: true
--------------------------------------------------------------------------------
/Template-Cloud-Password.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: add cloud-set-guest-password script (RHEL)
3 | when: ansible_os_family == "RedHat"
4 | template: src=templates/RHEL/cloud-set-guest-password-rhel.j2 dest=/usr/share/cloudstack/cloudstack-set-guest-password mode=0755
5 |
6 | - name: add cloud-set-guest-password script (Debian)
7 | when: ansible_distribution == "Debian"
8 | template: src=templates/Debian/cloud-set-guest-password-debian.j2 dest=/usr/share/cloudstack/cloudstack-set-guest-password mode=0755
9 |
10 | - name: add cloud-set-guest-password script (Ubuntu)
11 | when: ansible_distribution == "Ubuntu"
12 | template: src=templates/Ubuntu/cloud-set-guest-password-ubuntu.j2 dest=/usr/share/cloudstack/cloudstack-set-guest-password mode=0755
13 |
14 | - name: add cloud-set-guest-password script (FreeBSD)
15 | when: ansible_os_family == "FreeBSD"
16 | template: src=templates/FreeBSD/cloud-set-guest-password-freebsd.j2 dest=/usr/share/cloudstack/cloudstack_set_guest_password mode=0755
17 |
18 | - name: setup cloudstack-set-guest-password (init)
19 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
20 | file: state=link src=/usr/share/cloudstack/cloudstack-set-guest-password dest=/etc/init.d/cloudstack-set-guest-password mode=0755 force=yes
21 |
22 | - name: setup cloudstack-set-guest-password (upstart)
23 | when: upstart.stat.exists == true and systemd.stat.exists == false and ansible_os_family != "FreeBSD"
24 | template: src=templates/upstart/set-guest-password.upstart.j2 dest=/etc/init/cloudstack-set-guest-password.conf mode=0644
25 |
26 | - name: setup cloudstack-set-guest-password (systemd)
27 | when: upstart.stat.exists == false and systemd.stat.exists == true and ansible_os_family != "FreeBSD"
28 | template: src=templates/systemd/set-guest-password.systemd.j2 dest=/usr/lib/systemd/system/cloudstack-set-guest-password.service mode=0644
29 |
30 | - name: setup cloudstack-set-guest-password (FreeBSD)
31 | when: upstart.stat.exists == false and systemd.stat.exists == false and ansible_os_family == "FreeBSD"
32 | template: src=templates/FreeBSD/cloud-password-rc.j2 dest=/usr/local/etc/rc.d/cloudstack_set_guest_password mode=0755
33 |
34 | - name: clear init legacy
35 | when: ansible_os_family == "RedHat"
36 | shell: chkconfig --del cloudstack-set-guest-password
37 | ignore_errors: true
--------------------------------------------------------------------------------
/templates/FreeBSD/cloud-run-userdata-freebsd.j2:
--------------------------------------------------------------------------------
1 | #!/usr/local/bin/bash
2 |
3 | # Modify this line to specify the user (default is root)
4 | user=root
5 |
6 | . /usr/share/cloudstack/cloudstack-common-functions
7 | sleep $[ 1 + $[ RANDOM % 10 ]]
8 | find_lease
9 |
10 | HOSTNAME=`grep host-name $LEASE_FILE | uniq | awk '{print $NF}' | tr -d '\;' | tr -d '"' | uniq`
11 | CLOUD_DIR=/var/lib/cloud/instances/$HOSTNAME
12 | USER_DATA=/var/lib/cloud/instances/$HOSTNAME/user-data
13 | LOCK=/var/lib/cloud/user-data.ran
14 | user_data_received=0
15 | file_count=0
16 |
17 | if [ -f $LOCK ]
18 | then
19 | logger -t "cloud" "User-Data appears to be executed once, skipping"
20 | exit 0
21 | fi
22 |
23 | if [ ! -d $CLOUD_DIR ]
24 | then
25 | mkdir -p $CLOUD_DIR
26 | fi
27 |
28 |
29 | USER_DATA_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
30 | if [ -n $USER_DATA_SERVER_IP ]
31 | then
32 | logger -t "cloud" "Sending request to USER-DATA server at $USER_DATA_SERVER_IP"
33 | wget -t 3 -T 20 -O $USER_DATA http://$USER_DATA_SERVER_IP/latest/user-data 2>/dev/null
34 | if [ $? -eq 0 ]
35 | then
36 | logger -t "cloud" "Got user-data from server at $USER_DATA_SERVER_IP"
37 | if [ -s $USER_DATA ]; then
38 | chmod 600 $USER_DATA
39 | user_data_received=1
40 | else
41 | logger -t "cloud" "User-data is empty"
42 | fi
43 | fi
44 | else
45 | logger -t "cloud" "Could not find user-data server IP in $LEASE_FILE"
46 | fi
47 |
48 | # did we get the user-data?
49 | if [ "$user_data_received" == "0" ]
50 | then
51 | logger -t "cloud" "Failed to get user-data from any server"
52 | exit 1
53 | fi
54 |
55 | # test/execute user-data
56 | if [ "$user_data_received" == "1" ]
57 | then
58 | line1=`head -1 $USER_DATA`
59 | echo $line1 | grep -q ^#!
60 | if [ $? -eq 0 ]; then
61 | if [ -f $LOCK ]
62 | then
63 | logger -t "cloud" "User-Data appears to be executed once, skipping"
64 | exit 0
65 | else
66 | grep -r $'\r' $USER_DATA
67 | if [ $? -ne 0 ]; then
68 | chmod 700 $USER_DATA
69 | $USER_DATA
70 | else
71 | sed -i -e 's/\r//g' $USER_DATA
72 | chmod 700 $USER_DATA
73 | $USER_DATA
74 | fi
75 |
76 | chmod 600 $USER_DATA
77 | echo 'do not delete' > $LOCK
78 | logger -t "cloud" "user-data executed"
79 | fi
80 | else
81 | logger -t "cloud" "user-data is not a executable script"
82 | fi
83 | fi
84 | exit 0
85 |
--------------------------------------------------------------------------------
/templates/Generic/cloud-set-rhn-systemid:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for RHN SystemID Client
4 | #
5 | # chkconfig: 2345 98 02
6 | # description: RHN SystemID Client
7 | ### BEGIN INIT INFO
8 | # Provides: cloud-set-rhn-systemid
9 | # Required-Start: $sshd $network
10 | # Required-Stop: $sshd $network
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: 0 1 6
13 | # Short-Description: Sets rhn systemid
14 | # Description: Sets the rhn systemid in cloud.datapipe.com
15 | ### END INIT INFO
16 |
17 |
18 | # Add your DHCP lease folders here
19 | DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/* /var/lib/dhcp/* /var/lib/NetworkManager/*"
20 | SYSTEM_ID_FILE="/etc/sysconfig/rhn/systemid"
21 | CCP_URL="https://cloud.datapipe.com/api/instance/license"
22 | data_received=0
23 | DIST=$(lsb_release -i | sed 's/\t//g' |awk -F':' '{print $2}')
24 | RELEASE=$(lsb_release -r | sed 's/\t//g' |awk -F':' '{print $2}')
25 |
26 | # Check for RHEL7 -- it uses a different registrsation method and does not keep info in a file.
27 | if [[ "$DIST" == RedHat* ]] && [[ "$RELEASE" == 7.* ]]; then
28 | system_id=$(subscription-manager identity |grep 'system identity:' |awk '{print $NF}')
29 | elif [ -f $SYSTEM_ID_FILE ]; then
30 | system_id=$(grep -A 1 'system_id' /etc/sysconfig/rhn/systemid | sed -n '/string/{s/.*//;s/<\/string.*//;p;}' | sed 's/ID-//')
31 | else
32 | logger -t "cloud" "Could not find system id file: $SYSTEM_ID_FILE"
33 | exit 1
34 | fi
35 |
36 | for DHCP_FILE in $DHCP_FOLDERS
37 | do
38 | if [ -f $DHCP_FILE ]
39 | then
40 | file_count=$((file_count+1))
41 | DHCP_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
42 |
43 | if [ -n $DHCP_SERVER_IP ]
44 | then
45 | logger -t "cloud" "Sending request to dhcp server at $DHCP_SERVER_IP"
46 |
47 | instance_id=$(wget -t 3 -T 20 -O - http://$DHCP_SERVER_IP/latest/instance-id 2>/dev/null)
48 | region_name=$(wget -t 3 -T 20 -O - http://$DHCP_SERVER_IP/latest/availability-zone 2>/dev/null)
49 |
50 | if [ $? -eq 0 ]
51 | then
52 | logger -t "cloud" "Got response from server at $DHCP_SERVER_IP"
53 | data_received=1
54 | break
55 | fi
56 | else
57 | logger -t "cloud" "Could not find dhcp server IP in $DHCP_FILE"
58 | fi
59 | fi
60 | done
61 |
62 | # did we find the keys anywhere?
63 | if [ "$data_received" == "0" ]
64 | then
65 | logger -t "cloud" "Failed to get metadata from any server"
66 | exit 1
67 | fi
68 | response=$(curl -m 60 -d "instance_id=$instance_id®ion_name=$region_name&license_key=$system_id&license_name=RHEL" $CCP_URL)
69 | ret_val=$?
70 | logger -t "cloud" "Got response from $CCP_URL: $response"
71 | exit $ret_val
72 |
73 |
74 |
--------------------------------------------------------------------------------
/templates/Generic/cloud-common-functions.j2:
--------------------------------------------------------------------------------
1 | #!env bash
2 | function find_lease() {
3 |
4 | # Determine primary network adapter name
5 | if [ $(uname) == "Linux" ]; then
6 | NIC=`ip link | grep state\ UP | grep -v LOOPBACK | awk -F':' '{print $2}' | tr -d ' '`
7 | elif [ $(uname) == "FreeBSD" ]; then
8 | NIC=`ifconfig | grep UP | grep -v LOOPBACK | awk -F':' '{print $1}' | tr -d ' '`
9 | fi
10 |
11 | # Add your DHCP lease folders here
12 | if [ -f /etc/debian_version ]; then
13 | # Ubuntu / Debian
14 | DHCP_FOLDERS="/var/lib/dhclient/ /var/lib/dhcp3/ /var/lib/dhcp/"
15 | elif [ -f /etc/redhat-release ]; then
16 | # Redhat / CentOS / Scientific Linux
17 | DHCP_FOLDERS="/var/lib/dhclient/ /var/lib/dhcp3/"
18 | elif [ -f /etc/freebsd-update.conf ]; then
19 | # FreeBSD
20 | DHCP_FOLDERS="/var/db/"
21 | else
22 | # Others
23 | DHCP_FOLDERS="/var/lib/dhclient/ /var/lib/dhcp3/"
24 | fi
25 |
26 | for TEST_DIRECTORY in $DHCP_FOLDERS; do
27 | if [ -d $TEST_DIRECTORY ]; then
28 | LEASE_DIRECTORY=$TEST_DIRECTORY
29 | fi
30 | done
31 |
32 | DHCLIENT=$(which dhclient)
33 | RESTART_DHCLIENT=true
34 |
35 | RUNNING_NETWORKMANAGER=$(ps aux | grep -v grep | grep sbin\/NetworkManager | wc -l)
36 |
37 | if [[ -z $RUNNING_NETWORKMANAGER || $RUNNING_NETWORKMANAGER -eq 0 ]]; then
38 | if [ -e $LEASE_DIRECTORY/*-*$NIC* ] || [ -e $LEASE_DIRECTORY/*.$NIC* ]; then
39 | LEASE_FILE=$(ls $LEASE_DIRECTORY*$NIC*)
40 | logger -t "cloud" "DHCP file ($LEASE_FILE) exists. No need to restart dhclient."
41 | RESTART_DHCLIENT=false
42 | fi
43 |
44 | if [ $RESTART_DHCLIENT = false ]; then
45 | LEASE_SIZE=$(wc -l $LEASE_FILE | awk {'print $1'})
46 | if [ $LEASE_SIZE -eq 0 ]; then
47 | RESTART_DHCLIENT=true
48 | fi
49 | fi
50 |
51 | if [ $RESTART_DHCLIENT = true ]; then
52 | logger -t "cloud" "DHCP file does not exist. Restarting dhclient."
53 | DHCLIENT_PID=$(ps ax | grep dhclient | grep -v grep | uniq | awk {'print $1'})
54 | if [ -n $DHCLIENT_PID ]; then
55 | for CLIENTPID in $DHCLIENT_PID; do
56 | kill $CLIENTPID
57 | rm -f /var/run/dhc*
58 | done
59 | fi
60 | $DHCLIENT -lf $LEASE_DIRECTORY/dhclient-$NIC.leases -pf /var/run/dhclient-$NIC.pid $NIC
61 | sleep 5
62 | find_lease
63 | fi
64 | fi
65 |
66 | if [[ -n $RUNNING_NETWORKMANAGER && $RUNNING_NETWORKMANAGER -ge 1 ]] ; then
67 | LEASE_FILE=$( ps -eo args | grep -v grep | grep dhclient | sed -e 's/\s\+/\n/g' | grep lease | uniq)
68 |
69 | fi
70 |
71 | # echo "Using DHCP lease from $LEASE_FILE"
72 | logger -t "cloud" "Using DHCP lease from $LEASE_FILE"
73 | export LEASE_FILE
74 | }
75 |
--------------------------------------------------------------------------------
/templates/Ubuntu/cloud-set-guest-sshkey-ubuntu.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for SSH Public Keys Download Client
4 | #
5 | ### BEGIN INIT INFO
6 | # Provides: cloud-set-guest-sshkey
7 | # Required-Start: $local_fs $syslog $network
8 | # Required-Stop: $local_fs $syslog $network
9 | # Default-Start: 2 3 4 5
10 | # Default-Stop: 0 1 6
11 | # Short-Description: SSH Public Keys Download Client
12 | ### END INIT INFO
13 |
14 | set -e
15 |
16 | . /lib/lsb/init-functions
17 |
18 | # Modify this line to specify the user (default is root)
19 | user=root
20 |
21 | . /usr/share/cloudstack/cloudstack-common-functions
22 |
23 | function cloud_set_guest_sshkey() {
24 | keys_received=0
25 | file_count=0
26 | sleep $[ 1 + $[ RANDOM % 10 ]]
27 | find_lease
28 |
29 | SSHKEY_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
30 |
31 | if [ -n $SSHKEY_SERVER_IP ]; then
32 | logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP"
33 |
34 | publickey=$(wget -t 3 -T 20 -O - http://$SSHKEY_SERVER_IP/latest/public-keys 2>/dev/null)
35 |
36 | if [ $? -eq 0 ]; then
37 | logger -t "cloud" "Got response from server at $SSHKEY_SERVER_IP"
38 | keys_received=1
39 | fi
40 | else
41 | logger -t "cloud" "Could not find ssh key server IP in $LEASE_FILE"
42 | fi
43 |
44 | # did we find the keys anywhere?
45 | if [ "$keys_received" == "0" ]; then
46 | logger -t "cloud" "Failed to get ssh keys from any server"
47 | exit 1
48 | fi
49 |
50 | # set ssh public key
51 | homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}')
52 | sshdir=$homedir/.ssh
53 | authorized=$sshdir/authorized_keys
54 |
55 |
56 | if [ ! -e $sshdir ]; then
57 | mkdir $sshdir
58 | fi
59 |
60 | if [ ! -e $authorized ]; then
61 | touch $authorized
62 | fi
63 |
64 | #cat $authorized|grep -v "$publickey" > $authorized
65 | #echo "$publickey" >> $authorized
66 | #To support user copied ssh keys
67 | if [ `grep -c "$publickey" $authorized` == 0 ]; then
68 | echo "$publickey" >> $authorized
69 | fi
70 | }
71 |
72 | case "$1" in
73 | start)
74 | log_action_msg "Starting cloud" "cloud-set-guest-sshkey"
75 | sleep 10
76 | cloud_set_guest_sshkey
77 | if [ $? -eq 0 ]; then
78 | log_end_msg 0
79 | else
80 | log_end_msg 1
81 | fi
82 | ;;
83 | stop)
84 | log_action_msg "Stopping cloud" "cloud-set-guest-sshkey"
85 | log_end_msg 0
86 | ;;
87 | *)
88 | log_action_msg "Usage: /etc/init.d/cloud-set-guest-sshkey {start}"
89 | exit 1
90 | ;;
91 | esac
92 |
93 | exit 0
94 |
95 |
--------------------------------------------------------------------------------
/templates/RHEL/cloud-set-guest-sshkey-rhel.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # cloud-set-guest-sshkey SSH Public Keys Download Client
4 | #
5 | # chkconfig: 2345 50 02
6 | # description: SSH Public Keys Download Client
7 | #
8 | # Modify this line to specify the user (default is root)
9 | user=root
10 |
11 | ### BEGIN INIT INFO
12 | # Provides: cloud-set-guest-sshkey
13 | # Required-Start: $local_fs $network $sshd
14 | # Required-Stop: $local_fs $syslog
15 | # Should-Start: $syslog
16 | # Should-Stop: $network $syslog
17 | # Default-Start: 2 3 4 5
18 | # Default-Stop: 0 1 6
19 | # Short-Description:
20 | # Description: SSH Public Keys Download Client
21 | ### END INIT INFO
22 |
23 | # Source function library.
24 | . /etc/rc.d/init.d/functions
25 |
26 | . /usr/share/cloudstack/cloudstack-common-functions
27 |
28 |
29 | function cloud_set_guest_sshkey() {
30 | keys_received=0
31 | file_count=0
32 | sleep $[ 1 + $[ RANDOM % 10 ]]
33 | find_lease
34 |
35 | SSHKEY_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
36 |
37 | if [ -n $SSHKEY_SERVER_IP ]; then
38 | logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP"
39 |
40 | publickey=$(wget -t 3 -T 20 -O - http://$SSHKEY_SERVER_IP/latest/public-keys 2>/dev/null)
41 |
42 | if [ $? -eq 0 ]; then
43 | logger -t "cloud" "Got response from server at $SSHKEY_SERVER_IP"
44 | keys_received=1
45 | fi
46 | else
47 | logger -t "cloud" "Could not find ssh key server IP in $LEASE_FILE"
48 | fi
49 |
50 |
51 | # did we find the keys anywhere?
52 | if [ "$keys_received" == "0" ]; then
53 | logger -t "cloud" "Failed to get ssh keys from any server"
54 | exit 1
55 | fi
56 |
57 | # set ssh public key
58 | homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}')
59 | sshdir=$homedir/.ssh
60 | authorized=$sshdir/authorized_keys
61 |
62 | if [ ! -e $sshdir ]; then
63 | mkdir $sshdir
64 | fi
65 |
66 | if [ ! -e $authorized ]; then
67 | touch $authorized
68 | fi
69 |
70 | if [ `grep -c "$publickey" $authorized` == 0 ]; then
71 | echo "$publickey" >> $authorized
72 | /sbin/restorecon -R $homedir/.ssh
73 | fi
74 | }
75 |
76 | # See how we were called.
77 | case "$1" in
78 | start)
79 | action $"Starting cloud-set-guest-sshkey: " /bin/true
80 | cloud_set_guest_sshkey
81 | RETVAL=$?
82 | ;;
83 | stop)
84 | action $"Shutting down cloud-set-guest-sshkey: " /bin/true
85 | RETVAL=$?
86 | ;;
87 | restart)
88 | $0 stop
89 | $0 start
90 | ;;
91 | *)
92 | echo $"Usage: cloud-set-guest-sshey {start}"
93 | RETVAL=2
94 | ;;
95 | esac
96 |
97 | exit $RETVAL
98 |
--------------------------------------------------------------------------------
/templates/Debian/cloud-set-guest-sshkey-debian.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for SSH Public Keys Download Client
4 | #
5 | ### BEGIN INIT INFO
6 | # Provides: cloud-set-guest-sshkey
7 | # Required-Start: $local_fs $syslog $network
8 | # Required-Stop: $local_fs $syslog $network
9 | # Default-Start: 2 3 4 5
10 | # Default-Stop: 0 1 6
11 | # X-Start-Before: $sshd
12 | # Short-Description: SSH Public Keys Download Client
13 | ### END INIT INFO
14 |
15 | set -e
16 |
17 | . /lib/lsb/init-functions
18 |
19 | # Modify this line to specify the user (default is root)
20 | user=root
21 |
22 | . /usr/share/cloudstack/cloudstack-common-functions
23 |
24 | function cloud_set_guest_sshkey() {
25 | keys_received=0
26 | file_count=0
27 | sleep $[ 1 + $[ RANDOM % 10 ]]
28 | find_lease
29 |
30 | SSHKEY_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
31 |
32 | if [ -n $SSHKEY_SERVER_IP ]; then
33 | logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP"
34 |
35 | publickey=$(wget -t 3 -T 20 -O - http://$SSHKEY_SERVER_IP/latest/public-keys 2>/dev/null)
36 |
37 | if [ $? -eq 0 ]; then
38 | logger -t "cloud" "Got response from server at $SSHKEY_SERVER_IP"
39 | keys_received=1
40 | fi
41 | else
42 | logger -t "cloud" "Could not find ssh key server IP in $LEASE_FILE"
43 | fi
44 |
45 | # did we find the keys anywhere?
46 | if [ "$keys_received" == "0" ]; then
47 | logger -t "cloud" "Failed to get ssh keys from any server"
48 | exit 1
49 | fi
50 |
51 | # set ssh public key
52 | homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}')
53 | sshdir=$homedir/.ssh
54 | authorized=$sshdir/authorized_keys
55 |
56 |
57 | if [ ! -e $sshdir ]; then
58 | mkdir $sshdir
59 | fi
60 |
61 | if [ ! -e $authorized ]; then
62 | touch $authorized
63 | fi
64 |
65 | #cat $authorized|grep -v "$publickey" > $authorized
66 | #echo "$publickey" >> $authorized
67 | #To support user copied ssh keys
68 | if [ `grep -c "$publickey" $authorized` == 0 ]; then
69 | echo "$publickey" >> $authorized
70 | fi
71 | }
72 |
73 | case "$1" in
74 | start)
75 | log_action_msg "Starting cloud" "cloud-set-guest-sshkey"
76 | sleep 10
77 | cloud_set_guest_sshkey
78 | if [ $? -eq 0 ]; then
79 | log_end_msg 0
80 | else
81 | log_end_msg 1
82 | fi
83 | ;;
84 | stop)
85 | log_action_msg "Stopping cloud" "cloud-set-guest-sshkey"
86 | log_end_msg 0
87 | ;;
88 | *)
89 | log_action_msg "Usage: /etc/init.d/cloud-set-guest-sshkey {start}"
90 | exit 1
91 | ;;
92 | esac
93 |
94 | exit 0
95 |
96 |
--------------------------------------------------------------------------------
/templates/FreeBSD/cloud-set-guest-password-freebsd.j2:
--------------------------------------------------------------------------------
1 | #!/usr/local/bin/bash
2 | # FreeBSD
3 | # Modify this line to specify the user (default is root)
4 | user=root
5 |
6 | # Add your DHCP lease folders here
7 | WGET=/usr/local/bin/wget
8 | password_received=0
9 | file_count=0
10 | error_count=0
11 |
12 | . /usr/share/cloudstack/cloudstack-common-functions
13 | find_lease
14 |
15 | PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
16 |
17 | if [ -n $PASSWORD_SERVER_IP ]
18 | then
19 | logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $LEASE_FILE"
20 | logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP"
21 | password=$($WGET -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080)
22 | password=$(echo $password | tr -d '\r')
23 |
24 | if [ $? -eq 0 ]
25 | then
26 | logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP"
27 |
28 | case $password in
29 |
30 | "") logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM"
31 | # continue
32 | ;;
33 |
34 | "bad_request") logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP"
35 | error_count=$((error_count+1))
36 | #continue
37 | ;;
38 |
39 | "saved_password") logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP"
40 | #continue
41 | ;;
42 |
43 | *) logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP"
44 | password_received=1
45 | break
46 | ;;
47 |
48 | esac
49 | else
50 | logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP"
51 | error_count=$((error_count+1))
52 | fi
53 | else
54 | logger -t "cloud" "Could not find password server IP in $LEASE_FILE"
55 | error_count=$((error_count+1))
56 | fi
57 |
58 |
59 |
60 | if [ "$password_received" == "0" ]
61 | then
62 | if [ "$error_count" == "$file_count" ]
63 | then
64 | logger -t "cloud" "Failed to get password from any server"
65 | exit 1
66 | else
67 | logger -t "cloud" "Did not need to change password."
68 | exit 0
69 | fi
70 | fi
71 |
72 | logger -t "cloud" "Changing password ..."
73 | echo $password | pw mod user $user -h 0
74 |
75 | if [ $? -gt 0 ]
76 | then
77 | logger -t "cloud" "Failed to change password for user $user"
78 | exit 1
79 | else
80 | logger -t "cloud" "Successfully changed password for user $user"
81 | fi
82 |
83 | logger -t "cloud" "Sending acknowledgment to password server at $PASSWORD_SERVER_IP"
84 | $WGET -t 3 -T 20 -O - --header "DomU_Request: saved_password" $PASSWORD_SERVER_IP:8080
85 | exit 0
86 |
--------------------------------------------------------------------------------
/templates/Debian/firstboot-debian.sh.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Flush all things not needed for a new VM and create default network environment
4 | #
5 | # chkconfig: 235 90 02
6 | # description: Prepare new VM
7 | ### BEGIN INIT INFO
8 | # Provides: firstboot-cloudstack
9 | # Required-Start: $network $local_fs $remote_fs $syslog $all
10 | # Required-Stop: $network $local_fs $remote_fs $syslog $all
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: 0 1 6
13 | # X-Start-Before: $sshd
14 | # Short-Description: Prepare new VM
15 | # Description: Prepare new VM by flushing old information and preparing network environment
16 | ### END INIT INFO
17 | . /lib/lsb/init-functions
18 |
19 | . /usr/share/cloudstack/cloudstack-common-functions
20 |
21 | start_daemon () {
22 | echo "Initializing Virtual Machine..."
23 | logger -t "Setup" "Initializing Virtual Machine..."
24 | find_lease
25 |
26 | HOST_NAME=`grep host-name $LEASE_FILE | awk '{print $NF}' | tr -d '\;' | tr -d '"' | uniq`
27 | echo $HOST_NAME > /etc/hostname
28 | echo "Setting hostname to $HOST_NAME"
29 | logger -t "Setup" "Setting hostname to $HOST_NAME"
30 | /bin/hostname $HOST_NAME
31 |
32 | echo "# Do not remove the following line, or various programs" > /etc/hosts
33 | echo "# that require network functionality will fail." >> /etc/hosts
34 | echo "127.0.0.1 localhost.localdomain localhost" >> /etc/hosts
35 | echo "# The following lines are desirable for IPv6 capable hosts" >> /etc/hosts
36 | echo "::1 ip6-localhost ip6-loopback" >> /etc/hosts
37 | echo "fe00::0 ip6-localnet" >> /etc/hosts
38 | echo "ff00::0 ip6-mcastprefix" >> /etc/hosts
39 | echo "ff02::1 ip6-allnodes" >> /etc/hosts
40 | echo "ff02::2 ip6-allrouters" >> /etc/hosts
41 | echo "::1 localhost6.localdomain6 localhost6" >> /etc/hosts
42 | IP=`grep fixed-address $LEASE_FILE | awk '{print $NF}' | tr -d '\;' | uniq`
43 | echo "$IP $HOST_NAME" >> /etc/hosts
44 | echo "Setting up /etc/hosts for IP address $IP"
45 | logger -t "Setup" "Setting up /etc/hosts for IP address $IP"
46 |
47 | test -f /etc/ssh/ssh_host_dsa_key || dpkg-reconfigure openssh-server
48 |
49 | /usr/sbin/update-rc.d cloudstack-firstboot disable
50 | /usr/sbin/update-rc.d cloudstack-firstboot remove
51 | if [ -f /lib/init/upstart-job ]
52 | then
53 | echo manual > /etc/init/cloudstack-firstboot.override
54 | fi
55 |
56 | }
57 |
58 | case "$1" in
59 | start)
60 | log_daemon_msg "Starting $NAME daemon" "$NAME"
61 | start_daemon
62 | log_end_msg 0
63 | ;;
64 | stop)
65 | log_daemon_msg "Stopping $NAME daemon" "$NAME"
66 | log_end_msg 0
67 | ;;
68 | restart)
69 | log_daemon_msg "Restarting $NAME daemon" "$NAME"
70 | log_end_msg 0
71 | ;;
72 | *)
73 | echo "Usage: /etc/init.d/$NAME {start|stop|restart}"
74 | exit 2
75 | ;;
76 | esac
77 |
--------------------------------------------------------------------------------
/templates/RHEL/cloud-run-userdata-rhel.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for User-Data download and execution
4 | #
5 | # chkconfig: 345 99 02
6 | # description: User-Data Download Client
7 | ### BEGIN INIT INFO
8 | # Provides: cloud-userdata
9 | # Required-Start: $network $local_fs $remote_fs $syslog $all
10 | # Required-Stop: $network $local_fs $remote_fs $syslog $all
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: 0 1 6
13 | # Short-Description: Download and run Cloud userdata
14 | # Description: Downloads and executes any userdata specified when initializing the virtual machine.
15 | ### END INIT INFO
16 |
17 | # Modify this line to specify the user (default is root)
18 | user=root
19 |
20 | . /usr/share/cloudstack/cloudstack-common-functions
21 | sleep $[ 1 + $[ RANDOM % 10 ]]
22 | find_lease
23 |
24 | HOSTNAME=`grep host-name $LEASE_FILE | uniq | awk '{print $NF}' | tr -d '\;' | tr -d '"' | uniq`
25 | CLOUD_DIR=/var/lib/cloud/instances/$HOSTNAME
26 | USER_DATA=/var/lib/cloud/instances/$HOSTNAME/user-data
27 | LOCK=/var/lib/cloud/user-data.ran
28 | user_data_received=0
29 | file_count=0
30 |
31 | if [ -f $LOCK ]
32 | then
33 | logger -t "cloud" "User-Data appears to be executed once, skipping"
34 | exit 0
35 | fi
36 |
37 | if [ ! -d $CLOUD_DIR ]
38 | then
39 | mkdir -p $CLOUD_DIR
40 | fi
41 |
42 |
43 | USER_DATA_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
44 | if [ -n $USER_DATA_SERVER_IP ]
45 | then
46 | logger -t "cloud" "Sending request to USER-DATA server at $USER_DATA_SERVER_IP"
47 | wget -t 3 -T 20 -O $USER_DATA http://$USER_DATA_SERVER_IP/latest/user-data 2>/dev/null
48 | if [ $? -eq 0 ]
49 | then
50 | logger -t "cloud" "Got user-data from server at $USER_DATA_SERVER_IP"
51 | if [ -s $USER_DATA ]; then
52 | chmod 600 $USER_DATA
53 | user_data_received=1
54 | else
55 | logger -t "cloud" "User-data is empty"
56 | fi
57 | fi
58 | else
59 | logger -t "cloud" "Could not find user-data server IP in $LEASE_FILE"
60 | fi
61 |
62 | # did we get the user-data?
63 | if [ "$user_data_received" == "0" ]
64 | then
65 | logger -t "cloud" "Failed to get user-data from any server"
66 | exit 1
67 | fi
68 |
69 | # test/execute user-data
70 | if [ "$user_data_received" == "1" ]
71 | then
72 | line1=`head -1 $USER_DATA`
73 | echo $line1 | grep -q ^#!
74 | if [ $? -eq 0 ]; then
75 | if [ -f $LOCK ]
76 | then
77 | logger -t "cloud" "User-Data appears to be executed once, skipping"
78 | exit 0
79 | else
80 | grep -r $'\r' $USER_DATA
81 | if [ $? -ne 0 ]; then
82 | chmod 700 $USER_DATA
83 | $USER_DATA
84 | else
85 | sed -i -e 's/\r//g' $USER_DATA
86 | chmod 700 $USER_DATA
87 | $USER_DATA
88 | fi
89 |
90 | chmod 600 $USER_DATA
91 | echo 'do not delete' > $LOCK
92 | logger -t "cloud" "user-data executed"
93 | fi
94 | else
95 | logger -t "cloud" "user-data is not a executable script"
96 | fi
97 | fi
98 | exit 0
99 |
--------------------------------------------------------------------------------
/templates/Generic/cloud-set-guest-password:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for Password Download Client
4 | #
5 | # chkconfig: 2345 98 02
6 | # description: Password Download Client
7 | ### BEGIN INIT INFO
8 | # Provides: cloud-set-guest-password
9 | # Required-Start: $sshd $network
10 | # Required-Stop: $sshd $network
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: 0 1 6
13 | # Short-Description: Sets root password
14 | # Description: Sets the password for the root user based upon passwords stored by the CloudStack RouterVM
15 | ### END INIT INFO
16 |
17 | # Modify this line to specify the user (default is root)
18 | user=root
19 |
20 | sleep 10
21 | # Add your DHCP lease folders here
22 | DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/* /var/lib/dhcp/* /var/lib/NetworkManager/*"
23 | password_received=0
24 | file_count=0
25 | error_count=0
26 |
27 | for DHCP_FILE in $DHCP_FOLDERS
28 | do
29 | if [ -f $DHCP_FILE ]
30 | then
31 | file_count=$((file_count+1))
32 | PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
33 |
34 | if [ -n $PASSWORD_SERVER_IP ]
35 | then
36 | logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $DHCP_FILE"
37 | logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP"
38 | password=$(wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080)
39 | password=$(echo $password | tr -d '\r')
40 |
41 | if [ $? -eq 0 ]
42 | then
43 | logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP"
44 |
45 | case $password in
46 |
47 | "") logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM"
48 | continue
49 | ;;
50 |
51 | "bad_request") logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP"
52 | error_count=$((error_count+1))
53 | continue
54 | ;;
55 |
56 | "saved_password") logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP"
57 | continue
58 | ;;
59 |
60 | *) logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP"
61 | password_received=1
62 | break
63 | ;;
64 |
65 | esac
66 | else
67 | logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP"
68 | error_count=$((error_count+1))
69 | fi
70 | else
71 | logger -t "cloud" "Could not find password server IP in $DHCP_FILE"
72 | error_count=$((error_count+1))
73 | fi
74 | fi
75 | done
76 |
77 | if [ "$password_received" == "0" ]
78 | then
79 | if [ "$error_count" == "$file_count" ]
80 | then
81 | logger -t "cloud" "Failed to get password from any server"
82 | exit 1
83 | else
84 | logger -t "cloud" "Did not need to change password."
85 | exit 0
86 | fi
87 | fi
88 |
89 | logger -t "cloud" "Changing password ..."
90 | #echo $password | passwd --stdin $user
91 | passwd $user </dev/null
49 | if [ $? -eq 0 ]
50 | then
51 | logger -t "cloud" "Got user-data from server at $USER_DATA_SERVER_IP"
52 | if [ -s $USER_DATA ]; then
53 | chmod 600 $USER_DATA
54 | user_data_received=1
55 | else
56 | logger -t "cloud" "User-data is empty"
57 | fi
58 | fi
59 | else
60 | logger -t "cloud" "Could not find user-data server IP in $LEASE_FILE"
61 | fi
62 |
63 | # did we get the user-data?
64 | if [ "$user_data_received" == "0" ]
65 | then
66 | logger -t "cloud" "Failed to get user-data from any server"
67 | exit 1
68 | fi
69 |
70 | # test/execute user-data
71 | if [ "$user_data_received" == "1" ]
72 | then
73 | line1=`head -1 $USER_DATA`
74 | echo $line1 | grep -q ^#!
75 | if [ $? -eq 0 ]; then
76 | if [ -f $LOCK ]
77 | then
78 | logger -t "cloud" "User-Data appears to be executed once, skipping"
79 | exit 0
80 | else
81 | grep -r $'\r' $USER_DATA
82 | if [ $? -ne 0 ]; then
83 | chmod 700 $USER_DATA
84 | $USER_DATA
85 | else
86 | sed -i -e 's/\r//g' $USER_DATA
87 | chmod 700 $USER_DATA
88 | $USER_DATA
89 | fi
90 |
91 | chmod 600 $USER_DATA
92 | echo 'do not delete' > $LOCK
93 | logger -t "cloud" "user-data executed"
94 | fi
95 | else
96 | logger -t "cloud" "user-data is not a executable script"
97 | fi
98 | fi
99 | }
100 |
101 | case "$1" in
102 | start)
103 | log_action_msg "Starting cloud" "cloud-run-userdata"
104 | sleep 10
105 | cloud_run_userdata
106 | if [ $? -eq 0 ]; then
107 | log_end_msg 0
108 | else
109 | log_end_msg 1
110 | fi
111 | ;;
112 | stop)
113 | log_action_msg "Stopping cloud" "cloud-run-userdata"
114 | log_end_msg 0
115 | ;;
116 | *)
117 | log_action_msg "Usage: /etc/init.d/cloud-run-userdata {start}"
118 | exit 1
119 | ;;
120 | esac
121 | exit 0
122 |
--------------------------------------------------------------------------------
/Template.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 | tasks:
4 | - name: setup packages for RHEL
5 | include: Template-Packages-RHEL.yml
6 | - name: setup packages for Debian/Ubuntu
7 | include: Template-Packages-Debian.yml
8 | - name: setup packages for SUSE
9 | include: Template-Packages-SUSE.yml
10 | - name: setup packages for FreeBSD
11 | include: Template-Packages-FreeBSD.yml
12 |
13 | - name: disable sysklogd (if present)
14 | service: name=syslog enabled=no
15 | ignore_errors: true
16 | - name: enable rsyslog (if not)
17 | when: ansible_os_family != "FreeBSD"
18 | service: name=rsyslog enabled=yes
19 | ignore_errors: true
20 | - name: enable rsyslog (if not)
21 | when: ansible_os_family == "FreeBSD"
22 | service: name=rsyslogd enabled=yes
23 | ignore_errors: true
24 |
25 | - name: remove cloud user
26 | user: name=cloud state=absent
27 | - name: set root password to "cloudstack" (in case init scripts fail)
28 | user: name=root update_password=always password=$6$hIuIfYHMi8Vd$QCoX.nOo551xKqhIPjdc/aUhtSTpKf3kR0q5MjXrwOgP5Iu9G.MVojQZfvdK2hPqimnY16htsgLktuYhUehNQ0
29 |
30 | - name: add CloudStack login splash (Ubuntu)
31 | template: src=templates/Generic/motd.j2 dest=/etc/motd.tail
32 | when: ansible_distribution == "Ubuntu"
33 | - name: add CloudStack login spash (Others)
34 | template: src=templates/Generic/motd.j2 dest=/etc/motd
35 | when: ansible_distribution != "Ubuntu"
36 | - name: create ssh directory
37 | file: state=directory mode=0700 path=/root/.ssh
38 |
39 | - name: create directory to store cloudstack client scripts
40 | file: state=directory mode=0755 path=/usr/share/cloudstack
41 |
42 | - name: register init system variables
43 | include: Template-Test-Init-System.yml
44 |
45 | - name: setup common functions for init scripts
46 | include: Template-Cloud-Functions.yml
47 |
48 | - name: setup cloudstack-set-guest-password
49 | include: Template-Cloud-Password.yml
50 | - name: setup cloudstack-set-guest-sshkey
51 | include: Template-Cloud-SSH-Key.yml
52 | - name: setup cloudstack-run-userdata
53 | include: Template-Cloud-Userdata.yml
54 | - name: setup cloudstack-firstboot
55 | include: Template-Cloud-Firstboot.yml
56 |
57 | - name: register upstart services
58 | when: upstart.stat.exists == true and systemd.stat.exists == false
59 | shell: initctl reload-configuration
60 | - name: register systemd services
61 | when: upstart.stat.exists == false and systemd.stat.exists == true
62 | shell: systemctl daemon-reload
63 |
64 | - name: enable cloudstack-password service
65 | service: name=cloudstack-set-guest-password enabled=yes
66 | - name: enable cloudstack-sshkey service
67 | service: name=cloudstack-set-guest-sshkey enabled=yes
68 | - name: enable cloudstack-userdata service
69 | service: name=cloudstack-run-userdata enabled=yes
70 | - name: enable firstboot-cloudstack service
71 | service: name=cloudstack-firstboot enabled=yes
72 |
73 | - name: setup networking
74 | include: Template-Networking.yml
75 |
76 | - name: remove upstart overrides (if present)
77 | file: path=/etc/init/firstboot-cloudstack.override state=absent
78 | - name: remove userdata lock (if present)
79 | file: path=/var/lib/cloud/user-data.ran state=absent
80 | - name: remove userdata history
81 | shell: rm -Rf /var/lib/cloud/instances/*
82 | - name: remove dhcp history
83 | shell: rm -f /var/lib/dhc*/dhcl*leas*
84 | - name: cleanup logs
85 | include: Template-Clean-Logs.yml
86 | - name: remove shell history
87 | shell: rm -f /root/.*history*
88 | - name: remove authorized keys
89 | file: path=/root/.ssh/authorized_keys state=absent
90 | - name: remove ssh keys
91 | shell: rm -f /etc/ssh/*host*key*
--------------------------------------------------------------------------------
/templates/Debian/cloud-set-guest-password-debian.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for Password Download Client
4 | #
5 | ### BEGIN INIT INFO
6 | # Provides: cloud-set-guest-password
7 | # Required-Start: $local_fs $syslog $network
8 | # Required-Stop: $local_fs $syslog $network
9 | # Default-Start: 2 3 4 5
10 | # Default-Stop: 0 1 6
11 | # X-Start-Before: $sshd
12 | # Short-Description: Init file for Password Download Client
13 | ### END INIT INFO
14 |
15 | set -e
16 |
17 | . /lib/lsb/init-functions
18 |
19 | # Modify this line to specify the user (default is root)
20 | user=root
21 |
22 | . /usr/share/cloudstack/cloudstack-common-functions
23 |
24 | function cloud_set_guest_password() {
25 | sleep $[ 1 + $[ RANDOM % 10 ]]
26 | find_lease
27 | password_received=0
28 | file_count=0
29 | error_count=0
30 |
31 | file_count=$((file_count+1))
32 | PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
33 |
34 | if [ -n "$PASSWORD_SERVER_IP" ]; then
35 | logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $LEASE_FILE"
36 | logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP"
37 | password=$(wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080)
38 | password=$(echo $password | tr -d '\r')
39 |
40 | if [ $? -eq 0 ]; then
41 | logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP"
42 |
43 | case $password in
44 | "")
45 | logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM"
46 | ;;
47 | "bad_request")
48 | logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP"
49 | error_count=$((error_count+1))
50 | ;;
51 | "saved_password")
52 | logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP"
53 | ;;
54 | *)
55 | logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP"
56 | password_received=1
57 | ;;
58 | esac
59 | else
60 | logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP"
61 | error_count=$((error_count+1))
62 | fi
63 | else
64 | logger -t "cloud" "Could not find password server IP in $LEASE_FILE"
65 | error_count=$((error_count+1))
66 | fi
67 |
68 |
69 | if [ "$password_received" == "0" ]; then
70 | if [ "$error_count" == "$file_count" ]; then
71 | logger -t "cloud" "Failed to get password from any server"
72 | exit 1
73 | else
74 | logger -t "cloud" "Did not need to change password."
75 | exit 0
76 | fi
77 | fi
78 |
79 | logger -t "cloud" "Changing password ..."
80 |
81 | if [ -x /usr/sbin/chpasswd ]; then
82 | echo "${user}:${password}" | chpasswd
83 | else
84 | echo $password | passwd --stdin $user
85 | if [ $? -gt 0 ]; then
86 | logger -t "cloud" "Failed to change password for user $user"
87 | exit 1
88 | else
89 | logger -t "cloud" "Successfully changed password for user $user"
90 | fi
91 | fi
92 |
93 | logger -t "cloud" "Sending acknowledgment to password server at $PASSWORD_SERVER_IP"
94 | wget -t 3 -T 20 -O - --header "DomU_Request: saved_password" $PASSWORD_SERVER_IP:8080
95 | }
96 |
97 | case "$1" in
98 | start)
99 | log_action_msg "Starting cloud" "cloud-set-guest-password"
100 | sleep 10
101 | cloud_set_guest_password
102 | if [ $? -eq 0 ]; then
103 | log_end_msg 0
104 | else
105 | log_end_msg 1
106 | fi
107 | ;;
108 | stop)
109 | log_action_msg "Stopping cloud" "cloud-set-guest-password"
110 | log_end_msg 0
111 | ;;
112 | *)
113 | log_action_msg "Usage: /etc/init.d/cloud-set-guest-password {start}"
114 | exit 1
115 | ;;
116 | esac
117 |
118 | exit 0
119 |
120 |
--------------------------------------------------------------------------------
/templates/Ubuntu/cloud-set-guest-password-ubuntu.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Init file for Password Download Client
4 | #
5 | ### BEGIN INIT INFO
6 | # Provides: cloud-set-guest-password
7 | # Required-Start: $local_fs $syslog $network
8 | # Required-Stop: $local_fs $syslog $network
9 | # Default-Start: 2 3 4 5
10 | # Default-Stop: 0 1 6
11 | # Short-Description: Init file for Password Download Client
12 | ### END INIT INFO
13 |
14 | set -e
15 |
16 | . /lib/lsb/init-functions
17 |
18 | # Modify this line to specify the user (default is root)
19 | user=root
20 |
21 | . /usr/share/cloudstack/cloudstack-common-functions
22 |
23 | function cloud_set_guest_password() {
24 | sleep $[ 1 + $[ RANDOM % 10 ]]
25 | find_lease
26 | password_received=0
27 | file_count=0
28 | error_count=0
29 |
30 | file_count=$((file_count+1))
31 | PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
32 |
33 | if [ -n "$PASSWORD_SERVER_IP" ]; then
34 | logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $LEASE_FILE"
35 | logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP"
36 | password=$(wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080)
37 | password=$(echo $password | tr -d '\r')
38 |
39 | if [ $? -eq 0 ]; then
40 | logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP"
41 |
42 | case $password in
43 | "")
44 | logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM"
45 | ;;
46 | "bad_request")
47 | logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP"
48 | error_count=$((error_count+1))
49 | ;;
50 | "saved_password")
51 | logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP"
52 | ;;
53 | *)
54 | logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP"
55 | password_received=1
56 | ;;
57 | esac
58 | else
59 | logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP"
60 | error_count=$((error_count+1))
61 | fi
62 | else
63 | logger -t "cloud" "Could not find password server IP in $LEASE_FILE"
64 | error_count=$((error_count+1))
65 | fi
66 |
67 | if [ "$password_received" == "0" ]; then
68 | if [ "$error_count" == "$file_count" ]; then
69 | logger -t "cloud" "Failed to get password from any server"
70 | exit 1
71 | else
72 | logger -t "cloud" "Did not need to change password."
73 | exit 0
74 | fi
75 | fi
76 |
77 | logger -t "cloud" "Changing password ..."
78 |
79 | if [ -x /usr/sbin/chpasswd ]; then
80 | echo "${user}:${password}" | chpasswd
81 | else
82 | echo $password | passwd --stdin $user
83 | if [ $? -gt 0 ]; then
84 | logger -t "cloud" "Failed to change password for user $user"
85 | exit 1
86 | else
87 | logger -t "cloud" "Successfully changed password for user $user"
88 | fi
89 | fi
90 |
91 | logger -t "cloud" "Sending acknowledgment to password server at $PASSWORD_SERVER_IP"
92 | wget -t 3 -T 20 -O - --header "DomU_Request: saved_password" $PASSWORD_SERVER_IP:8080
93 | }
94 |
95 | case "$1" in
96 | start)
97 | log_action_msg "Starting cloud" "cloud-set-guest-password"
98 | sleep 10
99 | cloud_set_guest_password
100 | if [ $? -eq 0 ]; then
101 | log_end_msg 0
102 | else
103 | log_end_msg 1
104 | fi
105 | ;;
106 | stop)
107 | log_action_msg "Stopping cloud" "cloud-set-guest-password"
108 | log_end_msg 0
109 | ;;
110 | *)
111 | log_action_msg "Usage: /etc/init.d/cloud-set-guest-password {start}"
112 | exit 1
113 | ;;
114 | esac
115 |
116 | exit 0
117 |
118 |
--------------------------------------------------------------------------------
/templates/RHEL/cloud-set-guest-password-rhel.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # cloud-set-guest-password Init file for Password Download Client
4 | #
5 | # chkconfig: 2345 50 02
6 | # description: Init file for Password Download Client
7 |
8 | ### BEGIN INIT INFO
9 | # Provides: cloud-set-guest-password
10 | # Required-Start: $local_fs $network
11 | # Required-Stop: $local_fs $syslog
12 | # Should-Start: $syslog
13 | # Should-Stop: $network $syslog
14 | # Default-Start: 2 3 4 5
15 | # Default-Stop: 0 1 6
16 | # Short-Description: Init file for Password Download Client
17 | # Description: Init file for Password Download Client
18 | ### END INIT INFO
19 |
20 | # Source function library.
21 | . /etc/rc.d/init.d/functions
22 |
23 | # Modify this line to specify the user (default is root)
24 | user=root
25 |
26 | . /usr/share/cloudstack/cloudstack-common-functions
27 |
28 | function cloud_set_guest_password() {
29 | sleep $[ 1 + $[ RANDOM % 10 ]]
30 | find_lease
31 | password_received=0
32 | file_count=0
33 | error_count=0
34 | if [ -f $LEASE_FILE ]; then
35 | file_count=$((file_count+1))
36 | PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $LEASE_FILE | uniq | tail -1 | awk '{print $NF}' | tr -d '\;')
37 |
38 | if [ -n $PASSWORD_SERVER_IP ]; then
39 | logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $LEASE_FILE"
40 | logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP"
41 | password=$(wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080)
42 | password=$(echo $password | tr -d '\r')
43 |
44 | if [ $? -eq 0 ]; then
45 | logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP"
46 |
47 | case $password in
48 |
49 | "") logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM"
50 | ;;
51 |
52 | "bad_request") logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP"
53 | error_count=$((error_count+1))
54 | ;;
55 |
56 | "saved_password") logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP"
57 | ;;
58 |
59 | *) logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP"
60 | password_received=1
61 | ;;
62 |
63 | esac
64 | else
65 | logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP"
66 | error_count=$((error_count+1))
67 | fi
68 | else
69 | logger -t "cloud" "Could not find password server IP in $LEASE_FILE"
70 | error_count=$((error_count+1))
71 | fi
72 | fi
73 |
74 | if [ "$password_received" == "0" ]; then
75 | if [ "$error_count" == "$file_count" ]; then
76 | logger -t "cloud" "Failed to get password from any server"
77 | exit 1
78 | else
79 | logger -t "cloud" "Did not need to change password."
80 | exit 0
81 | fi
82 | fi
83 |
84 | logger -t "cloud" "Changing password ..."
85 | echo $password | passwd --stdin $user
86 |
87 | if [ $? -gt 0 ]; then
88 | logger -t "cloud" "Failed to change password for user $user"
89 | fi
90 |
91 | logger -t "cloud" "Successfully changed password for user $user"
92 | logger -t "cloud" "Sending acknowledgment to password server at $PASSWORD_SERVER_IP"
93 | wget -t 3 -T 20 -O - --header "DomU_Request: saved_password" $PASSWORD_SERVER_IP:8080
94 | }
95 |
96 | # See how we were called.
97 | case "$1" in
98 | start)
99 | action $"Starting cloud-set-guest-password: " /bin/true
100 | cloud_set_guest_password
101 | RETVAL=$?
102 | ;;
103 | stop)
104 | action $"Shutting down cloud-set-guest-password: " /bin/true
105 | RETVAL=$?
106 | ;;
107 | restart)
108 | $0 stop
109 | $0 start
110 | ;;
111 | *)
112 | echo $"Usage: cloud-set-guest-sshey {start}"
113 | RETVAL=2
114 | ;;
115 | esac
116 |
117 | exit $RETVAL
118 |
--------------------------------------------------------------------------------
/templates/Generic/cloud-get-userdata:
--------------------------------------------------------------------------------
1 | #!/bin/bash -x
2 | sleep 5
3 | #
4 | # Init file for User-Data download and execution
5 | #
6 | # chkconfig: 345 99 02
7 | # description: User-Data Download Client
8 | # Modify this line to specify the user (default is root)
9 | user=root
10 |
11 | # Add your DHCP lease folders here
12 | if [ -f /etc/debian_version ]; then
13 | # Ubuntu
14 | DHCP_FOLDERS="/var/lib/dhcpcd/dhcpcd-eth0.*"
15 | elif [ -f /etc/redhat-release ]; then
16 | # Redhat / CentOS / Scientific Linux
17 | #DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/*"
18 | DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/* /var/lib/dhcp/* /var/lib/NetworkManager/*"
19 | else
20 | # Others
21 | DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/*"
22 | fi
23 |
24 | # RHEL/CENTOS 7 use NetworkManager
25 | # Don't know how to verify NetworkManager is being used via output of "systemctl status NetworkManager"
26 | # So for now simply assuming it is being used.
27 | DIST=$(lsb_release -i | sed 's/\t//g' |awk -F':' '{print $2}')
28 | RELEASE=$(lsb_release -r | sed 's/\t//g' |awk -F':' '{print $2}')
29 | if [[ "$DIST" == RedHat*||CentOS* ]] && [[ "$RELEASE" == 7.* ]]; then
30 | HOSTNAME=$(tac /var/lib/NetworkManager/dhclient*eth0.lease | grep -m1 host-name | awk '{print $NF}' | tr -d '\;' | tr -d '"' | tail -1)
31 | else
32 | HOSTNAME=$(tac /var/lib/dhc*/dhclient?eth0.leases | grep -m1 host-name | awk '{print $NF}' | tr -d '\;' | tr -d '"' | tail -1)
33 | fi
34 |
35 | CLOUD_DIR=/var/lib/cloud/instances/$HOSTNAME
36 | USER_DATA=/var/lib/cloud/instances/$HOSTNAME/user-data
37 | LOCK=/var/lib/cloud/user-data.ran
38 | user_data_received=0
39 | file_count=0
40 |
41 | if [ -f "${LOCK}" ]
42 | then
43 | logger -t "cloud" "User-Data appears to be executed once, skipping"
44 | exit 0
45 | fi
46 |
47 | if [ ! -d "${CLOUD_DIR}" ]
48 | then
49 | mkdir -p "${CLOUD_DIR}"
50 | fi
51 |
52 | for DHCP_FILE in ${DHCP_FOLDERS}
53 | do
54 | if [ -f "${DHCP_FILE}" ]
55 | then
56 | file_count=$((file_count+1))
57 | if [ -f /etc/debian_version ]; then
58 | # Ubuntu
59 | #USER_DATA_SERVER_IP=$(grep DHCPSID $DHCP_FILE | tail -1 | egrep -o '([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})' )
60 | USER_DATA_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
61 | elif [ -f /etc/redhat-release ]; then
62 | # Redhat / CentOS / Scientific Linux
63 | USER_DATA_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
64 | else
65 | # Others
66 | USER_DATA_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
67 | fi
68 |
69 | if [ -n "${USER_DATA_SERVER_IP}" ]
70 | then
71 | logger -t "cloud" "Sending request to USER-DATA server at ${USER_DATA_SERVER_IP}"
72 | wget -t 3 -T 20 -O "${USER_DATA}" http://"${USER_DATA_SERVER_IP}"/latest/user-data 2>/dev/null
73 | if [ $? -eq 0 ]
74 | then
75 | logger -t "cloud" "Got user-data from server at ${USER_DATA_SERVER_IP}"
76 | if [ -s "${USER_DATA}" ]; then
77 | chmod 600 "${USER_DATA}"
78 | user_data_received=1
79 | else
80 | logger -t "cloud" "User-data is empty"
81 | fi
82 | break
83 | fi
84 | else
85 | logger -t "cloud" "Could not find user-data server IP in ${DHCP_FILE}"
86 | fi
87 | fi
88 | done
89 | # did we get the user-data?
90 | if [ "${user_data_received}" == "0" ]
91 | then
92 | logger -t "cloud" "Failed to get user-data from any server"
93 | exit 1
94 | fi
95 |
96 | # test/execute user-data
97 | if [ "${user_data_received}" == "1" ]
98 | then
99 | line1=$(head -1 "${USER_DATA}")
100 | echo "${line1}" | grep -q ^#!
101 | if [ $? -eq 0 ]; then
102 | if [ -f "${LOCK}" ]
103 | then
104 | logger -t "cloud" "User-Data appears to be executed once, skipping"
105 | exit 0
106 | else
107 | grep -r $'\r' "${USER_DATA}"
108 | if [ $? -ne 0 ]; then
109 | chmod 700 "${USER_DATA}"
110 | "${USER_DATA}"
111 | else
112 | sed -i -e 's/\r//g' "${USER_DATA}"
113 | chmod 700 "${USER_DATA}"
114 | "${USER_DATA}"
115 | fi
116 |
117 | chmod 600 "${USER_DATA}"
118 | echo 'do not delete' > "${LOCK}"
119 | logger -t "cloud" "user-data executed"
120 | fi
121 | else
122 | logger -t "cloud" "user-data is not a executable script"
123 | fi
124 | fi
125 | exit 0
126 |
--------------------------------------------------------------------------------
/templates/SLES/cloud-set-guest-password-sles.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Copyright (c) 2013 Apache CloudStack
3 | #
4 | # Author: Apache CloudStack
5 | #
6 | # /etc/init.d/cloud-set-guest-password
7 | #
8 | # Init file for Password Download Client
9 | #
10 | ### BEGIN INIT INFO
11 | # Provides: cloud-set-guest-password
12 | # Required-Start: $network $local_fs $syslog
13 | # Required-Stop: $network $local_fs $syslog
14 | # Default-Start: 3 5
15 | # Default-Stop: 0 1 2 6
16 | # Short-Description: Password Download Client
17 | # Description: CloudStack Password Download Client
18 | ### END INIT INFO
19 |
20 | . /etc/rc.status
21 |
22 | # First reset status of this service
23 | rc_reset
24 |
25 | # Modify this line to specify the user (default is root)
26 | user=root
27 |
28 | # Add your DHCP lease folders here
29 | DHCP_FOLDERS="/var/lib/dhcpcd/*"
30 | password_received=0
31 | file_count=0
32 | error_count=0
33 |
34 | case "$1" in
35 | start)
36 | echo -n "Starting cloud-guest-set-password"
37 | for DHCP_FILE in $DHCP_FOLDERS; do
38 | if [ -f $DHCP_FILE ]; then
39 | file_count=$((file_count+1))
40 | . /$DHCP_FILE
41 |
42 | PASSWORD_SERVER_IP=$DHCPSIADDR
43 |
44 | if [ -n $PASSWORD_SERVER_IP ]; then
45 | logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $DHCP_FILE"
46 | logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP"
47 | password=$(wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080)
48 | password=$(echo $password | tr -d '\r')
49 |
50 | if [ $? -eq 0 ]; then
51 | logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP"
52 |
53 | case $password in
54 |
55 | "") logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM"
56 | continue
57 | ;;
58 |
59 | "bad_request") logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP"
60 | error_count=$((error_count+1))
61 | continue
62 | ;;
63 |
64 | "saved_password") logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP"
65 | continue
66 | ;;
67 |
68 | *) logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP"
69 | password_received=1
70 | break
71 | ;;
72 |
73 | esac
74 | else
75 | logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP"
76 | error_count=$((error_count+1))
77 | fi
78 | else
79 | logger -t "cloud" "Could not find password server IP in $DHCP_FILE"
80 | error_count=$((error_count+1))
81 | fi
82 | fi
83 | done
84 |
85 | if [ "$password_received" == "0" ]; then
86 | if [ "$error_count" == "$file_count" ]; then
87 | logger -t "cloud" "Failed to get password from any server"
88 | exit 1
89 | else
90 | logger -t "cloud" "Did not need to change password."
91 | exit 0
92 | fi
93 | fi
94 |
95 | logger -t "cloud" "Changing password ..."
96 | echo $password | passwd --stdin $user
97 |
98 | if [ $? -gt 0 ]; then
99 | usermod -p `mkpasswd -m SHA-512 $password` $user
100 |
101 | if [ $? -gt 0 ]; then
102 | logger -t "cloud" "Failed to change password for user $user"
103 | exit 1
104 | else
105 | logger -t "cloud" "Successfully changed password for user $user"
106 | fi
107 | fi
108 |
109 | logger -t "cloud" "Sending acknowledgment to password server at $PASSWORD_SERVER_IP"
110 | wget -t 3 -T 20 -O - --header "DomU_Request: saved_password" $PASSWORD_SERVER_IP:8080
111 | # Remember status and be verbose
112 | rc_status -v
113 | ;;
114 | stop)
115 | echo -n "Shutting down cloud-set-guest-password"
116 | rc_status -v
117 | ;;
118 | esac
119 |
120 | rc_exit
121 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------