babeltrace: check header include guards in lint job
[lttng-ci.git] / automation / update_standalone.py
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 APIKEY = ''
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 && package-cleanup -y --oldkernels --count=2 && 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=APIKEY)
73
74 # Get jenkins node
75 print("Getting node %s from Jenkins..." % instance_name)
76 node = jenkins.get_node(instance_name)
77
78 if not node:
79 print("Could not get node %s on %s" % (instance_name, JENKINS_URL))
80 sys.exit(1)
81
82 # Check if node is idle
83 if not node.is_idle:
84 print("Node %s is not idle" % instance_name)
85 sys.exit(1)
86
87
88 # Set node temporarily offline
89 if not node.is_temporarily_offline():
90 node.toggle_temporarily_offline('Down for upgrade to base snapshot')
91
92 # Get libvirt connexion
93 print("Opening libvirt connexion to %s..." % vmhost_name)
94 vmhost = libvirt.open("qemu+ssh://root@%s/system" % vmhost_name)
95
96 if not vmhost:
97 print("Could not connect to libvirt on %s" % vmhost_name)
98 sys.exit(1)
99
100 # Get instance
101 print("Getting instance %s from libvirt..." % instance_name)
102 vminstance = vmhost.lookupByName(instance_name)
103
104 if not vminstance:
105 print("Could not get instance %s on %s" % (instance_name, vmhost_name))
106 sys.exit(1)
107
108 # If instance is running, shutdown
109 print("Checking if instance %s is running..." % instance_name)
110 if vminstance.isActive():
111 try:
112 print("Shutting down instance %s" % instance_name)
113 vminstance.destroy()
114 except:
115 print("Failed to shutdown %s", instance_name)
116 sys.exit(1)
117
118
119 # Revert to base snapshot
120 print("Getting base snapshot...")
121 basesnap = vminstance.snapshotLookupByName(BASESNAP)
122 if not basesnap:
123 print("Could not find base snapshot %s" % BASESNAP)
124 sys.exit(1)
125
126 #if not basesnap.isCurrent():
127 # print("Not current snapshot")
128
129 print("Reverting to base snapshot...")
130 try:
131 vminstance.revertToSnapshot(basesnap)
132 except:
133 print("Failed to revert to base snapshot %s" % basesnap.getName())
134 sys.exit(1)
135
136 # Launch instance
137 try:
138 print("Starting instance %s.." % instance_name)
139 vminstance.create()
140 except:
141 print("Failed to start instance %s" % instance_name)
142 sys.exit(1)
143
144
145 # Wait for instance to boot
146 print("Waiting for instance to boot...")
147 sleep(10)
148
149 # Run dist-upgrade
150 print("Running upgrade command...")
151 client = paramiko.SSHClient()
152 client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
153 client.load_system_host_keys()
154 client.connect(instance_name, username="root")
155 stdin, stdout, stderr = client.exec_command(DISTRO_COMMAND[distro])
156 while not stdout.channel.exit_status_ready():
157 if stdout.channel.recv_ready():
158 rl, wl, xl = select.select([stdout.channel], [], [], 0.0)
159 if len(rl) > 0:
160 print(stdout.channel.recv(1024)),
161
162 if stdout.channel.recv_exit_status() != 0:
163 print("Update command failed!")
164 sys.exit(1)
165
166 # Close ssh connexion
167 client.close()
168
169 # Shutdown VM
170 print("Shutting down instance...")
171 try:
172 vminstance.shutdown()
173 except:
174 print("Failed to shutdown instance %s" % instance_name)
175 sys.exit(1)
176
177 while vminstance.isActive():
178 sleep(1)
179 print("Waiting for instance to shutdown...")
180
181 # Delete original base snapshot
182 print("Deleting current base snapshot...")
183 try:
184 basesnap.delete()
185 except:
186 print("Failed to delete base snapshot %s" % basesnap.getName())
187 sys.exit(1)
188
189 # Create new base snapshot
190 print("Creating new base snapshot...")
191 try:
192 vminstance.snapshotCreateXML(SNAPSHOTXML)
193 except:
194 print("Failed to create new snapshot.")
195 sys.exit(1)
196
197 # Set node online in jenkins
198 if node.is_temporarily_offline():
199 node.toggle_temporarily_offline()
200
201 # And we're done!
202 print("All done!")
203
204
205 if __name__ == "__main__":
206 main()
207
208 # EOF
This page took 0.033095 seconds and 4 git commands to generate.