Exemplo n.º 1
0
    def initialize(self):
        """
        Initialize this prefix, this includes creating the destination path,
        and creating the uuid for the prefix, for any other actions see
        :func:`Prefix.virt_conf`

        Will safely roll back if any of those steps fail

        Returns:
            None

        Raises:
            RuntimeError: If it fails to create the prefix dir
        """
        prefix = self.paths.prefix
        os.environ['LAGO_PREFIX_PATH'] = prefix
        os.environ['LAGO_WORKDIR_PATH'] = os.path.dirname(prefix)

        with utils.RollbackContext() as rollback:
            with LogTask('Create prefix dirs'):
                try:
                    os.mkdir(prefix)
                except OSError as error:
                    raise RuntimeError(
                        'Could not create prefix at %s:\n%s' % (prefix, error)
                    )
            rollback.prependDefer(shutil.rmtree, prefix)

            with open(self.paths.uuid(), 'w') as f, \
                    LogTask('Generate prefix uuid'):
                f.write(uuid.uuid1().hex)

            with LogTask('Create ssh keys'):
                self._create_ssh_keys()

            with LogTask('Tag prefix as initialized'):
                with open(self.paths.prefix_lagofile(), 'w') as fd:
                    fd.write('')

            rollback.clear()
Exemplo n.º 2
0
    def virt_conf(
        self,
        conf,
        template_repo=None,
        template_store=None,
    ):
        with utils.RollbackContext() as rollback:
            if not os.path.exists(self.paths.images()):
                os.mkdir(self.paths.images())
                rollback.prependDefer(os.unlink, self.paths.images())

            if not os.path.exists(self.paths.virt()):
                os.mkdir(self.paths.virt())
                rollback.prependDefer(os.unlink, self.paths.virt())

            self._config_net_topology(conf)

            for name, spec in conf['domains'].items():
                new_disks = []
                spec['name'] = name
                for disk in spec['disks']:
                    path, metadata = self._create_disk(
                        name,
                        disk,
                        template_repo,
                        template_store,
                    )
                    new_disks.append(
                        {
                            'path': path,
                            'dev': disk['dev'],
                            'format': disk['format'],
                            'metadata': metadata,
                        }, )
                conf['domains'][name]['disks'] = new_disks

            env = virt.VirtEnv(self, conf['domains'], conf['nets'])
            env.save()
            env.bootstrap()
            rollback.clear()
Exemplo n.º 3
0
    def test_vm_lifecycle(self):
        inst = kimchi.model.Model(objstore_loc=self.tmp_store)

        with utils.RollbackContext() as rollback:
            params = {'name': 'test', 'disks': []}
            inst.templates_create(params)
            rollback.prependDefer(inst.template_delete, 'test')

            params = {'name': 'kimchi-vm', 'template': '/templates/test'}
            inst.vms_create(params)
            rollback.prependDefer(inst.vm_delete, 'kimchi-vm')

            vms = inst.vms_get_list()
            self.assertTrue('kimchi-vm' in vms)

            inst.vm_start('kimchi-vm')
            rollback.prependDefer(inst.vm_stop, 'kimchi-vm')

            info = inst.vm_lookup('kimchi-vm')
            self.assertEquals('running', info['state'])

        vms = inst.vms_get_list()
        self.assertFalse('kimchi-vm' in vms)
Exemplo n.º 4
0
    def _config_net_topology(self, conf):
        all_nics = [(nic, dom_name)
                    for dom_name, dom in conf['domains'].items()
                    for nic in dom['nics']]
        nics_by_net = {}
        for nic, dom in all_nics:
            nics_by_net.setdefault(nic['net'], []).append((nic, dom))

        with utils.RollbackContext() as rollback:
            for net_name, net_spec in conf.get('nets', {}).items():
                net_spec['name'] = net_name

                if net_spec.setdefault('type', 'nat') == 'bridge':
                    continue
                try:
                    subnet = net_spec['gw']
                    if subnet_lease.is_leasable_subnet(subnet):
                        raise RuntimeError(
                            '%s subnet can only be dynamically allocated' %
                            (subnet, ))
                except KeyError:
                    subnet = subnet_lease.acquire(self.paths.uuid())
                    rollback.prependDefer(subnet_lease.release, subnet)
                    net_spec['gw'] = subnet

                allocated_ips = set([1])

                # Check all allocated IPs
                for nic, dom in nics_by_net[net_name]:
                    if 'ip' not in nic:
                        continue

                    if not _ip_in_subnet(subnet, nic['ip']):
                        raise RuntimeError(
                            "%s:nic%d's IP [%s] is outside the subnet [%s]",
                            dom,
                            dom['nics'].index(nic),
                            nic['ip'],
                            subnet,
                        )

                    index = int(nic['ip'].split('.'))[3]
                    allocated_ips.add(index)
                    nic['ip'] = _create_ip(subnet, index)

                # Allocate IPs for domains without assigned IPs
                for nic, _ in nics_by_net[net_name]:
                    if 'ip' in nic:
                        continue

                    next_vacancy = set(set(range(1, 255))
                                       ^ allocated_ips).pop()
                    allocated_ips.add(next_vacancy)
                    nic['ip'] = _create_ip(subnet, next_vacancy)

                # Here we will store the domain images:
                logging.info('Creating bridge...')
                if 'mapping' not in net_spec:
                    net_spec['mapping'] = {}
                net_spec['mapping'].update(
                    {dom: nic['ip']
                     for nic, dom in nics_by_net[net_name]}, )
            rollback.clear()