Exemple #1
0
    def mount(self, req, body):
        """mount iso to vm """
        context = req.environ['nova.context']
        context.can(ics_vm_pl.BASE_POLICY_NAME)
        vmid = body['vmid']
        isoid = body['isoid']
        if not self._get_ics_session():
            raise webob.exc.HTTPServerError(explanation="ics connect failed !")

        image = self._validate_image(context, isoid)
        if image.get('disk_format')!= 'iso' and image.get('disk_format')!= 'ISO' :
            explanation = _("diskformat must be iso.")
            raise webob.exc.HTTPPreconditionFailed(explanation=explanation)
        self._validate_vm(context, vmid)
        # do ics-vm mount iso
        LOG.info("begin to mount iso to ics_vm : %s", vmid)
        try:
            task_info = self._ics_manager.vm.attach_cdrom(vm_id=vmid, isoid=isoid)
        except Exception as e:
            # do something
            LOG.error("mount iso to ics_vm exception : " + e.message)
            raise webob.exc.HTTPServerError(explanation=e.message)
        LOG.info("end to mount iso to ics_vm : %s", vmid)
        state = task_info['state']
        if state == 'FINISHED':
            res = {'success': True}
        else:
            res = {'success': False}

        return dict(vmMount=res)
Exemple #2
0
def _sync_glance_image_to_lxd(client, context, image_ref):
    """Sync an image from glance to LXD image store.

    The image from glance can't go directly into the LXD image store,
    as LXD needs some extra metadata connected to it.

    The image is stored in the LXD image store with an alias to
    the image_ref. This way, it will only copy over once.
    """
    lock_path = os.path.join(CONF.instances_path, 'locks')
    with lockutils.lock(
            lock_path, external=True,
            lock_file_prefix='lxd-image-{}'.format(image_ref)):

        try:
            image_file = tempfile.mkstemp()[1]
            manifest_file = tempfile.mkstemp()[1]

            image = IMAGE_API.get(context, image_ref)
            if image.get('disk_format') not in ACCEPTABLE_IMAGE_FORMATS:
                raise exception.ImageUnacceptable(
                    image_id=image_ref, reason=_('Bad image format'))
            IMAGE_API.download(context, image_ref, dest_path=image_file)

            metadata = {
                'architecture': image.get(
                    'hw_architecture', obj_fields.Architecture.from_host()),
                'creation_date': int(os.stat(image_file).st_ctime)}
            metadata_yaml = json.dumps(
                metadata, sort_keys=True, indent=4,
                separators=(',', ': '),
                ensure_ascii=False).encode('utf-8') + b"\n"

            tarball = tarfile.open(manifest_file, "w:gz")
            tarinfo = tarfile.TarInfo(name='metadata.yaml')
            tarinfo.size = len(metadata_yaml)
            tarball.addfile(tarinfo, io.BytesIO(metadata_yaml))
            tarball.close()

            with open(manifest_file, 'rb') as manifest:
                with open(image_file, 'rb') as image:
                    image = client.images.create(
                        image.read(), metadata=manifest.read(),
                        wait=True)
            image.add_alias(image_ref, '')

        finally:
            os.unlink(image_file)
            os.unlink(manifest_file)
Exemple #3
0
    def select_image(self, context, image, host_hypervisor, instance,
                     request_spec, filter_properties):
        """
        Select the final image from a image list which come from
        the image_template properties of original image. It's
        a template id where the other images can be found.

        image: the original image passed to nova boot
        host_hypervisor: hypervisor type of host
        instance: instance object
        request_spec: request specification
        filter_properties:
        """
        img_properties = image.get('properties', {})
        if img_properties and img_properties.get('image_template'):
            LOG.info("Start to select a new image ...")
            base_images = img_properties.get('image_template').split(',')
            #base_image = self.select_all_related_img(context, image_uuids)
            for img_uuid in base_images:
                img_info = self.image_api.get(context, img_uuid)
                LOG.debug('img_info: {0}'.format(img_info))
                if img_info.get('properties', {}):
                    image_hv_type = img_info['properties'].get(
                        'hypervisor_type')
                    if image_hv_type and image_hv_type.lower(
                    ) in host_hypervisor.lower():
                        return self.update_properties(img_info, instance,
                                                      request_spec,
                                                      filter_properties)

        return image, instance, request_spec
