Example #1
0
 def storagepools_create(self, params):
     try:
         name = params['name']
         pool = MockStoragePool(name)
         pool.info['type'] = params['type']
         if params['type'] == 'scsi':
             pool.info['path'] = '/dev/disk/by-path'
             pool.info['source'] = params['source']
             if not pool.info['source'].get('adapter_name'):
                 raise MissingParameter('KCHPOOL0004E', {
                     'item': 'adapter_name',
                     'name': name
                 })
             for vol in [
                     'unit:0:0:1', 'unit:0:0:2', 'unit:0:0:3', 'unit:0:0:4'
             ]:
                 mockvol = MockStorageVolume(name, vol,
                                             dict([('type', 'lun')]))
                 pool._volumes[vol] = mockvol
         else:
             pool.info['path'] = params['path']
         if params['type'] in ['dir', 'scsi']:
             pool.info['autostart'] = True
         else:
             pool.info['autostart'] = False
     except KeyError, item:
         raise MissingParameter("KCHPOOL0004E", {
             'item': str(item),
             'name': name
         })
Example #2
0
    def addRepo(self, params):
        """
        Add a new APT repository based on <params>
        """
        # To create a APT repository the dist is a required parameter
        # (in addition to baseurl, verified on controller through API.json)
        config = params.get('config', None)
        if config is None:
            raise MissingParameter("KCHREPOS0019E")

        if 'dist' not in config.keys():
            raise MissingParameter("KCHREPOS0019E")

        uri = params['baseurl']
        dist = config['dist']
        comps = config.get('comps', [])

        validate_repo_url(uri)

        kimchiLock.acquire()
        try:
            repos = self._get_repos()
            source_entry = repos.add('deb',
                                     uri,
                                     dist,
                                     comps,
                                     file=self.filename)
            with self.pkg_lock():
                repos.save()
        except Exception as e:
            kimchiLock.release()
            raise OperationFailed("KCHREPOS0026E", {'err': e.message})
        kimchiLock.release()
        return self._get_repo_id(source_entry)
Example #3
0
    def networks_create(self, params):
        name = params['name']
        if name in self.networks_get_list():
            raise InvalidOperation("KCHNET0001E", {'name': name})

        network = MockNetwork(name)
        connection = params['connection']
        network.info['connection'] = connection
        if connection == "bridge":
            try:
                interface = params['interface']
                network.info['interface'] = interface
            except KeyError:
                raise MissingParameter("KCHNET0004E", {'name': name})

        subnet = params.get('subnet', '')
        if subnet:
            network.info['subnet'] = subnet
            try:
                net = ipaddr.IPNetwork(subnet)
            except ValueError:
                msg_args = {'subnet': subnet, 'network': name}
                raise InvalidParameter("KCHNET0003E", msg_args)

            network.info['dhcp'] = {
                'start': str(net.network + net.numhosts / 2),
                'stop': str(net.network + net.numhosts - 2)
            }

        self._mock_networks[name] = network
        return name
Example #4
0
    def create(self, params):
        task_id = None
        conn = self.conn.get()
        try:
            name = params['name']
            if name == ISO_POOL_NAME:
                raise InvalidOperation("KCHPOOL0031E")

            if params['type'] == 'kimchi-iso':
                task_id = self._do_deep_scan(params)

            if params['type'] == 'scsi':
                adapter_name = params['source']['adapter_name']
                extra_params = self.device.lookup(adapter_name)
                # Adds name, adapter_type, wwpn and wwnn to source information
                params['source'].update(extra_params)
                params['fc_host_support'] = self.caps.fc_host_support

            poolDef = StoragePoolDef.create(params)
            poolDef.prepare(conn)
            xml = poolDef.xml.encode("utf-8")
        except KeyError, item:
            raise MissingParameter("KCHPOOL0004E", {
                'item': str(item),
                'name': name
            })
Example #5
0
    def addRepo(self, params):
        """
        Add a given repository to YumBase
        """
        # At least one base url, or one mirror, must be given.
        baseurl = params.get('baseurl', '')

        config = params.get('config', {})
        mirrorlist = config.get('mirrorlist', '')
        metalink = config.get('metalink', '')
        if not baseurl and not mirrorlist and not metalink:
            raise MissingParameter("KCHREPOS0013E")

        if baseurl:
            validate_repo_url(baseurl)

        if mirrorlist:
            validate_repo_url(mirrorlist)

        if metalink:
            validate_repo_url(metalink)

        if mirrorlist and metalink:
            raise InvalidOperation('KCHREPOS0030E')

        repo_id = params.get('repo_id', None)
        if repo_id is None:
            repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))

        repos = self._get_repos('KCHREPOS0026E')
        if repo_id in repos.keys():
            raise InvalidOperation("KCHREPOS0022E", {'repo_id': repo_id})

        repo_name = config.get('repo_name', repo_id)
        repo = {
            'baseurl': baseurl,
            'mirrorlist': mirrorlist,
            'name': repo_name,
            'gpgcheck': 1,
            'gpgkey': [],
            'enabled': 1,
            'metalink': metalink
        }

        # write a repo file in the system with repo{} information.
        parser = ConfigParser()
        parser.add_section(repo_id)

        for key, value in repo.iteritems():
            if value:
                parser.set(repo_id, key, value)

        repofile = os.path.join(self._confdir, repo_id + '.repo')
        try:
            with open(repofile, 'w') as fd:
                parser.write(fd)
        except:
            raise OperationFailed("KCHREPOS0018E", {'repo_file': repofile})

        return repo_id
