Commit | Line | Data |
---|---|---|
92150710 MJ |
1 | #!/usr/bin/python |
2 | # -*- coding: utf-8 -*- | |
3 | # | |
4 | # Copyright (C) 2015 - Michael Jeanson <mjeanson@efficios.com> | |
5 | # | |
6 | # This program is free software: you can redistribute it and/or modify | |
7 | # it under the terms of the GNU General Public License as published by | |
8 | # the Free Software Foundation, either version 3 of the License, or | |
9 | # (at your option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | ||
19 | """ This script is used to upgrade the base snapshot of standalone ci slaves """ | |
20 | ||
21 | USERNAME = '' | |
22 | PASSWORD = '' | |
23 | JENKINS_URL = 'https://ci.lttng.org' | |
24 | ||
25 | DISTRO_LIST = ['el', 'sles', 'ubuntu'] | |
26 | DEFAULT_DISTRO = 'ubuntu' | |
27 | DISTRO_COMMAND = { | |
28 | 'el': 'yum update -y && yum clean all', | |
29 | 'sles': 'zypper --non-interactive refresh && zypper --non-interactive patch --auto-agree-with-licenses --with-interactive', | |
30 | 'ubuntu': 'apt-get update && apt-get dist-upgrade -V -y && apt-get clean && apt-get --purge autoremove -y', | |
31 | } | |
32 | ||
33 | BASESNAP = 'base-configuration' | |
34 | ||
35 | SNAPSHOTXML = """ | |
36 | <domainsnapshot> | |
37 | <name>%s</name> | |
38 | <description>Snapshot of OS install and updates</description> | |
39 | <memory snapshot='no'/> | |
40 | </domainsnapshot> | |
41 | """ % BASESNAP | |
42 | ||
43 | import argparse | |
44 | import sys | |
45 | import libvirt | |
46 | #from jenkinsapi.jenkins import Jenkins | |
47 | from time import sleep | |
48 | import paramiko | |
49 | import select | |
50 | ||
51 | ||
52 | def main(): | |
53 | """ Main """ | |
54 | ||
55 | parser = argparse.ArgumentParser(description='Update base snapshot.') | |
56 | parser.add_argument('instance_name', metavar='INSTANCE', type=str, | |
57 | help='the shortname of the instance to update') | |
58 | parser.add_argument('vmhost_name', metavar='VMHOST', type=str, | |
59 | help='the hostname of the VM host') | |
60 | parser.add_argument('--distro', choices=DISTRO_LIST, | |
61 | default=DEFAULT_DISTRO, type=str, | |
62 | help='the distro of the target instance') | |
63 | ||
64 | args = parser.parse_args() | |
65 | ||
66 | instance_name = args.instance_name | |
67 | vmhost_name = args.vmhost_name | |
68 | distro = args.distro | |
69 | ||
70 | ||
71 | # Get jenkibs connexion | |
72 | #jenkins = Jenkins(JENKINS_URL, username=USERNAME, password=PASSWORD) | |
73 | ||
74 | # Get jenkins node | |
75 | #node = jenkins.get_node(instance_name) | |
76 | ||
77 | # Set node temporarily offline | |
78 | #node.toggle_temporarily_offline('Down for upgrade to base snapshot') | |
79 | ||
80 | # Get libvirt connexion | |
81 | print("Opening libvirt connexion to %s..." % vmhost_name) | |
82 | vmhost = libvirt.open("qemu+ssh://root@%s/system" % vmhost_name) | |
83 | ||
84 | if not vmhost: | |
85 | print("Could not connect to libvirt on %s" % vmhost_name) | |
86 | sys.exit(1) | |
87 | ||
88 | # Get instance | |
89 | print("Getting instance %s from libvirt..." % instance_name) | |
90 | vminstance = vmhost.lookupByName(instance_name) | |
91 | ||
92 | if not vminstance: | |
93 | print("Could not get instance %s on %s" % (instance_name, vmhost_name)) | |
94 | sys.exit(1) | |
95 | ||
96 | # If instance is running, shutdown | |
97 | print("Checking if instance %s is running..." % instance_name) | |
98 | if vminstance.isActive(): | |
99 | try: | |
100 | print("Shutting down instance %s" % instance_name) | |
101 | vminstance.destroy() | |
102 | except: | |
103 | print("Failed to shutdown %s", instance_name) | |
104 | sys.exit(1) | |
105 | ||
106 | ||
107 | # Revert to base snapshot | |
108 | print("Getting base snapshot...") | |
109 | basesnap = vminstance.snapshotLookupByName(BASESNAP) | |
110 | if not basesnap: | |
111 | print("Could not find base snapshot %s" % BASESNAP) | |
112 | sys.exit(1) | |
113 | ||
114 | #if not basesnap.isCurrent(): | |
115 | # print("Not current snapshot") | |
116 | ||
117 | print("Reverting to base snapshot...") | |
118 | try: | |
119 | vminstance.revertToSnapshot(basesnap) | |
120 | except: | |
121 | print("Failed to revert to base snapshot %s" % basesnap.getName()) | |
122 | sys.exit(1) | |
123 | ||
124 | # Launch instance | |
125 | try: | |
126 | print("Starting instance %s.." % instance_name) | |
127 | vminstance.create() | |
128 | except: | |
129 | print("Failed to start instance %s" % instance_name) | |
130 | sys.exit(1) | |
131 | ||
132 | ||
133 | # Wait for instance to boot | |
134 | print("Waiting for instance to boot...") | |
135 | sleep(10) | |
136 | ||
137 | # Run dist-upgrade | |
138 | print("Running upgrade command...") | |
139 | client = paramiko.SSHClient() | |
140 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | |
141 | client.load_system_host_keys() | |
142 | client.connect(instance_name, username="root") | |
143 | stdin, stdout, stderr = client.exec_command(DISTRO_COMMAND[distro]) | |
144 | while not stdout.channel.exit_status_ready(): | |
145 | if stdout.channel.recv_ready(): | |
146 | rl, wl, xl = select.select([stdout.channel], [], [], 0.0) | |
147 | if len(rl) > 0: | |
148 | print(stdout.channel.recv(1024)), | |
149 | ||
150 | if stdout.channel.recv_exit_status() != 0: | |
151 | print("Update command failed!") | |
152 | sys.exit(1) | |
153 | ||
154 | # Close ssh connexion | |
155 | client.close() | |
156 | ||
157 | # Shutdown VM | |
158 | print("Shutting down instance...") | |
159 | try: | |
160 | vminstance.shutdown() | |
161 | except: | |
162 | print("Failed to shutdown instance %s" % instance_name) | |
163 | sys.exit(1) | |
164 | ||
165 | while vminstance.isActive(): | |
166 | sleep(1) | |
167 | print("Waiting for instance to shutdown...") | |
168 | ||
169 | # Delete original base snapshot | |
170 | print("Deleting current base snapshot...") | |
171 | try: | |
172 | basesnap.delete() | |
173 | except: | |
174 | print("Failed to delete base snapshot %s" % basesnap.getName()) | |
175 | sys.exit(1) | |
176 | ||
177 | # Create new base snapshot | |
178 | print("Creating new base snapshot...") | |
179 | try: | |
180 | vminstance.snapshotCreateXML(SNAPSHOTXML) | |
181 | except: | |
182 | print("Failed to create new snapshot.") | |
183 | sys.exit(1) | |
184 | ||
185 | # And we're done! | |
186 | print("All done!") | |
187 | ||
188 | ||
189 | if __name__ == "__main__": | |
190 | main() | |
191 | ||
192 | # EOF |