Exemple #4
0
 def update_properties(self, image, instance, request_spec,
                       filter_properties):
     instance = self.update_instance_image_info(image, instance,
                                                filter_properties)
     request_spec['instance_properties']['image_ref'] = image.get('id')
     request_spec['instance_properties'][
         'system_metadata'] = instance.system_metadata
     request_spec['image'] = image
     return image, instance, request_spec
Exemple #5
0
    def index(self, req, image_id):
        context = req.environ['nova.context']
        try:
            image = self._image_service.show(context, image_id)
        except (exception.NotFound, exception.InvalidImageRef):
            explanation = _("Image not found.")
            raise webob.exc.HTTPNotFound(explanation=explanation)
        image_properties = image.get('properties', None)
        if image_properties:
            managed_disk = image_properties.get('managed_disk', False)

        return self._return_dict(image_id, managed_disk)
Exemple #6
0
 def update_instance_image_info(image, instance, filter_properties):
     instance.image_ref = image.get('id')
     from nova import utils as nova_utils
     system_metadata = nova_utils.get_system_metadata_from_image(
         image, filter_properties.get('instance_type'))
     keys = instance.system_metadata.keys()
     for item in keys:
         if item.startswith('image_'):
             del instance.system_metadata[item]
     instance.system_metadata.update(system_metadata)
     instance.system_metadata.setdefault('image_base_image_ref',
                                         instance['image_ref'])
     return instance
Exemple #7
0
 def remove_invalid_hosts(self, images, hosts):
     valid_host = []
     for host in hosts:
         for image in images:
             img_hy_type = image.get('properties',
                                     {}).get('hypervisor_type')
             host_hv_type = host.obj.hypervisor_type.lower()
             if host_hv_type == 'ironic':
                 host_hv_type = 'baremetal'
             if not img_hy_type or (img_hy_type and img_hy_type.lower()
                                    not in host_hv_type):
                 continue
             valid_host.append(host)
     LOG.debug('valid host: {0}'.format(valid_host))
     return valid_host
Exemple #8
0
    def _image_to_xml_detailed(self, xml_doc, image):
        image_node = xml_doc.createElement('image')
        self._add_image_attributes(image_node, image)

        if 'server' in image:
            server_node = self._create_server_node(xml_doc, image['server'])
            image_node.appendChild(server_node)

        metadata = image.get('metadata', {}).items()
        if len(metadata) > 0:
            metadata_node = self._create_metadata_node(xml_doc, metadata)
            image_node.appendChild(metadata_node)

        link_nodes = self._create_link_nodes(xml_doc, image['links'])
        for link_node in link_nodes:
            image_node.appendChild(link_node)

        return image_node
Exemple #9
0
    def _image_to_xml_detailed(self, xml_doc, image):
        image_node = xml_doc.createElement('image')
        self._add_image_attributes(image_node, image)

        if 'server' in image:
            server_node = self._create_server_node(xml_doc, image['server'])
            image_node.appendChild(server_node)

        metadata = image.get('metadata', {}).items()
        if len(metadata) > 0:
            metadata_node = self._create_metadata_node(xml_doc, metadata)
            image_node.appendChild(metadata_node)

        link_nodes = self._create_link_nodes(xml_doc,
                                             image['links'])
        for link_node in link_nodes:
            image_node.appendChild(link_node)

        return image_node
 def _get_metadata(self, context, image_id, image=None):
     if not image:
         image = self.image_service.show(context, image_id)
     metadata = image.get('properties', {})
     return metadata
 def check_is_bool(image, key):
     val = image.get('deleted')
     if not isinstance(val, bool):
         self.fail('image\'s "%s" attribute wasn\'t '
                   'a bool: %r' % (key, val))
