diff options
-rwxr-xr-x | bin/install_script.sh | 82 | ||||
-rw-r--r-- | environments/production/hiera.yaml | 3 | ||||
-rw-r--r-- | modules/base_installation/files/services/en-dhcp.network | 8 | ||||
-rw-r--r-- | modules/base_installation/lib/facter/ldapvar.rb | 83 | ||||
-rw-r--r-- | modules/base_installation/manifests/services.pp | 13 | ||||
-rw-r--r-- | modules/base_installation/templates/services/en-dhcp.network.erb | 13 | ||||
-rw-r--r-- | python/get_initial_configuration.py | 37 | ||||
-rw-r--r-- | python/reboot_vps_server.py | 6 |
8 files changed, 175 insertions, 70 deletions
diff --git a/bin/install_script.sh b/bin/install_script.sh index f46ab29..3a59006 100755 --- a/bin/install_script.sh +++ b/bin/install_script.sh | |||
@@ -1,20 +1,69 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | 2 | ||
3 | set -e | ||
4 | |||
5 | host_user=root | ||
6 | git_branch=master | ||
7 | |||
8 | while [ -n "$1" ]; do | ||
9 | case "$1" in | ||
10 | --vps) | ||
11 | vps_name="$2" | ||
12 | shift | ||
13 | ;; | ||
14 | --reinstall-first) | ||
15 | reinstall_first=1 | ||
16 | ;; | ||
17 | --password) | ||
18 | password="$2" | ||
19 | shift | ||
20 | ;; | ||
21 | --host-user) | ||
22 | host_user="$2" | ||
23 | shift | ||
24 | ;; | ||
25 | --no-reboot) | ||
26 | no_reboot=1 | ||
27 | ;; | ||
28 | --no-reboot-start) | ||
29 | no_reboot_start=1 | ||
30 | ;; | ||
31 | --no-reboot-end) | ||
32 | no_reboot_end=1 | ||
33 | ;; | ||
34 | --git-branch) | ||
35 | git_branch="$2" | ||
36 | shift | ||
37 | ;; | ||
38 | esac | ||
39 | |||
40 | shift | ||
41 | done | ||
42 | |||
3 | DIRECTORY=$(cd `dirname $0` && pwd) | 43 | DIRECTORY=$(cd `dirname $0` && pwd) |
4 | PYTHON_DIRECTORY="$DIRECTORY/../python" | 44 | PYTHON_DIRECTORY="$DIRECTORY/../python" |
5 | 45 | ||
6 | if [ -n "$1" ]; then | 46 | if [ -z "$vps_name" ]; then |
7 | vps_name="$1" | ||
8 | else | ||
9 | read -p "Nom du vps : " vps_name | 47 | read -p "Nom du vps : " vps_name |
10 | fi | 48 | fi |
11 | 49 | ||
12 | echo "Patienter le temps du reboot" | 50 | if [ -n "$reinstall_first" ]; then |
13 | python $PYTHON_DIRECTORY/reboot_vps_server.py --rescue "$vps_name" | 51 | echo "Réinstallation du système" |
52 | python $PYTHON_DIRECTORY/reinstall_vps_server.py --use-current "$vps_name" | ||
53 | |||
54 | read -p "Appuyer sur une touche quand le serveur est prêt" ready | ||
55 | fi | ||
56 | |||
57 | if [ -z "$no_reboot" -a -z "$no_reboot_start" ]; then | ||
58 | echo "Patienter le temps du reboot" | ||
59 | python $PYTHON_DIRECTORY/reboot_vps_server.py --rescue "$vps_name" | ||
60 | fi | ||
14 | 61 | ||
15 | stty -echo | 62 | if [ -z "$password" ]; then |
16 | read -p "Mot de passe reçu par e-mail : " password; echo | 63 | stty -echo |
17 | stty echo | 64 | read -p "Mot de passe reçu par e-mail : " password; echo |
65 | stty echo | ||
66 | fi | ||
18 | 67 | ||
19 | ARCH_DIR=`mktemp -d` | 68 | ARCH_DIR=`mktemp -d` |
20 | ARCH_HOST_SCRIPT="$ARCH_DIR/arch_host_script.sh" | 69 | ARCH_HOST_SCRIPT="$ARCH_DIR/arch_host_script.sh" |
@@ -22,10 +71,13 @@ ARCH_CHROOT_SCRIPT="$ARCH_DIR/arch_chroot_script.sh" | |||
22 | ARCH_INSTALL_SCRIPT="$ARCH_DIR/arch_install_script.sh" | 71 | ARCH_INSTALL_SCRIPT="$ARCH_DIR/arch_install_script.sh" |
23 | ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_host_puppet_configuration_script.sh" | 72 | ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_host_puppet_configuration_script.sh" |
24 | ARCH_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_puppet_configuration_script.sh" | 73 | ARCH_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_puppet_configuration_script.sh" |
74 | ARCH_PUPPET_INITIAL_CONFIGURATION="$ARCH_DIR/puppet_variables.json" | ||
25 | 75 | ||
26 | trap "rm -rf $ARCH_DIR" EXIT | 76 | trap "rm -rf $ARCH_DIR" EXIT |
27 | 77 | ||
28 | #### Base installation stage | 78 | #### Base installation stage |
79 | python $PYTHON_DIRECTORY/get_initial_configuration.py $vps_name > $ARCH_PUPPET_INITIAL_CONFIGURATION | ||
80 | |||
29 | cat > $ARCH_HOST_SCRIPT <<EOF | 81 | cat > $ARCH_HOST_SCRIPT <<EOF |
30 | #!/bin/bash | 82 | #!/bin/bash |
31 | 83 | ||
@@ -61,6 +113,7 @@ cp /tmp/arch_chroot_script.sh /tmp/root.x86_64/ | |||
61 | mount "\$DEVICE" | 113 | mount "\$DEVICE" |
62 | 114 | ||
63 | cp /tmp/arch_install_script.sh "\$MOUNTPOINT/root/" | 115 | cp /tmp/arch_install_script.sh "\$MOUNTPOINT/root/" |
116 | cp /tmp/puppet_variables.json "\$MOUNTPOINT/root/" | ||
64 | 117 | ||
65 | /tmp/root.x86_64/bin/arch-chroot "\$MOUNTPOINT" /root/arch_install_script.sh | 118 | /tmp/root.x86_64/bin/arch-chroot "\$MOUNTPOINT" /root/arch_install_script.sh |
66 | EOF | 119 | EOF |
@@ -100,7 +153,7 @@ EOF | |||
100 | cat > $ARCH_INSTALL_SCRIPT <<EOF | 153 | cat > $ARCH_INSTALL_SCRIPT <<EOF |
101 | CODE_PATH="/etc/puppetlabs/code" | 154 | CODE_PATH="/etc/puppetlabs/code" |
102 | rm -rf \$CODE_PATH | 155 | rm -rf \$CODE_PATH |
103 | git clone -b master --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH | 156 | git clone -b $git_branch --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH |
104 | puppet apply --test \$CODE_PATH/manifests/site.pp | 157 | puppet apply --test \$CODE_PATH/manifests/site.pp |
105 | # The password seed requires puppet to be run twice | 158 | # The password seed requires puppet to be run twice |
106 | puppet apply --test \$CODE_PATH/manifests/site.pp | 159 | puppet apply --test \$CODE_PATH/manifests/site.pp |
@@ -110,11 +163,11 @@ chmod a+x $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT | |||
110 | 163 | ||
111 | expect -f - <<EOF | 164 | expect -f - <<EOF |
112 | set timeout -1 | 165 | set timeout -1 |
113 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT root@$vps_name:/tmp | 166 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_INITIAL_CONFIGURATION $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT $host_user@$vps_name:/tmp |
114 | expect "assword:" | 167 | expect "assword:" |
115 | send "$password\n" | 168 | send "$password\n" |
116 | expect eof | 169 | expect eof |
117 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no root@$vps_name /tmp/arch_host_script.sh | 170 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $host_user@$vps_name /tmp/arch_host_script.sh |
118 | expect "assword:" | 171 | expect "assword:" |
119 | send "$password\r" | 172 | send "$password\r" |
120 | expect eof | 173 | expect eof |
@@ -142,19 +195,18 @@ chmod a+x $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRI | |||
142 | 195 | ||
143 | expect -f - <<EOF | 196 | expect -f - <<EOF |
144 | set timeout -1 | 197 | set timeout -1 |
145 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT root@$vps_name:/tmp | 198 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT $host_user@$vps_name:/tmp |
146 | expect "assword:" | 199 | expect "assword:" |
147 | send "$password\n" | 200 | send "$password\n" |
148 | expect eof | 201 | expect eof |
149 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no root@$vps_name /tmp/arch_host_puppet_configuration_script.sh | 202 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $host_user@$vps_name /tmp/arch_host_puppet_configuration_script.sh |
150 | expect "assword:" | 203 | expect "assword:" |
151 | send "$password\r" | 204 | send "$password\r" |
152 | expect eof | 205 | expect eof |
153 | EOF | 206 | EOF |
154 | 207 | ||
155 | ### Installation finished | 208 | ### Installation finished |
156 | read -p "Reboot to normal? [Y/n]" reboot | 209 | if [ -z "$no_reboot" -a -z "$no_reboot_end" ]; then |
157 | if [ "x$reboot" != "xn" ]; then | ||
158 | echo "Rebooting" | 210 | echo "Rebooting" |
159 | python $PYTHON_DIRECTORY/reboot_vps_server.py --local "$vps_name" | 211 | python $PYTHON_DIRECTORY/reboot_vps_server.py --local "$vps_name" |
160 | fi | 212 | fi |
diff --git a/environments/production/hiera.yaml b/environments/production/hiera.yaml index 44c7ecd..9cedf47 100644 --- a/environments/production/hiera.yaml +++ b/environments/production/hiera.yaml | |||
@@ -15,6 +15,9 @@ hierarchy: | |||
15 | path: "nodes/%{facts.ec2_metadata.hostname}.yaml" | 15 | path: "nodes/%{facts.ec2_metadata.hostname}.yaml" |
16 | ### /FIXME | 16 | ### /FIXME |
17 | 17 | ||
18 | - name: "Initialization variables" | ||
19 | path: "/root/puppet_variables.json" | ||
20 | |||
18 | - name: "Per-role data" | 21 | - name: "Per-role data" |
19 | mapped_paths: [ldapvar.self.vars.roles, role, "roles/%{role}.yaml"] | 22 | mapped_paths: [ldapvar.self.vars.roles, role, "roles/%{role}.yaml"] |
20 | 23 | ||
diff --git a/modules/base_installation/files/services/en-dhcp.network b/modules/base_installation/files/services/en-dhcp.network deleted file mode 100644 index 6eef0e9..0000000 --- a/modules/base_installation/files/services/en-dhcp.network +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | [Match] | ||
2 | Name=en* | ||
3 | |||
4 | [Network] | ||
5 | DHCP=yes | ||
6 | |||
7 | [DHCP] | ||
8 | UseMTU=true | ||
diff --git a/modules/base_installation/lib/facter/ldapvar.rb b/modules/base_installation/lib/facter/ldapvar.rb index ff8e898..3ee6623 100644 --- a/modules/base_installation/lib/facter/ldapvar.rb +++ b/modules/base_installation/lib/facter/ldapvar.rb | |||
@@ -1,46 +1,49 @@ | |||
1 | require 'ldap' | 1 | begin |
2 | require 'puppet/util/ldap/connection' | 2 | require 'ldap' |
3 | 3 | require 'puppet/util/ldap/connection' | |
4 | Facter.add("ldapvar") do | 4 | |
5 | setcode do | 5 | Facter.add("ldapvar") do |
6 | if Puppet[:node_terminus].to_sym != :ldap | 6 | setcode do |
7 | data = [] | 7 | if Puppet[:node_terminus].to_sym != :ldap |
8 | else | 8 | data = [] |
9 | begin | 9 | else |
10 | conn = Puppet::Util::Ldap::Connection.instance | 10 | begin |
11 | conn.start | 11 | conn = Puppet::Util::Ldap::Connection.instance |
12 | connection = conn.connection | 12 | conn.start |
13 | rescue ::LDAP::ResultError => e | 13 | connection = conn.connection |
14 | raise Puppet::ParseError, ("ldapquery(): LDAP ResultError - #{e.message}") | 14 | rescue ::LDAP::ResultError => e |
15 | end | 15 | raise Puppet::ParseError, ("ldapquery(): LDAP ResultError - #{e.message}") |
16 | 16 | end | |
17 | host = Facter.value('ec2_metadata')["hostname"] | ||
18 | base = Puppet[:ldapbase] | ||
19 | scope = ::LDAP::LDAP_SCOPE_SUBTREE | ||
20 | filter = "(objectclass=*)" | ||
21 | |||
22 | data = { | ||
23 | :self => {}, | ||
24 | :other => [], | ||
25 | } | ||
26 | |||
27 | connection.search(base, scope, filter) do |entry| | ||
28 | data_ = entry.to_hash | ||
29 | data_['vars'] = (data_[Puppet[:ldapstackedattrs]] || []) | ||
30 | .map { |var| var.split("=", 2) } | ||
31 | .group_by { |(key, value)| key } | ||
32 | .map { |key, value| [key, value.map(&:last)] } | ||
33 | .to_h | ||
34 | |||
35 | data[:other] << data_ | ||
36 | 17 | ||
37 | if data_["cn"].any? { |cn| cn == host } | 18 | host = Facter.value('ec2_metadata')["hostname"] |
38 | data[:self] = data_ | 19 | base = Puppet[:ldapbase] |
20 | scope = ::LDAP::LDAP_SCOPE_SUBTREE | ||
21 | filter = "(objectclass=*)" | ||
22 | |||
23 | data = { | ||
24 | :self => {}, | ||
25 | :other => [], | ||
26 | } | ||
27 | |||
28 | connection.search(base, scope, filter) do |entry| | ||
29 | data_ = entry.to_hash | ||
30 | data_['vars'] = (data_[Puppet[:ldapstackedattrs]] || []) | ||
31 | .map { |var| var.split("=", 2) } | ||
32 | .group_by { |(key, value)| key } | ||
33 | .map { |key, value| [key, value.map(&:last)] } | ||
34 | .to_h | ||
35 | |||
36 | data[:other] << data_ | ||
37 | |||
38 | if data_["cn"].any? { |cn| cn == host } | ||
39 | data[:self] = data_ | ||
40 | end | ||
39 | end | 41 | end |
40 | end | ||
41 | 42 | ||
42 | data | 43 | data |
44 | end | ||
43 | end | 45 | end |
44 | end | 46 | end |
47 | rescue LoadError | ||
48 | # No facts | ||
45 | end | 49 | end |
46 | |||
diff --git a/modules/base_installation/manifests/services.pp b/modules/base_installation/manifests/services.pp index b48c3b5..c641f4b 100644 --- a/modules/base_installation/manifests/services.pp +++ b/modules/base_installation/manifests/services.pp | |||
@@ -38,13 +38,14 @@ class base_installation::services inherits base_installation { | |||
38 | group => "root" | 38 | group => "root" |
39 | } | 39 | } |
40 | 40 | ||
41 | $ip6 = lookup("ips.v6") |$key| { {} } | ||
41 | file { '/etc/systemd/network/en-dhcp.network': | 42 | file { '/etc/systemd/network/en-dhcp.network': |
42 | ensure => "present", | 43 | ensure => "present", |
43 | path => "/etc/systemd/network/en-dhcp.network", | 44 | path => "/etc/systemd/network/en-dhcp.network", |
44 | source => 'puppet:///modules/base_installation/services/en-dhcp.network', | 45 | content => template('base_installation/services/en-dhcp.network.erb'), |
45 | mode => "0644", | 46 | mode => "0644", |
46 | owner => "root", | 47 | owner => "root", |
47 | group => "root" | 48 | group => "root" |
48 | } | 49 | } |
49 | 50 | ||
50 | } | 51 | } |
diff --git a/modules/base_installation/templates/services/en-dhcp.network.erb b/modules/base_installation/templates/services/en-dhcp.network.erb new file mode 100644 index 0000000..4f55582 --- /dev/null +++ b/modules/base_installation/templates/services/en-dhcp.network.erb | |||
@@ -0,0 +1,13 @@ | |||
1 | [Match] | ||
2 | Name=en* | ||
3 | |||
4 | [Network] | ||
5 | DHCP=ipv4 | ||
6 | |||
7 | <%- unless @ip6.empty? -%> | ||
8 | Address=<%= @ip6["ipAddress"] %>/<%= @ip6["mask"] %> | ||
9 | Gateway=<%= @ip6["gateway"] %> | ||
10 | <%- end -%> | ||
11 | |||
12 | [DHCP] | ||
13 | UseMTU=true | ||
diff --git a/python/get_initial_configuration.py b/python/get_initial_configuration.py new file mode 100644 index 0000000..0c6f698 --- /dev/null +++ b/python/get_initial_configuration.py | |||
@@ -0,0 +1,37 @@ | |||
1 | # -*- encoding: utf-8 -*- | ||
2 | import json | ||
3 | try: | ||
4 | from ovh import ovh | ||
5 | except ImportError: | ||
6 | # In case it's installed globally | ||
7 | import ovh | ||
8 | import sys | ||
9 | |||
10 | infos = {} | ||
11 | |||
12 | # Credentials are stored in ~/.ovh.conf | ||
13 | # See ovh/README.rst | ||
14 | client = ovh.Client() | ||
15 | |||
16 | vps_list = client.get('/vps/') | ||
17 | if sys.argv[-1] in vps_list: | ||
18 | vps = sys.argv[-1] | ||
19 | else: | ||
20 | print("VPS not in list:") | ||
21 | for vps in vps_list: | ||
22 | print(vps) | ||
23 | sys.exit(1) | ||
24 | |||
25 | ips = client.get('/vps/{}/ips'.format(vps)) | ||
26 | |||
27 | infos["ips"] = {} | ||
28 | for ip in ips: | ||
29 | ip_infos = client.get('/vps/{}/ips/{}'.format(vps, ip)) | ||
30 | |||
31 | if ip_infos["version"] == "v4": | ||
32 | infos["ips"]["v4"] = ip_infos | ||
33 | else: | ||
34 | infos["ips"]["v6"] = ip_infos | ||
35 | infos["ips"]["v6"]["mask"] = 128 | ||
36 | |||
37 | print(json.dumps(infos)) | ||
diff --git a/python/reboot_vps_server.py b/python/reboot_vps_server.py index 7ea301a..71c5227 100644 --- a/python/reboot_vps_server.py +++ b/python/reboot_vps_server.py | |||
@@ -1,6 +1,10 @@ | |||
1 | # -*- encoding: utf-8 -*- | 1 | # -*- encoding: utf-8 -*- |
2 | import json | 2 | import json |
3 | from ovh import ovh | 3 | try: |
4 | from ovh import ovh | ||
5 | except ImportError: | ||
6 | # In case it's installed globally | ||
7 | import ovh | ||
4 | import sys | 8 | import sys |
5 | import ovh_helper | 9 | import ovh_helper |
6 | 10 | ||