1
# abstract backend that is based around ssh login
3
from __future__ import absolute_import, print_function
5
from .UpgradeTestBackend import UpgradeTestBackend
14
class UpgradeTestBackendSSH(UpgradeTestBackend):
15
" abstract backend that works with ssh "
17
def __init__(self, profile):
18
UpgradeTestBackend.__init__(self, profile)
19
self.profiledir = os.path.dirname(profile)
21
self.ssh_key = os.path.abspath(
22
self.config.getWithDefault(
25
"/var/cache/auto-upgrade-tester/ssh-key")
27
if not os.path.exists(self.ssh_key):
28
print("Creating key: %s" % self.ssh_key)
29
subprocess.call(["ssh-keygen","-N","","-f",self.ssh_key])
32
" run a shell in the image "
35
ret = self._runInImage(["/bin/sh"])
37
logging.warn("_runInImage returned: %s" % ret)
40
def ping(self, user="root"):
41
" check if the instance is ready "
42
ret = self._runInImageAsUser(user, ["/bin/true"])
45
def _copyToImage(self, fromF, toF, recursive=False):
46
"copy a file (or a list of files) to the given toF image location"
49
"-q","-q", # shut it up
51
"-o", "StrictHostKeyChecking=no",
52
"-o", "UserKnownHostsFile=%s" % os.path.dirname(
53
self.profile)+"/known_hosts"
57
# we support both single files and lists of files
58
if isinstance(fromF,list):
62
cmd.append("root@%s:%s" % (self.ssh_hostname, toF))
64
ret = subprocess.call(cmd)
67
def _copyFromImage(self, fromF, toF):
68
"copy a file from the given fromF image location"
71
"-q","-q", # shut it up
73
"-o", "StrictHostKeyChecking=no",
74
"-o", "UserKnownHostsFile=%s" % os.path.dirname(self.profile)+"/known_hosts",
75
"root@%s:%s" % (self.ssh_hostname, fromF),
79
ret = subprocess.call(cmd)
83
def _runInImage(self, command, **kwargs):
84
ret = self._runInImageAsUser("root", command, **kwargs)
87
def _runInImageAsUser(self, user, command, **kwargs):
88
"run a given command in the image"
89
# ssh -l root -p 54321 localhost -i profile/server/ssh_key
90
# -o StrictHostKeyChecking=no
91
ret = subprocess.call(["ssh",
96
"-q","-q", # shut it up
98
"-o", "StrictHostKeyChecking=no",
99
"-o", "BatchMode=yes",
100
"-o", "UserKnownHostsFile=%s" % os.path.dirname(self.profile)+"/known_hosts",
105
def installPackages(self, pkgs):
106
" install additional pkgs (list) into the vm before the upgrade "
110
self._runInImage(["apt-get","update"])
111
ret = self._runInImage(["DEBIAN_FRONTEND=noninteractive","apt-get","install", "--reinstall", "-y"]+pkgs)
116
def _copyUpgraderFilesFromBzrCheckout(self):
117
" copy upgrader files from a bzr checkout "
118
print("copy upgrader into image")
119
# copy the upgrade into target+/upgrader-tester/
121
self._runInImage(["mkdir","-p","/upgrade-tester","/etc/update-manager/release-upgrades.d"])
122
for f in glob.glob("%s/*" % self.upgradefilesdir):
123
if not os.path.isdir(f):
125
elif os.path.islink(f):
126
print("Copying link '%s' to image " % f)
127
self._copyToImage(f, "/upgrade-tester", recursive=True)
128
self._copyToImage(files, "/upgrade-tester")
129
# and any other cfg files
130
for f in glob.glob(os.path.dirname(self.profile)+"/*.cfg"):
131
if (os.path.isfile(f) and
132
not os.path.basename(f).startswith("DistUpgrade.cfg")):
133
print("Copying '%s' to image " % f)
134
self._copyToImage(f, "/upgrade-tester")
136
bi="%s/base-installer" % self.upgradefilesdir
137
print("Copying '%s' to image" % bi)
138
self._copyToImage(bi, "/upgrade-tester/", recursive=True)
140
pd="%s/patches" % self.upgradefilesdir
141
print("Copying '%s' to image" % pd)
142
self._copyToImage(pd, "/upgrade-tester/", recursive=True)
144
prereq = self.config.getWithDefault("PreRequists","SourcesList",None)
145
if prereq is not None:
146
prereq = os.path.join(os.path.dirname(self.profile),prereq)
147
print("Copying '%s' to image" % prereq)
148
self._copyToImage(prereq, "/upgrade-tester")
150
def _runBzrCheckoutUpgrade(self, cmd_prefix):
152
print("running the upgrader now")
154
# this is to support direct copying of backport udebs into the
155
# qemu image - useful for testing backports without having to
156
# push them into the archive
160
backports = self.config.getlist("NonInteractive", "PreRequistsFiles")
162
self._runInImage(["mkdir -p /upgrade-tester/backports"])
164
print("Copying %s" % os.path.basename(f))
165
self._copyToImage(f, "/upgrade-tester/backports/")
166
self._runInImage(["(cd /upgrade-tester/backports ; dpkg-deb -x %s . )" % os.path.basename(f)])
167
upgrader_args = " --have-prerequists"
168
upgrader_env = "LD_LIBRARY_PATH=/upgrade-tester/backports/usr/lib PATH=/upgrade-tester/backports/usr/bin:$PATH PYTHONPATH=/upgrade-tester/backports//usr/lib/python$(python -c 'import sys; print(\"%s.%s\" % (sys.version_info[0], sys.version_info[1]))')/site-packages/ "
170
ret = self._runInImage(cmd_prefix+["(cd /upgrade-tester/ ; "
171
"%s./dist-upgrade.py %s)" % (upgrader_env,
176
# - generate diff of upgrade vs fresh install
181
self._copyFromImage("/var/crash/*.crash", self.resultdir)
182
crashfiles = glob.glob(self.resultdir+"/*.crash")
183
# run stuff in post_upgrade_tests dir
186
for script in glob.glob(self.post_upgrade_tests_dir+"*"):
187
if not os.access(script, os.X_OK):
189
result = {'name':os.path.basename(script),
194
start_time = time.time()
195
logging.info("running '%s' post_upgrade_test" % script)
196
self._copyToImage(script, "/tmp/")
197
ret = self._runInImage(["/tmp/%s" % os.path.basename(script)])
199
print("WARNING: post_upgrade_test '%s' failed" % script)
201
log=open(self.resultdir+"/test-%s.FAIL" % os.path.basename(script), "w")
203
result['result'] = 'fail'
204
result['message'] = "post_upgrade_test '%s' failed" % script
205
result['time'] = time.time() - start_time
206
results.append(result)
208
# check for conffiles (the copy is done via a post upgrade script)
209
self._copyFromImage("/tmp/*.dpkg-dist", self.resultdir)
210
# Collect debconf prompts generated by debconf_test.py script
211
self._copyFromImage("/tmp/debconf_*.log", self.resultdir)
212
self.resultsToJunitXML(results, os.path.join(self.resultdir, 'results.xml'))
215
if len(crashfiles) > 0:
216
print("WARNING: crash files detected on the upgrade")