Exemple #12
0
 def _get_metadata(self, context, image_id, image=None):
     if not image:
         image = self.image_service.show(context, image_id)
     metadata = image.get('properties', {})
     return metadata
Exemple #13
0
    def build_instances(self,
                        context,
                        instances,
                        image,
                        filter_properties,
                        admin_password,
                        injected_files,
                        requested_networks,
                        security_groups,
                        block_device_mapping=None,
                        legacy_bdm=True):
        # TODO(ndipanov): Remove block_device_mapping and legacy_bdm in version
        #                 2.0 of the RPC API.
        # TODO(danms): Remove this in version 2.0 of the RPC API
        if (requested_networks and not isinstance(requested_networks,
                                                  objects.NetworkRequestList)):
            requested_networks = objects.NetworkRequestList(objects=[
                objects.NetworkRequest.from_tuple(t)
                for t in requested_networks
            ])
        # TODO(melwitt): Remove this in version 2.0 of the RPC API
        flavor = filter_properties.get('instance_type')
        if flavor and not isinstance(flavor, objects.Flavor):
            # Code downstream may expect extra_specs to be populated since it
            # is receiving an object, so lookup the flavor to ensure this.
            flavor = objects.Flavor.get_by_id(context, flavor['id'])
            filter_properties = dict(filter_properties, instance_type=flavor)

        request_spec = {}
        try:
            # check retry policy. Rather ugly use of instances[0]...
            # but if we've exceeded max retries... then we really only
            # have a single instance.
            scheduler_utils.populate_retry(filter_properties,
                                           instances[0].uuid)
            request_spec = scheduler_utils.build_request_spec(
                context, image, instances)
            hosts = self._schedule_instances(context, request_spec,
                                             filter_properties)
        except Exception as exc:
            updates = {'vm_state': vm_states.ERROR, 'task_state': None}
            for instance in instances:
                self._set_vm_state_and_notify(context, instance.uuid,
                                              'build_instances', updates, exc,
                                              request_spec)
                self._cleanup_allocated_networks(context, instance,
                                                 requested_networks)
            return

        host_hypervisor = ''
        hosts_info = []
        reselect_flag = self.need_select_image(request_spec)
        if reselect_flag:
            # Normal user need promoted privilege to search db
            elevated = context.elevated()
            hosts_info = db.compute_node_get_all(elevated)
            LOG.debug("hosts_info: {0}".format(hosts_info))

        for (instance, host) in six.moves.zip(instances, hosts):
            if reselect_flag:
                for hi in hosts_info:
                    if hi.get('service') and hi['service'].get(
                            'host') == host['host']:
                        host_hypervisor = hi.get('hypervisor_type')
                        LOG.debug(
                            'host_hypervisor: {0}'.format(host_hypervisor))
                        break

                image, instance, request_spec = self.select_image(
                    context, image, host_hypervisor, instance, request_spec,
                    filter_properties)
                LOG.debug("Final image: {0}".format(image.get('id')))

            try:
                instance.save()
                instance.refresh()
            except (exception.InstanceNotFound,
                    exception.InstanceInfoCacheNotFound):
                LOG.debug('Instance deleted during build', instance=instance)
                continue
            local_filter_props = copy.deepcopy(filter_properties)
            scheduler_utils.populate_filter_properties(local_filter_props,
                                                       host)
            # The block_device_mapping passed from the api doesn't contain
            # instance specific information
            bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                context, instance.uuid)

            self.compute_rpcapi.build_and_run_instance(
                context,
                instance=instance,
                host=host['host'],
                image=image,
                request_spec=request_spec,
                filter_properties=local_filter_props,
                admin_password=admin_password,
                injected_files=injected_files,
                requested_networks=requested_networks,
                security_groups=security_groups,
                block_device_mapping=bdms,
                node=host['nodename'],
                limits=host['limits'])
