def power(s, state): center('PDU.power') for outlet in s.__systems[s.target]: ch = s.cdu(outlet) ch.sendline('%s %s' % (state, outlet)) ch.expect('Switched CDU: ') cleave('PDU.power')
def start_jobs(s, jobs): center(s.__class__.__name__ + '.create_jobs') for job in jobs: s.jenkins.build_job(job) sleep(2) cleave(s.__class__.__name__ + '.create_jobs')
def list_instances(s): center(s.__class__.__name__ + '.list_instances') retval = {} response = s.sh('describe-instances --filters "Name=tag:Owner,Values=UbuntuKernelTeam"') for reservation in response['Reservations']: for instance in reservation['Instances']: if instance['State']['Name'] != 'running': continue tags = {} for t in instance['Tags']: tags[t['Key']] = t['Value'] try: if tags['Owner'] == 'UbuntuKernelTeam': retval[tags['Name']] = { 'instance_id' : instance['InstanceId'], 'status_code' : instance['State']['Code'], 'status_name' : instance['State']['Name'], } if 'PublicIpAddress' in instance: retval[tags['Name']]['external_ip'] = instance['PublicIpAddress'] if 'PublicDnsName' in instance: retval[tags['Name']]['fqdn'] = instance['PublicDnsName'] retval[tags['Name']]['__other__'] = instance except KeyError: pass cleave(s.__class__.__name__ + '.list_instances (%s)' % retval) return retval
def load_template(s, file_name): """ Load the template file. """ center(s.__class__.__name__ + '.load_templace') retval = None if file_name[0] == '/' or file_name[0] == '.': # The full path is specified. Use the name as is. # fid = file_name else: # Find it ... # fid = file_name if not os.path.exists(fid): # Current directory fid = os.path.join(os.path.dirname(sys.argv[0]), file_name) if not os.path.exists(fid): fid = None if fid is not None: with open(fid, 'r') as f: retval = Template(f.read()) else: print("Error: Failed to find the template file.") cleave(s.__class__.__name__ + '.load_templace') return retval
def list_instances(s): center(s.__class__.__name__ + '.list_instances') retval = {} result, response = s.sh('instances list') for l in response: if l.startswith('NAME'): continue fields = l.split() if len(fields) == 6: retval[fields[0]] = { 'zone' : fields[1], 'type' : fields[2], 'internal_ip' : fields[3], 'external_ip' : fields[4], 'status' : fields[5], } elif len(fields) == 7: retval[fields[0]] = { 'zone' : fields[1], 'type' : fields[2], 'preemptible' : fields[3], 'internal_ip' : fields[4], 'external_ip' : fields[5], 'status' : fields[6], } cleave(s.__class__.__name__ + '.list_instances (%s)' % retval) return retval
def create(s, instance_name, series, region='us-west1', instance_type='unknown'): center(s.__class__.__name__ + '.create') cdebug(' instance_name: %s' % instance_name) cdebug(' series: %s' % series) cdebug(' region: %s' % region) retval = 0 s.instance_name = instance_name s.series = series # r = '-'.join(region.split('-')[0:2]) # images = CloudImages(s.cloud, series=series, region=r).images try: # print('image: %s' % (s.images[series])) # print('image: %s' % (images[0]['id'])) # cmd = 'instances create %s --zone %s --network "default" --no-restart-on-failure --image-project ubuntu-os-cloud --image %s' % (s.instance_name, region, images[0]['id'].replace('daily-', '')) cmd = 'instances create %s --zone %s --network "default" --no-restart-on-failure --image-project ubuntu-os-cloud --image %s' % (s.instance_name, region, s.images[series]) result, response = s.sh(cmd) for l in response: if l.startswith(s.instance_name): fields = l.split() s.target = fields[4] if s.target is not None: s.wait_for_target() except ShellError as e: retval = 1 for l in e.output: l.strip() print(l) cleave(s.__class__.__name__ + '.create') return retval
def verify_xen_target(s): center('Metal::verify_xen_target') retval = False s.progress('Verifying Xen install') if s.series == 'lucid': cdebug("Can't do lucid") elif s.series == 'precise': result, output = s.ssh('sudo xm list') for line in output: line = line.strip() if 'Domain-0' in line: retval = True break else: result, output = s.ssh('sudo xl list') for line in output: line = line.strip() if 'Domain-0' in line: retval = True break if not retval: error("") error("Failed to find the Domain-0 domain.") error("") cleave('Metal::verify_xen_target (%s)' % retval) return retval
def cycle(s): center('PDU.cycle') print(' Cycling Power... ') s.power('off') sleep(60) s.power('on') cleave('PDU.cycle')
def __init__(self, root): center("JenkinsTestResultsTree.__init__") self.root = root self.arkive = path.join(root, 'archive') cleave("JenkinsTestResultsTree.__init__")
def mainline_firmware_hack(s): ''' Mainline kernels look for their firmware in /lib/firmware and might miss other required firmware. ''' center('Base::mainline_firmware_hack') s.ssh('sudo ln -s /lib/firmware/\$\(uname -r\)/* /lib/firmware/', ignore_result=True) cleave('Base::mainline_firmware_hack')
def __init__(self, rc='test-results.rc'): ''' Load the test-results.rc file into self. ''' center("TestResultsRepository.__init__") try: # Find it ... # fid = rc if not path.exists(fid): # Current directory fid = path.join(path.expanduser('~'), rc) if not path.exists(fid): # Users home directory fid = path.join(path.dirname(argv[0]), rc) if not path.exists(fid): fid = path.join(path.dirname(argv[0]), 'lib', rc) if not path.exists(fid): raise FileDoesntExist(rc) self.cfg = json_load(fid) except FileDoesntExist as e: raise TestResultsRepositoryError( 'The file (%s) does not exist.\n' % e.file_name) cleave("TestResultsRepository.__init__") cleave("TestResultsRepository.__init__")
def disable_apt_periodic_updates(s): center("Base::disable_apt_periodic_updates") s.progress('Disabling Periodic APT Updates') s.ssh( r'sudo sed -i \'s/APT::Periodic::Update-Package-Lists "1"/APT::Periodic::Update-Package-Lists "0"/\' /etc/apt/apt.conf.d/10periodic' ) cleave('Base::disable_apt_periodic_updates')
def enable_live_kernel_patching(s): center("Base::enable_live_kernel_patching") s.progress('Enabling Live Kernel Patching') s.ssh('sudo touch /etc/apt/sources.list.d/canonical-livepatch.list') # FIXME: bjf - Need to use a kernel team config server for this # p = path.join(path.dirname(argv[0]), 'canonical-livepatch.list') with open(p, 'r') as f: for l in f.read().split('\n'): s.ssh( '\'echo \"%s\" | sudo tee -a /etc/apt/sources.list.d/canonical-livepatch.list\'' % l) s.ssh( 'sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 74603F44' ) s.ssh('sudo apt-get update') s.ssh('sudo apt-get install canonical-livepatch') sleep(60) # Give the livepatch daemon a minute to calm down s.ssh(r'sudo sed -i \'s/1/48/\' /etc/default/canonical-livepatch') s.ssh('sudo canonical-livepatch update') cleave('Base::enable_live_kernel_patching')
def __init__(s, target, series, arch, kernel=None, hwe=False, debs=None, ppa=None, dry_run=False, lkp=False, lkp_snappy=False, required_kernel_version=None, flavour='generic', ssh_options=None, ssh_user='******'): center(s.__class__.__name__ + '__init__') Target.__init__(s, target, series, arch, kernel=kernel, hwe=hwe, debs=debs, ppa=ppa, dry_run=dry_run, lkp=lkp, lkp_snappy=lkp_snappy, required_kernel_version=required_kernel_version, flavour=flavour, ssh_options=ssh_options, ssh_user=ssh_user) cleave(s.__class__.__name__ + '__init__')
def main(s): center(s.__class__.__name__ + '.main') retval = 0 s.create_jobs() cleave(s.__class__.__name__ + '.main (%s)' % retval) return retval
def __init__(s, target): center('PDU.__init__') s.__cfg = s.__config() s.__systems = s.__cfg['systems'] s.__cdus = s.__cfg['cdus'] s.target = target s.series = platform.dist()[2] cleave('PDU.__init__')
def __init__(s, cloud, series=None, region=None): ''' ''' center(s.__class__.__name__ + '.__init__') s.cloud = cloud s.series = series s.region = region cleave(s.__class__.__name__ + '.__init__')
def status(s): center('PDU.status') for outlet in s.__systems[s.target]: ch = s.cdu(outlet) ch.sendline('status %s' % outlet) ch.expect('Switched CDU: ') ch.sendline('quit') cleave('PDU.status')
def install_python_minimal(s): ''' From Wily onward, python 2 is no longer installed. ''' center('Base::install_python_minimal') s.progress('Installing python-minimal') s.ssh('sudo apt-get --yes install python-minimal', ignore_result=True) cleave('Base::install_python_minimal')
def series(s, results): center(s.__class__.__name__ + '.series') retval = "unknown" try: # First see if the series is in the results. This might have been done by hand # to add a series where this algorithm doesn't work. # retval = results['attributes']['series'] except KeyError: kv = '' try: kv = results['attributes']['kernel'] m = Debian.version_rc.match(kv) if m: for series in Ubuntu.index_by_series_name: if series in kv: cdebug(" is backport kernel", 'blue') # If the series is in the kernel version string, it is most likely # a "backport" kernel and we should use the series in the version # retval = series break if retval == 'unknown': # Starting with Utopic we are adding the series version to the kernel version and not # the series name. # for k in Ubuntu.db: if '~%s' % k in kv: cdebug(" is backport kernel", 'blue') # If the series is in the kernel version string, it is most likely # a "backport" kernel and we should use the series in the version # retval = Ubuntu.db[k]['name'] break if retval == 'unknown': # What a hack ... if '2.6' == m.group(1): version = '2.6.32' else: version = '%s.0' % ( m.group(1) ) # Only want major and minor for determining the series retval = s.ubuntu.lookup(version)['name'] else: print( " ** WARNING: The kernel version string found in the results data did not match the regex." ) except KeyError: print( " ** WARNING: The kernel version (%s) did not match up with any Ubuntu series." % (results['attributes']['kernel'])) cleave(s.__class__.__name__ + '.series') return retval
def fixup_hosts(s): center('Base::fixup_hosts') s.progress('Fixup /etc/hosts') s.ssh( 'sudo sed -i -e \\\'/localhost/a 127.0.1.1 %s %s\\\' /etc/hosts' % (s.raw_target, s.target), quiet=False, ignore_result=False) cleave('Base::fixup_hosts')
def enable_src(s): ''' On the target system, enable the src packages specified series. ''' center('Base::enable_src') s.progress('Enabling Src') s.ssh('\'cat /etc/apt/sources.list | sed "s/^deb /deb-src /" | sudo tee -a /etc/apt/sources.list\'') s.ssh('sudo apt-get update', ignore_result=True) cleave('Base::enable_src')
def store_results(self, data): center("TestResultsRepository.store_results") destdir = path.join(self.results_dir, 'results.json') cdebug('destdir: "%s"' % destdir) with open(destdir, 'w') as f: f.write(json.dumps(data, sort_keys=True, indent=4)) cleave("TestResultsRepository.store_results")
def dist_upgrade(s): ''' Perform a update and dist-upgrade on a remote system. ''' center('Base::dist_upgrade') s.progress('Dist Upgrade') s.ssh('sudo apt-get update', ignore_result=True) s.ssh('sudo DEBIAN_FRONTEND=noninteractive UCF_FORCE_CONFFNEW=1 apt-get --yes dist-upgrade') cleave('Base::dist_upgrade')
def kernel_upgrade(s): ''' Perform a update of the kernels on a remote system. ''' center('Base::kernel_upgrade') s.progress('Kernel Upgrade') s.ssh('sudo apt-get update', ignore_result=True) s.ssh('sudo apt-get --yes install linux-image-generic linux-headers-generic') cleave('Base::kernel_upgrade')
def prossh(s, cmd, quiet=True, ignore_result=False, additional_ssh_options=''): ''' Helper for ssh'ing to the provisioning server. This is done a lot with the same options over and over. ''' center("Base::prossh") result, output = Shell.ssh(s.ps.server, cmd, additional_ssh_options=additional_ssh_options, user=s.ps.user, quiet=quiet, ignore_result=ignore_result) cleave("Base::prossh (%d)" % result) return result, output
def ssh(s, cmd, additional_ssh_options='', quiet=True, ignore_result=False): ''' This ssh method uses the lower-level ssh function for actuall remote shell to the target system. This helper automatically provides the 'target' and 'user' options to every ssh call. ''' center("Base::ssh") result, output = Shell.ssh(s.target, cmd, user=s.ps.sut_user, additional_ssh_options=additional_ssh_options, quiet=quiet, ignore_result=ignore_result) cleave("Base::ssh") return result, output
def enable_proposed(s): ''' On the target system, enable the -proposed archive pocket for the specified series. ''' center('Base::enable_proposed') s.progress('Enabling Proposed') s.ssh('\'grep "%s main" /etc/apt/sources.list | sed s/\ %s\ /\ %s-proposed\ / | sudo tee -a /etc/apt/sources.list\'' % (s.series, s.series, s.series)) s.ssh('sudo apt-get update', ignore_result=True) cleave('Base::enable_proposed')
def remove_hwe(s): ''' Remove all the packages that have to do with hwe kernels ''' center(s.__class__.__name__ + '.remove_hwe') s.ssh( '\'dpkg -l | grep linux- | grep "\-hwe-" | tr -s " " | cut -f 2 -d " " | sudo xargs apt-get --yes --assume-yes purge\'' ) s.ssh( '\'dpkg -l | grep linux- | grep "~" | tr -s " " | cut -f 2 -d " " | sudo xargs apt-get --yes --assume-yes purge\'' ) cleave(s.__class__.__name__ + '.remove_hwe')
def kernel_upgrade(s): ''' Perform a update of the kernels on a remote system. ''' center(s.__class__.__name__ + '.kernel_upgrade') s.progress('Kernel Upgrade') s.remove_hwe() s.ssh('sudo apt-get update', ignore_result=True) s.ssh( 'sudo apt-get --yes install linux-image-generic linux-headers-generic' ) cleave(s.__class__.__name__ + '.kernel_upgrade')