Example #6
0
    def _create_volume_with_capacity(self, cb, params):
        pool_name = params.pop('pool')
        vol_xml = """
        <volume>
          <name>%(name)s</name>
          <allocation unit='bytes'>%(allocation)s</allocation>
          <capacity unit='bytes'>%(capacity)s</capacity>
          <source>
          </source>
          <target>
            <format type='%(format)s'/>
          </target>
        </volume>
        """
        params.setdefault('allocation', 0)
        params.setdefault('format', 'qcow2')

        name = params['name']
        try:
            pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            xml = vol_xml % params
        except KeyError, item:
            raise MissingParameter("KCHVOL0004E", {
                'item': str(item),
                'volume': name
            })
Example #7
0
    def _get_os_info(self, args, scan):
        distro = version = 'unknown'

        # Identify the cdrom if present
        iso = args.get('cdrom', '')
        if len(iso) > 0:
            if not iso.startswith('/'):
                self.info.update({'iso_stream': True})

            if scan:
                distro, version = self.get_iso_info(iso)

            return distro, version

        # CDROM is not presented: check for base image
        base_imgs = []
        for d in args.get('disks', []):
            if 'base' in d.keys():
                base_imgs.append(d)
                if scan:
                    distro, version = imageinfo.probe_image(d['base'])

                if 'size' not in d.keys():
                    d_info = imageinfo.probe_img_info(d['base'])
                    d['size'] = d_info['virtual-size']

        if len(base_imgs) == 0:
            raise MissingParameter("KCHTMPL0016E")

        return distro, version
Example #8
0
 def login(self, *args):
     params = parse_request()
     try:
         username = params['username']
         password = params['password']
     except KeyError, item:
         e = MissingParameter('KCHAUTH0003E', {'item': str(item)})
         raise cherrypy.HTTPError(400, e.message)
Example #9
0
    def updateRepo(self, repo_id, repo={}):
        """
        Update a given repository in repositories.Repositories() format
        """
        if len(repo) == 0:
            raise MissingParameter("KCHREPOS0013E")

        self.removeRepo(repo_id)
        self.addRepo(repo)
Example #10
0
    def vms_create(self, params):
        t_name = template_name_from_uri(params['template'])
        name = get_vm_name(params.get('name'), t_name, self._mock_vms.keys())
        if name in self._mock_vms:
            raise InvalidOperation("KCHVM0001E", {'name': name})

        vm_uuid = str(uuid.uuid4())
        vm_overrides = dict()
        pool_uri = params.get('storagepool')
        if pool_uri:
            vm_overrides['storagepool'] = pool_uri

        t = self._get_template(t_name, vm_overrides)
        t.validate()

        t_info = copy.deepcopy(t.info)
        graphics = params.get('graphics')
        if graphics:
                t_info.update({'graphics': graphics})

        vm = MockVM(vm_uuid, name, t_info)
        icon = t_info.get('icon')
        if icon:
            vm.info['icon'] = icon

        pool = t._storage_validate()
        if pool.info['type'] == 'scsi':
            vm.disk_paths = []
            if not params.get('volumes'):
                raise MissingParameter('KCHVM0017E')
            for vol in params['volumes']:
                vm.disk_paths.append({'pool': pool.name,
                                      'volume': vol})

        else:
            vm.disk_paths = t.fork_vm_storage(vm_uuid)

        index = 0
        for disk in vm.disk_paths:
            storagepath = self._mock_storagepools[disk['pool']].info['path']
            fullpath = os.path.join(storagepath, disk['volume'])
            dev_name = "hd" + string.ascii_lowercase[index]
            params = {'dev': dev_name, 'path': fullpath, 'type': 'disk'}
            vm.storagedevices[dev_name] = MockVMStorageDevice(params)
            index += 1

        cdrom = "hd" + string.ascii_lowercase[index + 1]
        cdrom_params = {'dev': cdrom, 'path': t_info['cdrom'], 'type': 'cdrom'}
        vm.storagedevices[cdrom] = MockVMStorageDevice(cdrom_params)

        self._mock_vms[name] = vm
        return name