Exemple #14
0
    def notify(self, context, message, priority, retry=False):
        ctxt = self._deserialize_context(context)

        event_type = message.get('event_type')
        if event_type in CONF.wiki_eventtype_blacklist:
            return
        if event_type not in CONF.wiki_eventtype_whitelist:
            LOG.debug("Ignoring message type %s" % event_type)
            return

        LOG.debug("Handling message type %s" % event_type)

        payload = message['payload']
        instance = payload['instance_id']
        instance_name = payload['display_name']
        project_id = payload['tenant_id']

        if project_id in CONF.wiki_project_blacklist:
            LOG.debug("Ignoring project %s" % project_id)
            return

        template_param_dict = {}
        for field in self.RawTemplateFields:
            template_param_dict[field] = payload[field]

        template_param_dict['username'] = payload['user_id']

        fqdn = "%s.%s.%s" % (instance_name, project_id,
                             CONF.wiki_instance_dns_domain)
        resource_name = fqdn

        if event_type == 'compute.instance.delete.end':
            # No need to gather up instance info, just delete the page
            self.page_editor.edit_page("", resource_name, True)
            return

        inst = objects.Instance.get_by_uuid(ctxt, instance)

        simple_id = inst['id']
        ec2_id = 'i-%08x' % simple_id

        template_param_dict['cpu_count'] = inst['vcpus']
        template_param_dict['disk_gb_current'] = inst['ephemeral_gb']
        template_param_dict['host'] = inst['host']
        template_param_dict['reservation_id'] = inst['reservation_id']
        template_param_dict['availability_zone'] = inst['availability_zone']
        template_param_dict['original_host'] = inst['launched_on']
        template_param_dict['fqdn'] = fqdn
        template_param_dict['ec2_id'] = ec2_id
        template_param_dict['project_name'] = project_id
        template_param_dict['region'] = CONF.wiki_instance_region

        ips = []
        floating_ips = []

        try:
            nw_info = network.API().get_instance_nw_info(ctxt, inst)
            ip_objs = nw_info.fixed_ips()
            floating_ip_objs = nw_info.floating_ips()

            ips = [ip['address'] for ip in ip_objs]
            floating_ips = [ip['address'] for ip in floating_ip_objs]
        except exception.FixedIpNotFoundForInstance:
            ips = []
            floating_ips = []

        template_param_dict['private_ip'] = ','.join(ips)
        template_param_dict['public_ip'] = ','.join(floating_ips)

        sec_groups = inst['security_groups']
        grps = [grp['name'] for grp in sec_groups]
        template_param_dict['security_group'] = ','.join(grps)

        if inst['image_ref']:
            try:
                image = self._image_service.show(ctxt, inst['image_ref'])
                image_name = image.get('name', inst['image_ref'])
                template_param_dict['image_name'] = image_name
            except (TypeError, exception.ImageNotAuthorized):
                template_param_dict['image_name'] = inst['image_ref']
        else:
            template_param_dict['image_name'] = 'tbd'

        fields_string = ""
        for key in template_param_dict:
            fields_string += "\n|%s=%s" % (key, template_param_dict[key])

        self.page_editor.edit_page(fields_string, resource_name, False)
