예제 #1
0
파일: instance.py 프로젝트: sue-su/nova
    def _from_db_object(instance, db_inst, expected_attrs=None):
        """Method to help with migration to objects.

        Converts a database entity to a formal object.
        """
        if expected_attrs is None:
            expected_attrs = []
        # Most of the field names match right now, so be quick
        for field in instance.fields:
            if field in INSTANCE_OPTIONAL_FIELDS + INSTANCE_IMPLIED_FIELDS:
                continue
            elif field == 'deleted':
                instance.deleted = db_inst['deleted'] == db_inst['id']
            else:
                instance[field] = db_inst[field]

        if 'metadata' in expected_attrs:
            instance['metadata'] = utils.metadata_to_dict(db_inst['metadata'])
        if 'system_metadata' in expected_attrs:
            instance['system_metadata'] = utils.metadata_to_dict(
                db_inst['system_metadata'])
        # NOTE(danms): info_cache and security_groups are almost always joined
        # in the DB layer right now, so check to see if they're filled instead
        # of looking at expected_attrs
        if db_inst['info_cache']:
            instance['info_cache'] = instance_info_cache.InstanceInfoCache()
            instance_info_cache.InstanceInfoCache._from_db_object(
                instance['info_cache'], db_inst['info_cache'])

        instance.obj_reset_changes()
        return instance
예제 #2
0
 def test_metadata_to_dict_with_include_deleted(self):
     metadata = [
         {"key": "foo1", "value": "bar", "deleted": 1442875429, "other": "stuff"},
         {"key": "foo2", "value": "baz", "deleted": 0, "other": "stuff2"},
     ]
     self.assertEqual({"foo1": "bar", "foo2": "baz"}, utils.metadata_to_dict(metadata, include_deleted=True))
     self.assertEqual({"foo2": "baz"}, utils.metadata_to_dict(metadata, include_deleted=False))
     # verify correct default behavior
     self.assertEqual(utils.metadata_to_dict(metadata), utils.metadata_to_dict(metadata, include_deleted=False))
예제 #3
0
    def test_shelved_poll_timedout(self):
        active_instance = jsonutils.to_primitive(self._create_fake_instance())
        self.compute.run_instance(self.context, active_instance, {}, {}, [],
                None, None, True, None, False)

        instance = jsonutils.to_primitive(self._create_fake_instance())
        self.compute.run_instance(self.context, instance, {}, {}, [], None,
                None, True, None, False)
        sys_meta = utils.metadata_to_dict(instance['system_metadata'])
        shelved_time = timeutils.utcnow()
        timeutils.set_time_override(shelved_time)
        timeutils.advance_time_seconds(CONF.shelved_offload_time + 1)
        sys_meta['shelved_at'] = timeutils.strtime(at=shelved_time)
        (old, instance) = db.instance_update_and_get_original(self.context,
                instance['uuid'], {'vm_state': vm_states.SHELVED,
                                   'system_metadata': sys_meta})

        def fake_destroy(inst, nw_info, bdm):
            # NOTE(alaski) There are too many differences between an instance
            # as returned by instance_update_and_get_original and
            # instance_get_all_by_filters so just compare the uuid.
            self.assertEqual(instance['uuid'], inst['uuid'])

        self.stubs.Set(self.compute.driver, 'destroy', fake_destroy)
        self.compute._poll_shelved_instances(self.context)
예제 #4
0
파일: instance.py 프로젝트: ammonite/nova
    def _from_db_object(context, instance, db_inst, expected_attrs=None):
        """Method to help with migration to objects.

        Converts a database entity to a formal object.
        """
        if expected_attrs is None:
            expected_attrs = []
        # Most of the field names match right now, so be quick
        for field in instance.fields:
            if field in INSTANCE_OPTIONAL_FIELDS + INSTANCE_IMPLIED_FIELDS:
                continue
            elif field == 'deleted':
                instance.deleted = db_inst['deleted'] == db_inst['id']
            elif field == 'cleaned':
                instance.cleaned = db_inst['cleaned'] == 1
            else:
                instance[field] = db_inst[field]

        if 'metadata' in expected_attrs:
            instance['metadata'] = utils.metadata_to_dict(db_inst['metadata'])
        if 'system_metadata' in expected_attrs:
            instance['system_metadata'] = utils.metadata_to_dict(
                db_inst['system_metadata'])
        if 'fault' in expected_attrs:
            instance['fault'] = (
                instance_fault.InstanceFault.get_latest_for_instance(
                    context, instance.uuid))
        # NOTE(danms): info_cache and security_groups are almost
        # always joined in the DB layer right now, so check to see if
        # they are asked for and are present in the resulting object
        if 'info_cache' in expected_attrs and db_inst.get('info_cache'):
            instance['info_cache'] = instance_info_cache.InstanceInfoCache()
            instance_info_cache.InstanceInfoCache._from_db_object(
                    context, instance['info_cache'], db_inst['info_cache'])
        if ('security_groups' in expected_attrs and
                db_inst.get('security_groups')):
            instance['security_groups'] = security_group.SecurityGroupList()
            security_group._make_secgroup_list(context,
                                               instance['security_groups'],
                                               db_inst['security_groups'])

        instance._context = context
        instance.obj_reset_changes()
        return instance
