diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rwxr-xr-x | bin/install_script.sh | 124 | ||||
m--------- | python/ovh | 0 | ||||
-rw-r--r-- | python/ovh_helper.py | 19 | ||||
-rw-r--r-- | python/reboot_vps_server.py | 36 | ||||
-rw-r--r-- | python/reinstall_vps_server.py | 82 |
7 files changed, 265 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c7e8afb --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1 @@ | |||
python/__pycache__/ | |||
diff --git a/.gitmodules b/.gitmodules index 24305ea..fa48ebf 100644 --- a/.gitmodules +++ b/.gitmodules | |||
@@ -28,3 +28,6 @@ | |||
28 | [submodule "modules/pacman"] | 28 | [submodule "modules/pacman"] |
29 | path = modules/pacman | 29 | path = modules/pacman |
30 | url = git://git.immae.eu/github/aboe76/puppet-pacman | 30 | url = git://git.immae.eu/github/aboe76/puppet-pacman |
31 | [submodule "python/ovh"] | ||
32 | path = python/ovh | ||
33 | url = git://git.immae.eu/github/ovh/python-ovh | ||
diff --git a/bin/install_script.sh b/bin/install_script.sh new file mode 100755 index 0000000..f250285 --- /dev/null +++ b/bin/install_script.sh | |||
@@ -0,0 +1,124 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | DIRECTORY=$(cd `dirname $0` && pwd) | ||
4 | PYTHON_DIRECTORY="$DIRECTORY/../python" | ||
5 | |||
6 | if [ -n "$1" ]; then | ||
7 | vps_name="$1" | ||
8 | else | ||
9 | read -p "Nom du vps : " vps_name | ||
10 | fi | ||
11 | |||
12 | echo "Patienter le temps du reboot" | ||
13 | python $PYTHON_DIRECTORY/reboot_vps_server.py --rescue "$vps_name" | ||
14 | |||
15 | stty -echo | ||
16 | read -p "Mot de passe reçu par e-mail : " password; echo | ||
17 | stty echo | ||
18 | |||
19 | ARCH_DIR=`mktemp -d` | ||
20 | ARCH_HOST_SCRIPT="$ARCH_DIR/arch_host_script.sh" | ||
21 | ARCH_CHROOT_SCRIPT="$ARCH_DIR/arch_chroot_script.sh" | ||
22 | ARCH_INSTALL_SCRIPT="$ARCH_DIR/arch_install_script.sh" | ||
23 | |||
24 | trap "rm -rf $ARCH_DIR" EXIT | ||
25 | |||
26 | cat > $ARCH_HOST_SCRIPT <<EOF | ||
27 | #!/bin/bash | ||
28 | |||
29 | apt-get update | ||
30 | apt-get install -y haveged | ||
31 | haveged & | ||
32 | |||
33 | cd /tmp | ||
34 | |||
35 | LATEST=\$(curl https://mirrors.kernel.org/archlinux/iso/latest/sha1sums.txt | grep "bootstrap" | head -n1) | ||
36 | SHA1=\$(echo "\$LATEST" | cut -d' ' -f1) | ||
37 | NAME=\$(echo "\$LATEST" | cut -d' ' -f3) | ||
38 | |||
39 | curl -O "https://mirrors.kernel.org/archlinux/iso/latest/\$NAME" | ||
40 | |||
41 | tar -xzf "\$NAME" | ||
42 | |||
43 | echo 'Server = http://archlinux.mirrors.ovh.net/archlinux/\$repo/os/\$arch' > /tmp/root.x86_64/etc/pacman.d/mirrorlist | ||
44 | |||
45 | DEVICE_STR=\$(cat /proc/mounts | grep "/dev/sd.. /mnt/") | ||
46 | DEVICE=\$(echo "\$DEVICE_STR" | cut -d' ' -f1) | ||
47 | MOUNTPOINT=\$(echo "\$DEVICE_STR" | cut -d' ' -f2) | ||
48 | |||
49 | umount "\$DEVICE" | ||
50 | UUID=\$(lsblk -rno UUID "\$DEVICE") | ||
51 | |||
52 | echo "\$UUID" > /tmp/root.x86_64/device_uuid | ||
53 | |||
54 | cp /tmp/arch_chroot_script.sh /tmp/root.x86_64/ | ||
55 | |||
56 | /tmp/root.x86_64/bin/arch-chroot /tmp/root.x86_64/ /arch_chroot_script.sh | ||
57 | |||
58 | mount "\$DEVICE" | ||
59 | |||
60 | cp /tmp/arch_install_script.sh "\$MOUNTPOINT/root/" | ||
61 | |||
62 | /tmp/root.x86_64/bin/arch-chroot "\$MOUNTPOINT" /root/arch_install_script.sh | ||
63 | EOF | ||
64 | |||
65 | |||
66 | cat > $ARCH_CHROOT_SCRIPT <<EOF | ||
67 | #!/bin/bash | ||
68 | |||
69 | pacman-key --init | ||
70 | pacman-key --populate archlinux | ||
71 | |||
72 | UUID=\$(cat /device_uuid) | ||
73 | PART="/dev/disk/by-uuid/\$UUID" | ||
74 | DEVICE=\$(realpath "\$PART") | ||
75 | |||
76 | # mkfs.ext4 -F -U "\$UUID" "\$DEVICE" | ||
77 | mount "\$DEVICE" /mnt | ||
78 | |||
79 | ##### FIXME: mkfs.ext4 would be better #### | ||
80 | for i in /mnt/*; do | ||
81 | if [ "\$i" = "/mnt/boot" ]; then | ||
82 | # keep /boot/grub | ||
83 | rm -f \$i/* | ||
84 | else | ||
85 | rm -rf \$i | ||
86 | fi | ||
87 | done | ||
88 | ##### /FIXME #### | ||
89 | |||
90 | pacstrap /mnt base git puppet | ||
91 | |||
92 | echo "\$PART / auto defaults 0 1" > /mnt/etc/fstab | ||
93 | |||
94 | umount /mnt | ||
95 | EOF | ||
96 | |||
97 | cat > $ARCH_INSTALL_SCRIPT <<EOF | ||
98 | CODE_PATH="/etc/puppetlabs/code" | ||
99 | rm -rf \$CODE_PATH | ||
100 | git clone -b master --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH | ||
101 | puppet apply --test \$CODE_PATH/manifests/site.pp | ||
102 | # The password seed requires puppet to be run twice | ||
103 | puppet apply --test \$CODE_PATH/manifests/site.pp | ||
104 | EOF | ||
105 | |||
106 | chmod a+x $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT | ||
107 | |||
108 | expect -f - <<EOF | ||
109 | set timeout -1 | ||
110 | 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 | ||
111 | expect "assword:" | ||
112 | send "$password\n" | ||
113 | expect eof | ||
114 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no root@$vps_name /tmp/arch_host_script.sh | ||
115 | expect "assword:" | ||
116 | send "$password\r" | ||
117 | expect eof | ||
118 | EOF | ||
119 | |||
120 | read -p "Reboot to normal? [Y/n]" reboot | ||
121 | if [ "x$reboot" != "xn" ]; then | ||
122 | echo "Rebooting" | ||
123 | python $PYTHON_DIRECTORY/reboot_vps_server.py --local "$vps_name" | ||
124 | fi | ||
diff --git a/python/ovh b/python/ovh new file mode 160000 | |||
Subproject 2a0cc19a96d8efc38ca8e1897c8fa38e459beb8 | |||
diff --git a/python/ovh_helper.py b/python/ovh_helper.py new file mode 100644 index 0000000..a49a245 --- /dev/null +++ b/python/ovh_helper.py | |||
@@ -0,0 +1,19 @@ | |||
1 | import time | ||
2 | |||
3 | def show_progress(client, vps, task_type): | ||
4 | running_task_id = client.get("/vps/{}/tasks?type={}".format(vps, task_type))[0] | ||
5 | |||
6 | progress = 0 | ||
7 | state = "todo" | ||
8 | print(" 0 %", end='') | ||
9 | while state != "done": | ||
10 | old_progress = progress | ||
11 | task = client.get("/vps/{}/tasks/{}".format(vps, running_task_id)) | ||
12 | progress = task["progress"] | ||
13 | state = task["state"] | ||
14 | |||
15 | if progress != old_progress: | ||
16 | print("\r{:>3} %".format(progress), end="") | ||
17 | time.sleep(3) | ||
18 | |||
19 | print("\rFinished") | ||
diff --git a/python/reboot_vps_server.py b/python/reboot_vps_server.py new file mode 100644 index 0000000..7ea301a --- /dev/null +++ b/python/reboot_vps_server.py | |||
@@ -0,0 +1,36 @@ | |||
1 | # -*- encoding: utf-8 -*- | ||
2 | import json | ||
3 | from ovh import ovh | ||
4 | import sys | ||
5 | import ovh_helper | ||
6 | |||
7 | # Credentials are stored in ~/.ovh.conf | ||
8 | # See ovh/README.rst | ||
9 | client = ovh.Client() | ||
10 | |||
11 | vps_list = client.get('/vps/') | ||
12 | if sys.argv[-1] in vps_list: | ||
13 | vps = sys.argv[-1] | ||
14 | else: | ||
15 | print("VPS not in list:") | ||
16 | for vps in vps_list: | ||
17 | print(vps) | ||
18 | sys.exit(1) | ||
19 | |||
20 | if "--rescue" in sys.argv: | ||
21 | netboot_mode="rescue" | ||
22 | elif "--local" in sys.argv: | ||
23 | netboot_mode="local" | ||
24 | else: | ||
25 | netboot_mode=None | ||
26 | |||
27 | current_state=client.get("/vps/{}".format(vps))["netbootMode"] | ||
28 | |||
29 | if netboot_mode is None or current_state == netboot_mode: | ||
30 | client.post("/vps/{}/reboot".format(vps)) | ||
31 | task_type="rebootVm" | ||
32 | else: | ||
33 | client.put("/vps/{}".format(vps), netbootMode=netboot_mode) | ||
34 | task_type="setNetboot" | ||
35 | |||
36 | ovh_helper.show_progress(client, vps, task_type) | ||
diff --git a/python/reinstall_vps_server.py b/python/reinstall_vps_server.py new file mode 100644 index 0000000..2eea203 --- /dev/null +++ b/python/reinstall_vps_server.py | |||
@@ -0,0 +1,82 @@ | |||
1 | # -*- encoding: utf-8 -*- | ||
2 | import json | ||
3 | from ovh import ovh | ||
4 | import sys | ||
5 | import ovh_helper | ||
6 | |||
7 | # Credentials are stored in ~/.ovh.conf | ||
8 | # See ovh/README.rst | ||
9 | client = ovh.Client() | ||
10 | |||
11 | vps_list = client.get('/vps/') | ||
12 | if sys.argv[-1] in vps_list: | ||
13 | vps = sys.argv[-1] | ||
14 | else: | ||
15 | print("VPS not in list:") | ||
16 | for vps in vps_list: | ||
17 | print(vps) | ||
18 | sys.exit(1) | ||
19 | |||
20 | current_distribution = client.get('/vps/{}/distribution'.format(vps)) | ||
21 | |||
22 | available_templates = client.get('/vps/{}/templates'.format(vps)) | ||
23 | |||
24 | def print_templates(client, vps, available_templates): | ||
25 | for tid in available_templates: | ||
26 | template = client.get('/vps/{}/templates/{}'.format(vps, tid)) | ||
27 | print("{}: {}".format(template["id"], template["distribution"])) | ||
28 | |||
29 | |||
30 | if "--get-state" in sys.argv: | ||
31 | print(client.get('/vps/{}'.format(vps))["state"]) | ||
32 | elif "--use-current" in sys.argv: | ||
33 | if current_distribution['id'] in available_templates: | ||
34 | print("Current template still available, using it") | ||
35 | result = client.post('/vps/{}/reinstall'.format(vps), templateId=current_distribution['id']) | ||
36 | print(result) | ||
37 | ovh_helper.show_progress(client, vps, "reinstallVm") | ||
38 | else: | ||
39 | print("Current template no more available. Chose among:") | ||
40 | print_templates(client, vps, available_templates) | ||
41 | elif sys.argv[-1] in available_templates: | ||
42 | print("Chosen template available, using it") | ||
43 | result = client.post('/vps/{}/reinstall'.format(vps), templateId=int(sys.argv[-1])) | ||
44 | print(result) | ||
45 | ovh_helper.show_progress(client, vps, "reinstallVm") | ||
46 | else: | ||
47 | print("Chosen template not available. Chose among:") | ||
48 | print_templates(client, vps, available_templates) | ||
49 | |||
50 | # Buy new: | ||
51 | # POST /order/cart | ||
52 | # ovhSubsidiary FR | ||
53 | # POST /order/cart/{cartId}/assign | ||
54 | # GET /vps/datacenter?country=FR | ||
55 | # Get list of vps: | ||
56 | # GET /order/cart/{cartId}/vps | ||
57 | # POST /order/cart/{cartId}/vps | ||
58 | # duration "P1M" | ||
59 | # planCode "vps_ssd_model1" | ||
60 | # pricingMode "default" | ||
61 | # quantity 1 | ||
62 | # POST /order/cart/{cartId}/item/{item}/configuration | ||
63 | # label: "vps_ssd_datacenter" | ||
64 | # value: "gra" | ||
65 | # POST /order/cart/{cartId}/item/{item}/configuration | ||
66 | # label: "vps_ssd_os" | ||
67 | # value: "linux--archlinux--64--en" | ||
68 | # POST /order/cart/{cartId}/item/{item}/configuration | ||
69 | # label: "AUTO_RENEW_VPS" | ||
70 | # value: false | ||
71 | # GET /order/cart/{carId}/summary | ||
72 | # GET /order/cart/{cartId}/checkout | ||
73 | # POST /order/cart/{cartId}/checkout | ||
74 | # waiveRetractationPeriod | ||
75 | |||
76 | # /me/paymentMean ? /me/order/{orderId}/debt/pay ? | ||
77 | |||
78 | # Reboot in rescue: | ||
79 | # PUT /vps/{serviceName} | ||
80 | # netbootMode "rescue" / "local" | ||
81 | # changer son nom: | ||
82 | # displayName: "..." | ||