Exemple #15
0
def _sync_glance_image_to_lxd(client, context, image_ref):
    """Sync an image from glance to LXD image store.

    The image from glance can't go directly into the LXD image store,
    as LXD needs some extra metadata connected to it.

    The image is stored in the LXD image store with an alias to
    the image_ref. This way, it will only copy over once.
    """
    lock_path = os.path.join(CONF.instances_path, 'locks')
    with lockutils.lock(
            lock_path, external=True,
            lock_file_prefix='lxd-image-{}'.format(image_ref)):

        # NOTE(jamespage): Re-query by image_ref to ensure
        #                  that another process did not
        #                  sneak infront of this one and create
        #                  the same image already.
        try:
            client.images.get_by_alias(image_ref)
            return
        except lxd_exceptions.LXDAPIException as e:
            if e.response.status_code != 404:
                raise

        try:
            image_file = tempfile.mkstemp()[1]
            manifest_file = tempfile.mkstemp()[1]

            image = IMAGE_API.get(context, image_ref)
            if image.get('disk_format') not in ACCEPTABLE_IMAGE_FORMATS:
                raise exception.ImageUnacceptable(
                    image_id=image_ref, reason=_('Bad image format'))
            IMAGE_API.download(context, image_ref, dest_path=image_file)

            # It is possible that LXD already have the same image
            # but NOT aliased as result of previous publish/export operation
            # (snapshot from openstack).
            # In that case attempt to add it again
            # (implicitly via instance launch from affected image) will produce
            # LXD error - "Image with same fingerprint already exists".
            # Error does not have unique identifier to handle it we calculate
            # fingerprint of image as LXD do it and check if LXD already have
            # image with such fingerprint.
            # If any we will add alias to this image and will not re-import it
            def add_alias():

                def lxdimage_fingerprint():
                    def sha256_file():
                        sha256 = hashlib.sha256()
                        with closing(open(image_file, 'rb')) as f:
                            for block in iter(lambda: f.read(65536), b''):
                                sha256.update(block)
                        return sha256.hexdigest()

                    return sha256_file()

                fingerprint = lxdimage_fingerprint()
                if client.images.exists(fingerprint):
                    LOG.info(
                        'Image with fingerprint %(fingerprint)s already exists'
                        'but not accessible by alias %(alias)s, add alias',
                        {'fingerprint': fingerprint, 'alias': image_ref})
                    lxdimage = client.images.get(fingerprint)
                    lxdimage.add_alias(image_ref, '')
                    return True

                return False

            if add_alias():
                return

            # up2date LXD publish/export operations produce images which
            # already contains /rootfs and metdata.yaml in exported file.
            # We should not pass metdata explicitly in that case as imported
            # image will be unusable bacause LXD will think that it containts
            # rootfs and will not extract embedded /rootfs properly.
            # Try to detect if image content already has metadata and not pass
            # explicit metadata in that case
            def imagefile_has_metadata(image_file):
                try:
                    with closing(tarfile.TarFile.open(
                        name=image_file, mode='r:*')) as tf:
                        try:
                            tf.getmember('metadata.yaml')
                            return True
                        except KeyError:
                            pass
                except tarfile.ReadError:
                    pass
                return False

            if imagefile_has_metadata(image_file):
                LOG.info('Image %(alias)s already has metadata, '
                         'skipping metadata injection...',
                         {'alias': image_ref})
                with open(image_file, 'rb') as image:
                    image = client.images.create(image.read(), wait=True)
            else:
                metadata = {
                    'architecture': image.get(
                        'hw_architecture',
                        obj_fields.Architecture.from_host()),
                    'creation_date': int(os.stat(image_file).st_ctime)}
                metadata_yaml = json.dumps(
                    metadata, sort_keys=True, indent=4,
                    separators=(',', ': '),
                    ensure_ascii=False).encode('utf-8') + b"\n"

                tarball = tarfile.open(manifest_file, "w:gz")
                tarinfo = tarfile.TarInfo(name='metadata.yaml')
                tarinfo.size = len(metadata_yaml)
                tarball.addfile(tarinfo, io.BytesIO(metadata_yaml))
                tarball.close()

                with open(manifest_file, 'rb') as manifest:
                    with open(image_file, 'rb') as image:
                        image = client.images.create(
                            image.read(), metadata=manifest.read(),
                            wait=True)

            image.add_alias(image_ref, '')

        finally:
            os.unlink(image_file)
            os.unlink(manifest_file)