예제 #5
0
파일: agent.py 프로젝트: sue-su/nova
 def _save_instance_password_if_sshkey_present(self, new_pass):
     sshkey = self.instance.get('key_data')
     if sshkey:
         ctxt = context.get_admin_context()
         enc = crypto.ssh_encrypt_text(sshkey, new_pass)
         sys_meta = utils.metadata_to_dict(self.instance['system_metadata'])
         sys_meta.update(password.convert_password(ctxt,
                                                   base64.b64encode(enc)))
         self.virtapi.instance_update(ctxt, self.instance['uuid'],
                                      {'system_metadata': sys_meta})
예제 #6
0
def extract_instance_type(instance, prefix=''):
    """Create an InstanceType-like object from instance's system_metadata
    information."""

    instance_type = {}
    sys_meta = utils.metadata_to_dict(instance['system_metadata'])
    for key, type_fn in system_metadata_instance_type_props.items():
        type_key = '%sinstance_type_%s' % (prefix, key)
        instance_type[key] = type_fn(sys_meta[type_key])
    return instance_type
예제 #7
0
파일: agent.py 프로젝트: JacobMulero/nova
    def set_admin_password(self, new_pass):
        """Set the root/admin password on the VM instance.

        This is done via an agent running on the VM. Communication between nova
        and the agent is done via writing xenstore records. Since communication
        is done over the XenAPI RPC calls, we need to encrypt the password.
        We're using a simple Diffie-Hellman class instead of a more advanced
        library (such as M2Crypto) for compatibility with the agent code.
        """
        LOG.debug(_('Setting admin password'), instance=self.instance)

        dh = SimpleDH()

        # Exchange keys
        args = {'pub': str(dh.get_public())}
        resp = _call_agent(
            self.session, self.instance, self.vm_ref, 'key_init', args)

        # Successful return code from key_init is 'D0'
        if resp['returncode'] != 'D0':
            msg = _('Failed to exchange keys: %(resp)r') % locals()
            LOG.error(msg, instance=self.instance)
            raise NotImplementedError(msg)

        # Some old versions of the Windows agent have a trailing \\r\\n
        # (ie CRLF escaped) for some reason. Strip that off.
        agent_pub = int(resp['message'].replace('\\r\\n', ''))
        dh.compute_shared(agent_pub)

        # Some old versions of Linux and Windows agent expect trailing \n
        # on password to work correctly.
        enc_pass = dh.encrypt(new_pass + '\n')

        # Send the encrypted password
        args = {'enc_pass': enc_pass}
        resp = _call_agent(
            self.session, self.instance, self.vm_ref, 'password', args)

        # Successful return code from password is '0'
        if resp['returncode'] != '0':
            msg = _('Failed to update password: %(resp)r') % locals()
            LOG.error(msg, instance=self.instance)
            raise NotImplementedError(msg)

        sshkey = self.instance.get('key_data')
        if sshkey:
            ctxt = context.get_admin_context()
            enc = crypto.ssh_encrypt_text(sshkey, new_pass)
            sys_meta = utils.metadata_to_dict(self.instance['system_metadata'])
            sys_meta.update(password.convert_password(ctxt,
                                                      base64.b64encode(enc)))
            self.virtapi.instance_update(ctxt, self.instance['uuid'],
                                         {'system_metadata': sys_meta})

        return resp['message']