Example #11
0
    def updateRepo(self, repo_id, params):
        """
        Update a given repository in repositories.Repositories() format
        """
        kimchiLock.acquire()
        repos = self._get_repos('KCHREPOS0011E')
        kimchiLock.release()
        if repo_id not in repos.repos.keys():
            raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})

        entry = repos.getRepo(repo_id)

        baseurl = params.get('baseurl', None)
        config = params.get('config', {})
        mirrorlist = config.get('mirrorlist', None)
        metalink = config.get('metalink', None)

        if baseurl is not None and len(baseurl.strip()) == 0:
            baseurl = None

        if mirrorlist is not None and len(mirrorlist.strip()) == 0:
            mirrorlist = None

        if metalink is not None and len(metalink.strip()) == 0:
            metalink = None

        if baseurl is None and mirrorlist is None and metalink is None:
            raise MissingParameter("KCHREPOS0013E")

        if baseurl is not None:
            validate_repo_url(baseurl)
            entry.baseurl = baseurl

        if mirrorlist is not None:
            validate_repo_url(mirrorlist)
            entry.mirrorlist = mirrorlist

        if metalink is not None:
            validate_repo_url(metalink)
            entry.metalink = metalink

        if mirrorlist and metalink:
            raise InvalidOperation('KCHREPOS0030E')

        entry.id = params.get('repo_id', repo_id)
        entry.name = config.get('repo_name', entry.name)
        entry.gpgcheck = config.get('gpgcheck', entry.gpgcheck)
        entry.gpgkey = config.get('gpgkey', entry.gpgkey)
        kimchiLock.acquire()
        self._conf.writeRawRepoFile(entry)
        kimchiLock.release()
        return repo_id
Example #12
0
    def create(self, vm, params):
        conn = self.conn.get()
        networks = conn.listNetworks() + conn.listDefinedNetworks()
        networks = map(lambda x: x.decode('utf-8'), networks)

        if params['type'] == 'network':
            network = params.get("network")

            if network is None:
                raise MissingParameter('KCHVMIF0007E')

            if network not in networks:
                raise InvalidParameter('KCHVMIF0002E', {
                    'name': vm,
                    'network': network
                })

        macs = (iface.mac.get('address')
                for iface in self.get_vmifaces(vm, self.conn))

        # user defined customized mac address
        if 'mac' in params and params['mac']:
            # make sure it is unique
            if params['mac'] in macs:
                raise InvalidParameter('KCHVMIF0009E', {
                    'name': vm,
                    'mac': params['mac']
                })

        # otherwise choose a random mac address
        else:
            while True:
                params['mac'] = VMIfacesModel.random_mac()
                if params['mac'] not in macs:
                    break

        dom = VMModel.get_vm(vm, self.conn)

        os_data = VMModel.vm_get_os_metadata(dom, self.caps.metadata_support)
        os_version, os_distro = os_data
        xml = get_iface_xml(params, conn.getInfo()[0], os_distro, os_version)

        flags = 0
        if dom.isPersistent():
            flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
        if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
            flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE

        dom.attachDeviceFlags(xml, flags)

        return params['mac']
Example #13
0
    def storagevolumes_create(self, pool_name, params):
        pool = self._get_storagepool(pool_name)
        if pool.info['state'] == 'inactive':
            raise InvalidOperation("KCHVOL0003E",
                                   {'pool': pool_name,
                                    'volume': params['name']})

        try:
            name = params['name']
            volume = MockStorageVolume(pool, name, params)
            volume.info['type'] = params['type']
            volume.info['format'] = params['format']
            volume.info['path'] = os.path.join(
                pool.info['path'], name)
        except KeyError, item:
            raise MissingParameter("KCHVOL0004E",
                                   {'item': str(item), 'volume': name})
Example #14
0
    def create(self, params):
        task_id = None
        conn = self.conn.get()
        try:
            name = params['name']
            if name == ISO_POOL_NAME:
                raise InvalidOperation("KCHPOOL0031E")

            # The user may want to create a logical pool with the same name
            # used before but a volume group will already exist with this name
            # So check the volume group does not exist to create the pool
            if params['type'] == 'logical':
                vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')]
                output, error, returncode = run_command(vgdisplay_cmd)
                # From vgdisplay error codes:
                # 1  error reading VGDA
                # 2  volume group doesn't exist
                # 3  not all physical volumes of volume group online
                # 4  volume group not found
                # 5  no volume groups found at all
                # 6  error reading VGDA from lvmtab
                if returncode not in [2, 4, 5]:
                    raise InvalidOperation("KCHPOOL0036E", {'name': name})

            if params['type'] == 'kimchi-iso':
                task_id = self._do_deep_scan(params)

            if params['type'] == 'scsi':
                adapter_name = params['source']['adapter_name']
                extra_params = self.device.lookup(adapter_name)
                # Adds name, adapter_type, wwpn and wwnn to source information
                params['source'].update(extra_params)
                params['fc_host_support'] = self.caps.fc_host_support

            poolDef = StoragePoolDef.create(params)
            poolDef.prepare(conn)
            xml = poolDef.xml.encode("utf-8")
        except KeyError, item:
            raise MissingParameter("KCHPOOL0004E", {
                'item': str(item),
                'name': name
            })
