示例#1
0
 def __init__(self, scheme):
     self._metadata_iso_catalog = CONF.vcloud.metadata_iso_catalog
     self._session = VCloudAPISession(
         host_ip=CONF.vcloud.vcloud_host_ip,
         host_port=CONF.vcloud.vcloud_host_port,
         server_username=CONF.vcloud.vcloud_host_username,
         server_password=CONF.vcloud.vcloud_host_password,
         org=CONF.vcloud.vcloud_org,
         vdc=CONF.vcloud.vcloud_vdc,
         version=CONF.vcloud.vcloud_version,
         service=CONF.vcloud.vcloud_service,
         verify=CONF.vcloud.vcloud_verify,
         service_type=CONF.vcloud.vcloud_service_type,
         retry_count=CONF.vcloud.vcloud_api_retry_count,
         create_session=True,
         scheme=scheme)
示例#2
0
class VCloudClient(object):

    def __init__(self, scheme):
        self._metadata_iso_catalog = CONF.vcloud.metadata_iso_catalog
        self._session = VCloudAPISession(
            host_ip=CONF.vcloud.vcloud_host_ip,
            host_port=CONF.vcloud.vcloud_host_port,
            server_username=CONF.vcloud.vcloud_host_username,
            server_password=CONF.vcloud.vcloud_host_password,
            org=CONF.vcloud.vcloud_org,
            vdc=CONF.vcloud.vcloud_vdc,
            version=CONF.vcloud.vcloud_version,
            service=CONF.vcloud.vcloud_service,
            verify=CONF.vcloud.vcloud_verify,
            service_type=CONF.vcloud.vcloud_service_type,
            retry_count=CONF.vcloud.vcloud_api_retry_count,
            create_session=True,
            scheme=scheme)

    @property
    def org(self): 
        return self._session.org

    @property
    def username(self): 
        return self._session.username

    @property
    def password(self): 
        return self._session.password

    @property
    def vdc(self): 
        return self._session.vdc

    @property
    def host_ip(self): 
        return self._session.host_ip

    def _get_vcloud_vdc(self):
        return self._invoke_api("get_vdc",
                                self._session.vdc)

    def _get_vcloud_vapp(self, vapp_name):
        the_vapp = self._invoke_api("get_vapp",
                                    self._get_vcloud_vdc(),
                                    vapp_name)

        if not the_vapp:
            #raise exception.NovaException("can't find the vapp")
            LOG.info("can't find the vapp %s" % vapp_name)
            return None
        else:
            return the_vapp

    def _invoke_api(self, method_name, *args, **kwargs):
        res = self._session.invoke_api(self._session.vca,
                                       method_name,
                                       *args, **kwargs)
        LOG.info("_invoke_api (%s, %s, %s) = %s" %
                 (method_name, args, kwargs, res))
        return res

    def _invoke_vapp_api(self, the_vapp, method_name, *args, **kwargs):
        res = self._session.invoke_api(the_vapp, method_name, *args, **kwargs)
        LOG.info("_invoke_vapp_api (%s, %s, %s) = %s" %
                 (method_name, args, kwargs, res))
        return res

    def get_disk_ref(self, disk_name):
        disk_refs = self._invoke_api('get_diskRefs',
                                     self._get_vcloud_vdc())
        link = filter(lambda link: link.get_name() == disk_name, disk_refs)
        if len(link) == 1:
            return True, link[0]
        elif len(link) == 0:
            return False, 'disk not found'
        elif len(link) > 1:
            return False, 'more than one disks found with that name.'

    def get_vcloud_vapp_status(self, vapp_name):
        return self._get_vcloud_vapp(vapp_name).me.status

    def power_off_vapp(self, vapp_name):
        @RetryDecorator(max_retry_count=10,
                        exceptions=exception.NovaException)
        def _power_off(vapp_name):
            expected_vapp_status = 8
            the_vapp = self._get_vcloud_vapp(vapp_name)
            vapp_status = self._get_status_first_vm(the_vapp)
            if vapp_status == expected_vapp_status:
                return the_vapp

            task_stop = self._invoke_vapp_api(the_vapp, "undeploy")
            if not task_stop:
                raise exception.NovaException(
                    "power off vapp failed, task")
            self._session.wait_for_task(task_stop)

            retry_times = 60
            while vapp_status != expected_vapp_status and retry_times > 0:
                time.sleep(3)
                the_vapp = self._get_vcloud_vapp(vapp_name)
                vapp_status = self._get_status_first_vm(the_vapp)
                LOG.debug('During power off vapp_name: %s, %s' % (vapp_name, vapp_status))
                retry_times -= 1
            return the_vapp

        return _power_off(vapp_name)

    def _get_status_first_vm(self, the_vapp):
        children = the_vapp.me.get_Children()
        if children:
            vms = children.get_Vm()
            for vm in vms:
                return vm.get_status()
        return None

    def power_on_vapp(self, vapp_name):
        @RetryDecorator(max_retry_count=10,
                        exceptions=exception.NovaException)
        def _power_on(vapp_name):
            the_vapp = self._get_vcloud_vapp(vapp_name)

            vapp_status = self._get_status_first_vm(the_vapp)
            expected_vapp_status = 4
            if vapp_status == expected_vapp_status:
                return the_vapp

            task = self._invoke_vapp_api(the_vapp, "poweron")
            if not task:
                raise exception.NovaException("power on vapp failed, task")
            self._session.wait_for_task(task)

            retry_times = 60
            while vapp_status != expected_vapp_status and retry_times > 0:
                time.sleep(3)
                the_vapp = self._get_vcloud_vapp(vapp_name)
                vapp_status = self._get_status_first_vm(the_vapp)
                LOG.debug('During power on vapp_name: %s, %s' %
                        (vapp_name, vapp_status))
                retry_times -= 1
            return the_vapp

        return _power_on(vapp_name)

    def delete_vapp(self, vapp_name):
        the_vapp = self._get_vcloud_vapp(vapp_name)
        task = self._invoke_vapp_api(the_vapp, "delete")
        if not task:
            raise exception.NovaException(
                "delete vapp failed, task: %s" % task)
        self._session.wait_for_task(task)

    def reboot_vapp(self, vapp_name):
        the_vapp = self._get_vcloud_vapp(vapp_name)
        task = self._invoke_vapp_api(the_vapp, "reboot")
        if not task:
            raise exception.NovaException(
                "reboot vapp failed, task: %s" % task)
        self._session.wait_for_task(task)

    def query_vmdk_url(self, vapp_name):
        # 0. shut down the app first
        try:
            the_vapp = self.power_off_vapp(vapp_name)
        except:
            LOG.error('power off failed')

        # 1.enable download.
        task = self._invoke_vapp_api(the_vapp, 'enableDownload')
        if not task:
            raise exception.NovaException(
                "enable vmdk file download failed, task:")
        self._session.wait_for_task(task)

        # 2.get vapp info and ovf descriptor
        the_vapp = self._get_vcloud_vapp(vapp_name)

        ovf = self._invoke_vapp_api(the_vapp, 'get_ovf_descriptor')

        # 3.get referenced file url
        referenced_file_url = self._invoke_vapp_api(the_vapp,
                                                    'get_referenced_file_url',
                                                    ovf)
        if not referenced_file_url:
            raise exception.NovaException(
                "get vmdk file url failed")
        return referenced_file_url

    def attach_disk_to_vm(self, vapp_name, disk_ref):
        @RetryDecorator(max_retry_count=16,
                        exceptions=exception.NovaException)
        def _attach_disk(vapp_name, disk_ref):
            the_vapp = self._get_vcloud_vapp(vapp_name)
            task = the_vapp.attach_disk_to_vm(disk_ref)
            if not task:
                raise exception.NovaException(
                    "Unable to attach disk to vm %s" % vapp_name)
            else:
                self._session.wait_for_task(task)
                return True

        return _attach_disk(vapp_name, disk_ref)

    def detach_disk_from_vm(self, vapp_name, disk_ref):
        @RetryDecorator(max_retry_count=16,
                        exceptions=exception.NovaException)
        def _detach_disk(vapp_name, disk_ref):
            the_vapp = self._get_vcloud_vapp(vapp_name)
            task = the_vapp.detach_disk_from_vm(disk_ref)
            if not task:
                raise exception.NovaException(
                    "Unable to detach disk from vm %s" % vapp_name)
            else:
                self._session.wait_for_task(task)
                return True

        return _detach_disk(vapp_name, disk_ref)
        
    def modify_vm_cpu(self, vapp_name, cpus):
        the_vapp = self._get_vcloud_vapp(vapp_name)
        task = the_vapp.modify_vm_cpu(vapp_name, cpus)
        if not task:
            raise exception.NovaException(
                "Unable to modify vm %s cpu" % vapp_name)
        else:
            self._session.wait_for_task(task)
            return True

    def insert_media(self, vapp_name, iso_file):
        the_vapp = self._get_vcloud_vapp(vapp_name)
        task = the_vapp.vm_media(iso_file, 'insert')
        if not task:
            raise exception.NovaException(
                "Unable to insert media vm %s" % vapp_name)
        else:
            self._session.wait_for_task(task)
            return True

    def upload_vm(self, ovf_name, vapp_name, api_net, tun_net):
        cmd = ('ovftool --net:"vmnetwork-0=%s"'
               ' --net:"vmnetwork-1=%s"'
               ' %s "vcloud://%s:%s@%s?org=%s&vdc=%s&vapp=%s"' %
               (api_net,
                tun_net,
                ovf_name,
                self.username,
                self.password,
                self.host_ip,
                self.org,
                self.vdc,
                vapp_name))
        LOG.debug("begin run create vapp command '%s'." % cmd)
        cmd_result = subprocess.call(cmd, shell=True)
        LOG.debug("end run create vapp command '%s'." % cmd)
        if cmd_result != 0:
            raise exception.NovaException(
                "Unable to upload vm %s" % vapp_name)

    def _upload_metadata_iso(self, iso_file, media_name, overwrite=False):
        overw = ''
        if overwrite:
            overw = '--overwrite'
        cmd = ('ovftool %s --sourceType="ISO" '
               ' --vCloudTemplate="false"'
               ' "%s" "vcloud://%s:%s@%s?org=%s&vdc=%s&media=%s'
               '&catalog=%s"' %
               (overw,
                iso_file,
                self.username,
                self.password,
                self.host_ip,
                self.org,
                self.vdc,
                media_name,
                self._metadata_iso_catalog))
        LOG.debug("begin run upload iso command '%s'." % cmd)
        cmd_result = subprocess.call(cmd, shell=True)
        LOG.debug("end run upload iso command '%s'." % cmd)
        return cmd_result
        
    def upload_metadata_iso(self, iso_file, vapp_name):
        media_name = "metadata_%s.iso" % vapp_name
        try:
            cmd_result = self._upload_metadata_iso(iso_file, media_name)
        except Exception as e:
            cmd_result = 1
            LOG.error('upload meta-data failed without overwrite %s.' % (e))
        if cmd_result != 0:
            cmd_result = self._upload_metadata_iso(iso_file, media_name, True)
        if cmd_result != 0:
            raise exception.NovaException(
                "Unable to upload meta-data iso file %s" % vapp_name)
        return self._invoke_api("get_media",
                                            self._metadata_iso_catalog,
                                            media_name)        
         

    def delete_metadata_iso(self, vapp_name):
        media_name = "metadata_%s.iso" % vapp_name
        # not work for pyvcloud10 but for pyvcloud14
        result = self._invoke_api("delete_catalog_item",
                                self._metadata_iso_catalog,
                                media_name)
        if not result:
            raise exception.NovaException(
                "delete metadata iso failed vapp_name:%s" % vapp_name)

    def get_network_configs(self, network_names):
        return self._session.invoke_api(self._session.vca, "get_network_configs", self._session._vdc, network_names)

    def get_network_connections(self, vapp, network_names):
        return self._session.invoke_api(vapp, "get_network_connections", network_names)

    def update_vms_connections(self, vapp, network_connections):
        result, task = self._session.invoke_api(vapp, "update_vms_connections", network_connections)

        # check the task is success or not
        if not result:
            raise exceptions.VCloudDriverException(
                "Update_vms_connections error, task:" +
                task)

        self._session.wait_for_task(task)

    def modify_vm_cpu(self, vapp, cpus):
        result, task = self._session.invoke_api(vapp, "modify_vm_cpu", cpus)

        # check the task is success or not
        if not result:
            raise exceptions.VCloudDriverException(
                "Modify_vm_cpu error, task:" +
                task)

        self._session.wait_for_task(task)

    def modify_vm_memory(self, vapp, new_size):
        result, task = self._session.invoke_api(vapp, "modify_vm_memory", new_size)

        # check the task is success or not
        if not result:
            raise exceptions.VCloudDriverException(
                "Modify_vm_memory error, task:" +
                task)

        self._session.wait_for_task(task)


    def create_vapp(self, vapp_name, template_name, network_configs, root_gb=None):
        result, task = self._session.invoke_api(self._session.vca,
                                                "create_vapp",
                                                self._session._vdc, vapp_name,
                                                template_name, network_configs=network_configs, root_gb=root_gb)

        # check the task is success or not
        if not result:
            raise exceptions.VCloudDriverException(
                "Create_vapp error, task:" +
                task)
        self._session.wait_for_task(task)
        the_vdc = self._session.invoke_api(self._session.vca, "get_vdc", self._session._vdc)

        return self._session.invoke_api(self._session.vca, "get_vapp", the_vdc, vapp_name)