예제 #8
0
 def __init__(self, context, info):
     for k, v in info.iteritems():
         if k == 'name':
             setattr(self, 'OS-EXT-SRV-ATTR:instance_name', v)
         elif k == 'metadata':
             setattr(self, k, utils.metadata_to_dict(v))
         else:
             setattr(self, k, v)
     self.flavor_name = conductor_api.instance_type_get(
         context, self.instance_type_id).get('name', 'UNKNOWN')
     LOG.debug(_('INFO %r'), info)
예제 #9
0
 def test_metadata_to_dict(self):
     self.assertEqual(
         utils.metadata_to_dict([{
             'key': 'foo1',
             'value': 'bar'
         }, {
             'key': 'foo2',
             'value': 'baz'
         }]), {
             'foo1': 'bar',
             'foo2': 'baz'
         })
예제 #10
0
파일: instance.py 프로젝트: melwitt/nova
    def _from_db_object(instance, db_inst, expected_attrs=None):
        """Method to help with migration to objects.

        Converts a database entity to a formal object.
        """
        if expected_attrs is None:
            expected_attrs = []
        # Most of the field names match right now, so be quick
        for field in instance.fields:
            if field in ['metadata', 'system_metadata']:
                continue
            instance[field] = db_inst[field]

        if 'metadata' in expected_attrs:
            instance['metadata'] = utils.metadata_to_dict(db_inst['metadata'])
        if 'system_metadata' in expected_attrs:
            instance['system_metadata'] = utils.metadata_to_dict(
                db_inst['system_metadata'])

        instance.obj_reset_changes()
        return instance
예제 #11
0
    def __init__(self, context, info):
        for k, v in info.iteritems():
            if k == 'name':
                setattr(self, 'OS-EXT-SRV-ATTR:instance_name', v)
            elif k == 'metadata':
                setattr(self, k, utils.metadata_to_dict(v))
            else:
                setattr(self, k, v)

        instance_type = flavors.extract_flavor(info)
        self.flavor_name = instance_type.get('name', 'UNKNOWN')
        self.instance_flavor_id = instance_type.get('flavorid', '')
        LOG.debug(_('INFO %r'), info)
예제 #12
0
    def test_shelved_poll_not_timedout(self):
        instance = jsonutils.to_primitive(self._create_fake_instance())
        sys_meta = utils.metadata_to_dict(instance['system_metadata'])
        shelved_time = timeutils.utcnow()
        timeutils.set_time_override(shelved_time)
        timeutils.advance_time_seconds(CONF.shelved_offload_time - 1)
        sys_meta['shelved_at'] = timeutils.strtime(at=shelved_time)
        db.instance_update_and_get_original(self.context, instance['uuid'],
                {'vm_state': vm_states.SHELVED, 'system_metadata': sys_meta})

        self.mox.StubOutWithMock(self.compute.driver, 'destroy')
        self.mox.ReplayAll()
        self.compute._poll_shelved_instances(self.context)
예제 #13
0
    def test_shelved_poll_not_timedout(self):
        instance = jsonutils.to_primitive(self._create_fake_instance())
        self.compute.run_instance(self.context, instance, {}, {}, [], None, None, True, None, False)
        sys_meta = utils.metadata_to_dict(instance["system_metadata"])
        shelved_time = timeutils.utcnow()
        timeutils.set_time_override(shelved_time)
        timeutils.advance_time_seconds(CONF.shelved_offload_time - 1)
        sys_meta["shelved_at"] = timeutils.strtime(at=shelved_time)
        db.instance_update_and_get_original(
            self.context, instance["uuid"], {"vm_state": vm_states.SHELVED, "system_metadata": sys_meta}
        )

        self.mox.StubOutWithMock(self.compute.driver, "destroy")
        self.mox.ReplayAll()
        self.compute._poll_shelved_instances(self.context)