Example #15
0
    def _set_network_bridge(self, params):
        try:
            iface = params['interface']
            if iface in self.get_all_networks_interfaces():
                msg_args = {'iface': iface, 'network': params['name']}
                raise InvalidParameter("KCHNET0006E", msg_args)
        except KeyError:
            raise MissingParameter("KCHNET0004E", {'name': params['name']})

        self._ensure_iface_up(iface)
        if netinfo.is_bridge(iface):
            if 'vlan_id' in params:
                raise InvalidParameter('KCHNET0019E', {'name': iface})
            params['bridge'] = iface
        elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
            if params.get('vlan_id') is None:
                params['forward']['dev'] = iface
            else:
                params['bridge'] = \
                    self._create_vlan_tagged_bridge(str(iface),
                                                    str(params['vlan_id']))
        else:
            raise InvalidParameter("KCHNET0007E")
Example #16
0
    def update(self, vm, mac, params):
        dom = VMModel.get_vm(vm, self.conn)
        iface = self._get_vmiface(vm, mac)

        if iface is None:
            raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})

        # cannot change mac address in a running system
        if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
            raise InvalidOperation('KCHVMIF0011E')

        # mac address is a required parameter
        if 'mac' not in params:
            raise MissingParameter('KCHVMIF0008E')

        # new mac address must be unique
        if self._get_vmiface(vm, params['mac']) is not None:
            raise InvalidParameter('KCHVMIF0009E', {
                'name': vm,
                'mac': params['mac']
            })

        flags = 0
        if dom.isPersistent():
            flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG

        # remove the current nic
        xml = etree.tostring(iface)
        dom.detachDeviceFlags(xml, flags=flags)

        # add the nic with the desired mac address
        iface.mac.attrib['address'] = params['mac']
        xml = etree.tostring(iface)
        dom.attachDeviceFlags(xml, flags=flags)

        return [vm, params['mac']]
Example #17
0
    def create(self, params):
        conn = self.conn.get()
        t_name = template_name_from_uri(params['template'])
        vm_uuid = str(uuid.uuid4())
        vm_list = self.get_list()
        name = get_vm_name(params.get('name'), t_name, vm_list)
        # incoming text, from js json, is unicode, do not need decode
        if name in vm_list:
            raise InvalidOperation("KCHVM0001E", {'name': name})

        vm_overrides = dict()
        pool_uri = params.get('storagepool')
        if pool_uri:
            vm_overrides['storagepool'] = pool_uri
            vm_overrides['fc_host_support'] = self.caps.fc_host_support
        t = TemplateModel.get_template(t_name, self.objstore, self.conn,
                                       vm_overrides)

        if not self.caps.qemu_stream and t.info.get('iso_stream', False):
            raise InvalidOperation("KCHVM0005E")

        t.validate()

        # If storagepool is SCSI, volumes will be LUNs and must be passed by
        # the user from UI or manually.
        vol_list = []
        if t._get_storage_type() in READONLY_POOL_TYPE:
            if not params.get('volumes'):
                raise MissingParameter('KCHVM0017E')
            else:
                # Get system path of the LUNs
                pool = t.info['storagepool'].split('/')[-1]
                for vol in params.get('volumes'):
                    path = self._get_volume_path(pool, vol)
                    vol_list.append((vol, path))
        else:
            vol_list = t.fork_vm_storage(vm_uuid)

        # Store the icon for displaying later
        icon = t.info.get('icon')
        if icon:
            with self.objstore as session:
                session.store('vm', vm_uuid, {'icon': icon})

        libvirt_stream = False
        if len(self.caps.libvirt_stream_protocols) == 0:
            libvirt_stream = True

        graphics = params.get('graphics')
        xml = t.to_vm_xml(name, vm_uuid,
                          libvirt_stream=libvirt_stream,
                          qemu_stream_dns=self.caps.qemu_stream_dns,
                          graphics=graphics,
                          volumes=vol_list)

        try:
            conn.defineXML(xml.encode('utf-8'))
        except libvirt.libvirtError as e:
            if t._get_storage_type() not in READONLY_POOL_TYPE:
                for v in vol_list:
                    vol = conn.storageVolLookupByPath(v['path'])
                    vol.delete(0)
            raise OperationFailed("KCHVM0007E", {'name': name,
                                                 'err': e.get_error_message()})

        return name