Exemple #16
0
 def check_is_bool(image, key):
     val = image.get('deleted')
     if not isinstance(val, bool):
         self.fail('image\'s "%s" attribute wasn\'t '
                   'a bool: %r' % (key, val))
Exemple #17
0
    def notify(self, ctxt, message):
        event_type = message.get('event_type')
        if event_type in CONF.wiki_eventtype_blacklist:
            return
        if event_type not in CONF.wiki_eventtype_whitelist:
            LOG.debug("Ignoring message type %s" % event_type)
            return

        payload = message['payload']
        instance = payload['instance_id']
        instance_name = payload['display_name']

        template_param_dict = {}
        for field in self.RawTemplateFields:
            template_param_dict[field] = payload[field]

        tenant_id = payload['tenant_id']
        if (CONF.wiki_use_keystone and self._keystone_login(tenant_id, ctxt)):
            tenant_obj = self.tenant_manager[tenant_id].get(tenant_id)
            user_obj = self.user_manager[tenant_id].get(payload['user_id'])
            tenant_name = tenant_obj.name
            user_name = user_obj.name
            template_param_dict['tenant'] = tenant_name
            template_param_dict['username'] = user_name

        inst = self.conductor_api.instance_get_by_uuid(ctxt,
                                                       payload['instance_id'])

        simple_id = inst['id']
        ec2_id = 'i-%08x' % simple_id

        if CONF.wiki_instance_dns_domain:
            fqdn = "%s.%s" % (instance_name, CONF.wiki_instance_dns_domain)
            resourceName = "%s.%s" % (ec2_id, CONF.wiki_instance_dns_domain)
        else:
            fqdn = instance_name
            resourceName = ec2_id

        template_param_dict['cpu_count'] = inst['vcpus']
        template_param_dict['disk_gb_current'] = inst['ephemeral_gb']
        template_param_dict['host'] = inst['host']
        template_param_dict['reservation_id'] = inst['reservation_id']
        template_param_dict['availability_zone'] = inst['availability_zone']
        template_param_dict['original_host'] = inst['launched_on']
        template_param_dict['fqdn'] = fqdn
        template_param_dict['ec2_id'] = ec2_id
        template_param_dict['project_name'] = inst['project_id']
        template_param_dict['region'] = CONF.wiki_instance_region

        ips = []
        floating_ips = []

        try:
            nw_info = network.API().get_instance_nw_info(ctxt, inst)
            ip_objs = nw_info.fixed_ips()
            floating_ip_objs = nw_info.floating_ips()

            ips = [ip['address'] for ip in ip_objs]
            floating_ips = [ip['address'] for ip in floating_ip_objs]
        except exception.FixedIpNotFoundForInstance:
            ips = []
            floating_ips = []

        template_param_dict['private_ip'] = ','.join(ips)
        template_param_dict['public_ip'] = ','.join(floating_ips)

        sec_groups = self.conductor_api.security_group_get_by_instance(
            ctxt, inst)
        grps = [grp['name'] for grp in sec_groups]
        template_param_dict['security_group'] = ','.join(grps)

        image = self._image_service.show(ctxt, inst['image_ref'])
        image_name = image.get('name', inst['image_ref'])
        template_param_dict['image_name'] = image_name

        fields_string = ""
        for key in template_param_dict:
            fields_string += "\n|%s=%s" % (key, template_param_dict[key])

        clear_page = False
        if event_type == 'compute.instance.delete.start':
            page_string = ("\n%s\nThis instance has been deleted.\n%s\n" %
                           (begin_comment, end_comment))
            clear_page = True
        else:
            page_string = "%s\n{{InstanceStatus%s}}\n%s" % (
                begin_comment, fields_string, end_comment)

        self._wiki_login()
        pagename = "%s%s" % (CONF.wiki_page_prefix, resourceName)
        LOG.debug("wikistatus:  Writing instance info"
                  " to page http://%s/wiki/%s" % (self.host, pagename))

        page = self.site.Pages[pagename]
        try:
            pText = page.edit()
            if clear_page:
                newText = page_string
            else:
                start_replace_index = pText.find(begin_comment)
                if start_replace_index == -1:
                    # Just stick new text at the top.
                    newText = "%s\n%s" % (page_string, pText)
                else:
                    # Replace content between comment tags.
                    end_replace_index = pText.find(end_comment,
                                                   start_replace_index)
                    if end_replace_index == -1:
                        end_replace_index = (start_replace_index +
                                             len(begin_comment))
                    else:
                        end_replace_index += len(end_comment)
                    newText = "%s%s%s" % (pText[:start_replace_index],
                                          page_string,
                                          pText[end_replace_index:])
            page.save(newText, "Auto update of instance info.")
        except (mwclient.errors.InsufficientPermission,
                mwclient.errors.LoginError):
            LOG.debug("Failed to update wiki page..."
                      " trying to re-login next time.")
            self._wiki_logged_in = False
    def notify(self, ctxt, message):
        event_type = message.get('event_type')
        if event_type in FLAGS.wiki_eventtype_blacklist:
            return
        if event_type not in FLAGS.wiki_eventtype_whitelist:
            LOG.debug("Ignoring message type %s" % event_type)
            return

        payload = message['payload']
        instance = payload['instance_id']
        instance_name = payload['display_name']

        pagename = "%s%s" % (FLAGS.wiki_page_prefix, instance_name)
        LOG.debug("wikistatus:  Writing instance info"
                  " to page http://%s/wiki/%s" %
                  (self.host, pagename))

        if event_type == 'compute.instance.delete.end':
            page_string = _("This instance has been deleted.")
        else:
            template_param_dict = {}
            for field in self.RawTemplateFields:
                template_param_dict[field] = payload[field]

            tenant_id = payload['tenant_id']
            if (FLAGS.wiki_use_keystone and
                self._keystone_login(tenant_id, ctxt)):
                tenant_obj = self.tenant_manager[tenant_id].get(tenant_id)
                user_obj = self.user_manager[tenant_id].get(payload['user_id'])
                tenant_name = tenant_obj.name
                user_name = user_obj.name
                template_param_dict['tenant'] = tenant_name
                template_param_dict['username'] = user_name

            inst = db.instance_get_by_uuid(ctxt, payload['instance_id'])

            simple_id = inst.id
            template_param_dict['cpu_count'] = inst.vcpus
            template_param_dict['disk_gb_current'] = inst.ephemeral_gb
            template_param_dict['host'] = inst.host
            template_param_dict['reservation_id'] = inst.reservation_id
            template_param_dict['availability_zone'] = inst.availability_zone
            template_param_dict['original_host'] = inst.launched_on
            template_param_dict['public_ip'] = inst.access_ip_v4

            try:
                fixed_ips = db.fixed_ip_get_by_instance(ctxt, payload['instance_id'])
            except exception.FixedIpNotFoundForInstance:
                fixed_ips = []
            ips = [ip.address for ip in fixed_ips]
            template_param_dict['private_ip'] = ','.join(ips)

            sec_groups = db.security_group_get_by_instance(ctxt, simple_id)
            grps = [grp.name for grp in sec_groups]
            template_param_dict['security_group'] = ','.join(grps)

            image = self._image_service.show(ctxt, inst.image_ref)
            image_name = image.get('name', inst.image_ref)
            template_param_dict['image_name'] = image_name

            fields_string = ""
            for key in template_param_dict:
                fields_string += "\n|%s=%s" % (key, template_param_dict[key])

            page_string = "{{InstanceStatus%s}}" % fields_string

        self._wiki_login()
        page = self.site.Pages[pagename]
        try:
            page.edit()
            page.save(page_string, "Auto update of instance info.")
        except (mwclient.errors.InsufficientPermission,
                mwclient.errors.LoginError):
            LOG.debug("Failed to update wiki page..."
                      " trying to re-login next time.")
            self._wiki_logged_in = False