예제 #14
0
파일: utils.py 프로젝트: tr3buchet/nova
def notify_usage_exists(
    context,
    instance_ref,
    current_period=False,
    ignore_missing_network_data=True,
    system_metadata=None,
    extra_usage_info=None,
):
    """Generates 'exists' notification for an instance for usage auditing
    purposes.

    :param current_period: if True, this will generate a usage for the
        current usage period; if False, this will generate a usage for the
        previous audit period.

    :param ignore_missing_network_data: if True, log any exceptions generated
        while getting network info; if False, raise the exception.
    :param system_metadata: system_metadata DB entries for the instance,
        if not None.  *NOTE*: Currently unused here in trunk, but needed for
        potential custom modifications.
    :param extra_usage_info: Dictionary containing extra values to add or
        override in the notification if not None.
    """

    audit_start, audit_end = notifications.audit_period_bounds(current_period)

    bw = notifications.bandwidth_usage(instance_ref, audit_start, ignore_missing_network_data)

    if system_metadata is None:
        system_metadata = utils.metadata_to_dict(instance_ref["system_metadata"])

    # add image metadata to the notification:
    image_meta = notifications.image_meta(system_metadata)

    extra_info = dict(
        audit_period_beginning=str(audit_start), audit_period_ending=str(audit_end), bandwidth=bw, image_meta=image_meta
    )

    if extra_usage_info:
        extra_info.update(extra_usage_info)

    notify_about_instance_usage(
        context, instance_ref, "exists", system_metadata=system_metadata, extra_usage_info=extra_info
    )
예제 #15
0
    def test_shelved_poll_timedout(self):
        instance = jsonutils.to_primitive(self._create_fake_instance())
        sys_meta = utils.metadata_to_dict(instance["system_metadata"])
        shelved_time = timeutils.utcnow()
        timeutils.set_time_override(shelved_time)
        timeutils.advance_time_seconds(CONF.shelved_offload_time + 1)
        sys_meta["shelved_at"] = timeutils.strtime(at=shelved_time)
        (old, instance) = db.instance_update_and_get_original(
            self.context, instance["uuid"], {"vm_state": vm_states.SHELVED, "system_metadata": sys_meta}
        )

        def fake_destroy(inst, nw_info, bdm):
            # NOTE(alaski) There are too many differences between an instance
            # as returned by instance_update_and_get_original and
            # instance_get_all_by_filters so just compare the uuid.
            self.assertEqual(instance["uuid"], inst["uuid"])

        self.stubs.Set(self.compute.driver, "destroy", fake_destroy)
        self.compute._poll_shelved_instances(self.context)
예제 #16
0
파일: password.py 프로젝트: 674009287/nova
def handle_password(req, meta_data):
    ctxt = context.get_admin_context()
    if req.method == 'GET':
        return meta_data.password
    elif req.method == 'POST':
        # NOTE(vish): The conflict will only happen once the metadata cache
        #             updates, but it isn't a huge issue if it can be set for
        #             a short window.
        if meta_data.password:
            raise exc.HTTPConflict()
        if (req.content_length > MAX_SIZE or len(req.body) > MAX_SIZE):
            msg = _("Request is too large.")
            raise exc.HTTPBadRequest(explanation=msg)

        conductor_api = conductor.API()
        instance = conductor_api.instance_get_by_uuid(ctxt, meta_data.uuid)
        sys_meta = utils.metadata_to_dict(instance['system_metadata'])
        sys_meta.update(convert_password(ctxt, req.body))
        conductor_api.instance_update(ctxt, meta_data.uuid,
                                      system_metadata=sys_meta)
    else:
        raise exc.HTTPBadRequest()
예제 #17
0
 def test_metadata_to_dict(self):
     self.assertEqual(
         utils.metadata_to_dict([{"key": "foo1", "value": "bar"}, {"key": "foo2", "value": "baz"}]),
         {"foo1": "bar", "foo2": "baz"},
     )
예제 #18
0
 def test_metadata_to_dict_empty(self):
     self.assertEqual(utils.metadata_to_dict([]), {})
