def test_get_created(self): with patch.multiple( misc, sh=lambda cmd: self.teuthology_instance, ): o = OpenStackInstance('NAME') assert o.get_created() > 0
def test_volumes(self): with patch.multiple( misc, sh=lambda cmd: self.teuthology_instance, ): o = OpenStackInstance('NAME') assert len(o.get_volumes()) == 3
def test_init(self): with patch.multiple( misc, sh=lambda cmd: self.teuthology_instance, ): o = OpenStackInstance('NAME') assert o['id'] == 'f3ca32d7-212b-458b-a0d4-57d1085af953' o = OpenStackInstance('NAME', {"id": "OTHER"}) assert o['id'] == "OTHER"
def test_get_addresses(self): answers = [self.teuthology_instance_no_addresses, self.teuthology_instance] def sh(self): return answers.pop(0) with patch.multiple(misc, sh=sh): o = OpenStackInstance("NAME") assert o.get_addresses() == "Ext-Net=167.114.233.32"
def test_exists(self): with patch.multiple(misc, sh=lambda cmd: self.teuthology_instance): o = OpenStackInstance("NAME") assert o.exists() def sh_raises(cmd): raise subprocess.CalledProcessError("FAIL", "BAD") with patch.multiple(misc, sh=sh_raises): o = OpenStackInstance("NAME") assert not o.exists()
def test_get_addresses(self): answers = [ self.teuthology_instance_no_addresses, self.teuthology_instance, ] def sh(self): return answers.pop(0) with patch.multiple( misc, sh=sh, ): o = OpenStackInstance('NAME') assert o.get_addresses() == 'Ext-Net=167.114.233.32'
def test_exists(self): with patch.multiple( misc, sh=lambda cmd: self.teuthology_instance, ): o = OpenStackInstance('NAME') assert o.exists() def sh_raises(cmd): raise subprocess.CalledProcessError('FAIL', 'BAD') with patch.multiple( misc, sh=sh_raises, ): o = OpenStackInstance('NAME') assert not o.exists()
def test_get_ip_neutron(self): instance_id = '8e1fd70a-3065-46f8-9c30-84dc028c1834' ip = '10.10.10.4' def sh(cmd): if 'neutron subnet-list' in cmd: return """ [ { "ip_version": 6, "id": "c45b9661-b2ba-4817-9e3a-f8f63bf32989" }, { "ip_version": 4, "id": "e03a3dbc-afc8-4b52-952e-7bf755397b50" } ] """ elif 'neutron port-list' in cmd: return (""" [ { "device_id": "915504ad-368b-4cce-be7c-4f8a83902e28", "fixed_ips": "{\\"subnet_id\\": \\"e03a3dbc-afc8-4b52-952e-7bf755397b50\\", \\"ip_address\\": \\"10.10.10.1\\"}\\n{\\"subnet_id\\": \\"c45b9661-b2ba-4817-9e3a-f8f63bf32989\\", \\"ip_address\\": \\"2607:f298:6050:9afc::1\\"}" }, { "device_id": "{instance_id}", "fixed_ips": "{\\"subnet_id\\": \\"e03a3dbc-afc8-4b52-952e-7bf755397b50\\", \\"ip_address\\": \\"{ip}\\"}\\n{\\"subnet_id\\": \\"c45b9661-b2ba-4817-9e3a-f8f63bf32989\\", \\"ip_address\\": \\"2607:f298:6050:9afc:f816:3eff:fe07:76c1\\"}" }, { "device_id": "17e4a968-4caa-4cee-8e4b-f950683a02bd", "fixed_ips": "{\\"subnet_id\\": \\"e03a3dbc-afc8-4b52-952e-7bf755397b50\\", \\"ip_address\\": \\"10.10.10.5\\"}\\n{\\"subnet_id\\": \\"c45b9661-b2ba-4817-9e3a-f8f63bf32989\\", \\"ip_address\\": \\"2607:f298:6050:9afc:f816:3eff:fe9c:37f0\\"}" } ] """.replace('{instance_id}', instance_id).replace('{ip}', ip)) else: raise Exception("unexpected " + cmd) with patch.multiple( misc, sh=sh, ): assert ip == OpenStackInstance( instance_id, { 'id': instance_id }, ).get_ip_neutron()
def stale_openstack_instances(ctx, instances, locked_nodes): for (instance_id, instance) in instances.items(): i = OpenStackInstance(instance_id) if not i.exists(): log.debug( "stale-openstack: {instance} disappeared, ignored".format( instance=instance_id)) continue if (i.get_created() > config['max_job_time'] + OPENSTACK_DELAY): log.info("stale-openstack: destroying instance {instance}" " because it was created {created} seconds ago" " which is older than" " max_job_time {max_job_time} + {delay}".format( instance=i['name'], created=i.get_created(), max_job_time=config['max_job_time'], delay=OPENSTACK_DELAY)) if not ctx.dry_run: i.destroy() continue name = canonicalize_hostname(i['name'], user=None) if i.get_created() > OPENSTACK_DELAY and name not in locked_nodes: log.info("stale-openstack: destroying instance {instance}" " because it was created {created} seconds ago" " is older than {delay}s and it is not locked".format( instance=i['name'], created=i.get_created(), delay=OPENSTACK_DELAY)) if not ctx.dry_run: i.destroy() continue log.debug("stale-openstack: instance " + i['name'] + " OK")
def destroy(self, name_or_id): log.debug('ProvisionOpenStack:destroy ' + name_or_id) return OpenStackInstance(name_or_id).destroy()
def create(self, num, os_type, os_version, arch, resources_hint): """ Create num OpenStack instances running os_type os_version and return their names. Each instance has at least the resources described in resources_hint. """ log.debug('ProvisionOpenStack:create') if arch is None: arch = self.get_default_arch() resources_hint = self.interpret_hints({ 'machine': config['openstack']['machine'], 'volumes': config['openstack']['volumes'], }, resources_hint) self.init_user_data(os_type, os_version) image = self.image(os_type, os_version, arch) if 'network' in config['openstack']: net = "--nic net-id=" + str(self.net_id(config['openstack']['network'])) else: net = '' flavor = self.flavor(resources_hint['machine'], arch) keypair = config['openstack']['keypair'] or 'teuthology' worker_group = config['openstack']['worker_group'] or 'teuthology-worker' cmd = ("flock --close --timeout 28800 /tmp/teuthology-server-create.lock" + " openstack server create" + " " + config['openstack'].get('server-create', '') + " -f json " + " --image '" + str(image) + "'" + " --flavor '" + str(flavor) + "'" + " --key-name %s " % keypair + " --user-data " + str(self.user_data) + " " + net + " --min " + str(num) + " --max " + str(num) + " --security-group %s" % worker_group + " --property teuthology=" + self.property + " --property ownedby=" + config.openstack['ip'] + " --wait " + " " + self.basename) try: self.run(cmd, type='compute') except CalledProcessError as exc: if "quota exceeded" in exc.output.lower(): raise QuotaExceededError(message=exc.output) raise instances = filter( lambda instance: self.property in instance['Properties'], self.list_instances()) instances = [OpenStackInstance(i['ID']) for i in instances] fqdns = [] try: network = config['openstack'].get('network', '') for instance in instances: ip = instance.get_ip(network) name = self.ip2name(self.basename, ip) self.run("server set " + "--name " + name + " " + instance['ID']) fqdn = name + '.' + config.lab_domain if not misc.ssh_keyscan_wait(fqdn): console_log = misc.sh("openstack console log show %s " "|| true" % instance['ID']) log.error(console_log) raise ValueError('ssh_keyscan_wait failed for ' + fqdn) time.sleep(15) if not self.cloud_init_wait(instance): raise ValueError('cloud_init_wait failed for ' + fqdn) self.attach_volumes(name, resources_hint['volumes']) fqdns.append(fqdn) except Exception as e: log.exception(str(e)) for id in [instance['ID'] for instance in instances]: self.destroy(id) raise e return fqdns