예제 #19
0
def info_from_instance(context, instance_ref, network_info,
                system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param network_info: network_info provided if not None
    :param system_metadata: system_metadata DB entries for the instance,
    if not None.  *NOTE*: Currently unused here in trunk, but needed for
    potential custom modifications.
    """

    def null_safe_str(s):
        return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance_ref['image_ref'])

    instance_type_name = instance_ref.get('instance_type', {}).get('name', '')

    if system_metadata is None:
        system_metadata = utils.metadata_to_dict(
                instance_ref['system_metadata'])

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref['project_id'],
        user_id=instance_ref['user_id'],

        # Identity properties
        instance_id=instance_ref['uuid'],
        display_name=instance_ref['display_name'],
        reservation_id=instance_ref['reservation_id'],
        hostname=instance_ref['hostname'],

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref['instance_type_id'],
        architecture=instance_ref['architecture'],

        # Capacity properties
        memory_mb=instance_ref['memory_mb'],
        disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
        vcpus=instance_ref['vcpus'],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref['root_gb'],
        ephemeral_gb=instance_ref['ephemeral_gb'],

        # Location properties
        host=instance_ref['host'],
        availability_zone=instance_ref['availability_zone'],

        # Date properties
        created_at=str(instance_ref['created_at']),
        # Nova's deleted vs terminated instance terminology is confusing,
        # this should be when the instance was deleted (i.e. terminated_at),
        # not when the db record was deleted. (mdragon)
        deleted_at=null_safe_str(instance_ref.get('terminated_at')),
        launched_at=null_safe_str(instance_ref.get('launched_at')),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref['os_type'],
        kernel_id=instance_ref['kernel_id'],
        ramdisk_id=instance_ref['ramdisk_id'],

        # Status properties
        state=instance_ref['vm_state'],
        state_description=null_safe_str(instance_ref.get('task_state')),

        # accessIPs
        access_ip_v4=instance_ref['access_ip_v4'],
        access_ip_v6=instance_ref['access_ip_v6'],
        )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = instance_ref['metadata']

    instance_info.update(kw)
    return instance_info
예제 #20
0
 def test_metadata_to_dict(self):
     self.assertEqual(utils.metadata_to_dict(
             [{'key': 'foo1', 'value': 'bar'},
              {'key': 'foo2', 'value': 'baz'}]),
                      {'foo1': 'bar', 'foo2': 'baz'})
예제 #21
0
def info_from_instance(context, instance_ref, network_info, system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param network_info: network_info provided if not None
    :param system_metadata: system_metadata DB entries for the instance,
    if not None.  *NOTE*: Currently unused here in trunk, but needed for
    potential custom modifications.
    """

    def null_safe_str(s):
        return str(s) if s else ""

    image_ref_url = glance.generate_image_url(instance_ref["image_ref"])

    instance_type_name = instance_ref.get("instance_type", {}).get("name", "")

    if system_metadata is None:
        system_metadata = utils.metadata_to_dict(instance_ref["system_metadata"])

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref["project_id"],
        user_id=instance_ref["user_id"],
        # Identity properties
        instance_id=instance_ref["uuid"],
        display_name=instance_ref["display_name"],
        reservation_id=instance_ref["reservation_id"],
        hostname=instance_ref["hostname"],
        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref["instance_type_id"],
        architecture=instance_ref["architecture"],
        # Capacity properties
        memory_mb=instance_ref["memory_mb"],
        disk_gb=instance_ref["root_gb"] + instance_ref["ephemeral_gb"],
        vcpus=instance_ref["vcpus"],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref["root_gb"],
        ephemeral_gb=instance_ref["ephemeral_gb"],
        # Location properties
        host=instance_ref["host"],
        availability_zone=instance_ref["availability_zone"],
        # Date properties
        created_at=str(instance_ref["created_at"]),
        # Nova's deleted vs terminated instance terminology is confusing,
        # this should be when the instance was deleted (i.e. terminated_at),
        # not when the db record was deleted. (mdragon)
        deleted_at=null_safe_str(instance_ref.get("terminated_at")),
        launched_at=null_safe_str(instance_ref.get("launched_at")),
        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref["os_type"],
        kernel_id=instance_ref["kernel_id"],
        ramdisk_id=instance_ref["ramdisk_id"],
        # Status properties
        state=instance_ref["vm_state"],
        state_description=null_safe_str(instance_ref.get("task_state")),
        # accessIPs
        access_ip_v4=instance_ref["access_ip_v4"],
        access_ip_v6=instance_ref["access_ip_v6"],
    )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                fixed_ips.append(ip)
        instance_info["fixed_ips"] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info["metadata"] = instance_ref["metadata"]

    instance_info.update(kw)
    return instance_info
예제 #22
0
 def test_metadata_to_dict_empty(self):
     self.assertEqual({}, utils.metadata_to_dict([]))
     self.assertEqual({}, utils.metadata_to_dict([], include_deleted=True))
     self.assertEqual({}, utils.metadata_to_dict([], include_deleted=False))
예제 #23
0
 def test_metadata_to_dict_empty(self):
     self.assertEqual(utils.metadata_to_dict([]), {})
예제 #24
0
 def test_metadata_to_dict_empty(self):
     self.assertEqual({}, utils.metadata_to_dict([]))
     self.assertEqual({}, utils.metadata_to_dict([], include_deleted=True))
     self.assertEqual({}, utils.metadata_to_dict([], include_deleted=False))