Ejemplo n.º 1
0
    def create(self, lock=None):
        db.update_instance_state(self.db_entry['uuid'], 'creating')

        # Ensure we have state on disk
        if not os.path.exists(self.instance_path):
            LOG.withObj(self).debug('Creating instance storage at %s' %
                                    self.instance_path)
            os.makedirs(self.instance_path)

        # Generate a config drive
        with util.RecordedOperation('make config drive', self):
            self._make_config_drive(
                os.path.join(
                    self.instance_path,
                    self.db_entry['block_devices']['devices'][1]['path']))

        # Prepare disks
        if not self.db_entry['block_devices']['finalized']:
            modified_disks = []
            for disk in self.db_entry['block_devices']['devices']:
                if disk.get('base'):
                    img = images.Image.from_url(disk['base'])
                    hashed_image_path = img.version_image_path()

                    with util.RecordedOperation('detect cdrom images', self):
                        try:
                            cd = pycdlib.PyCdlib()
                            cd.open(hashed_image_path)
                            disk['present_as'] = 'cdrom'
                        except Exception:
                            pass

                    if disk.get('present_as', 'cdrom') == 'cdrom':
                        # There is no point in resizing or COW'ing a cdrom
                        disk['path'] = disk['path'].replace('.qcow2', '.raw')
                        disk['type'] = 'raw'
                        disk['snapshot_ignores'] = True

                        try:
                            os.link(hashed_image_path, disk['path'])
                        except OSError:
                            # Different filesystems
                            util.execute([lock], 'cp %s %s' %
                                         (hashed_image_path, disk['path']))

                        # Due to limitations in some installers, cdroms are always on IDE
                        disk['device'] = 'hd%s' % disk['device'][-1]
                        disk['bus'] = 'ide'
                    else:
                        if config.parsed.get('DISK_FORMAT') == 'qcow':
                            with util.RecordedOperation(
                                    'create copy on write layer', self):
                                images.create_cow([lock], hashed_image_path,
                                                  disk['path'], disk['size'])

                            # Record the backing store for modern libvirts
                            disk['backing'] = (
                                '<backingStore type=\'file\'>\n'
                                '        <format type=\'qcow2\'/>\n'
                                '        <source file=\'%s\'/>\n'
                                '      </backingStore>\n' %
                                (hashed_image_path))

                        elif config.parsed.get('DISK_FORMAT') == 'qcow_flat':
                            with util.RecordedOperation('resize image', self):
                                resized_image_path = img.resize([lock],
                                                                disk['size'])

                            with util.RecordedOperation(
                                    'create flat layer', self):
                                images.create_flat([lock], resized_image_path,
                                                   disk['path'])

                        elif config.parsed.get('DISK_FORMAT') == 'flat':
                            with util.RecordedOperation('resize image', self):
                                resized_image_path = img.resize([lock],
                                                                disk['size'])

                            with util.RecordedOperation(
                                    'create raw disk', self):
                                images.create_raw([lock], resized_image_path,
                                                  disk['path'])

                        else:
                            raise Exception('Unknown disk format')

                elif not os.path.exists(disk['path']):
                    util.execute(
                        None, 'qemu-img create -f qcow2 %s %sG' %
                        (disk['path'], disk['size']))

                modified_disks.append(disk)

            self.db_entry['block_devices']['devices'] = modified_disks
            self.db_entry['block_devices']['finalized'] = True

        db.persist_block_devices(self.db_entry['uuid'],
                                 self.db_entry['block_devices'])

        # Create the actual instance
        with util.RecordedOperation('create domain XML', self):
            self._create_domain_xml()

        # Sometimes on Ubuntu 20.04 we need to wait for port binding to work.
        # Revisiting this is tracked by issue 320 on github.
        with util.RecordedOperation('create domain', self):
            if not self.power_on():
                attempts = 0
                while not self.power_on() and attempts < 100:
                    LOG.withObj(self).warning(
                        'Instance required an additional attempt to power on')
                    time.sleep(5)
                    attempts += 1

        if self.is_powered_on():
            LOG.withObj(self).info('Instance now powered on')
        else:
            LOG.withObj(self).info('Instance failed to power on')
        db.update_instance_state(self.db_entry['uuid'], 'created')
Ejemplo n.º 2
0
 def test_create_cow(self, mock_exists, mock_execute):
     images.create_cow(None, '/a/b/c/base', '/a/b/c/cow', 10)
     mock_execute.assert_called_with(
         None, 'qemu-img create -b /a/b/c/base -f qcow2 /a/b/c/cow 10G')
Ejemplo n.º 3
0
    def create(self, lock=None):
        # Ensure we have state on disk
        if not os.path.exists(self.instance_path):
            LOG.debug('%s: Creating instance storage at %s' %
                      (self, self.instance_path))
            os.makedirs(self.instance_path)

        # Generate a config drive
        with util.RecordedOperation('make config drive', self) as _:
            self._make_config_drive(
                os.path.join(
                    self.instance_path,
                    self.db_entry['block_devices']['devices'][1]['path']))

        # Prepare disks
        if not self.db_entry['block_devices']['finalized']:
            modified_disks = []
            for disk in self.db_entry['block_devices']['devices']:
                if disk.get('base'):
                    with util.RecordedOperation('fetch image', self) as _:
                        image_url = images.resolve(disk['base'])
                        hashed_image_path, info, image_dirty, resp = \
                            images.requires_fetch(image_url)

                        if image_dirty:
                            hashed_image_path = images.fetch(hashed_image_path,
                                                             info,
                                                             resp,
                                                             lock=lock)
                        else:
                            hashed_image_path = '%s.v%03d' % (
                                hashed_image_path, info['version'])

                    try:
                        cd = pycdlib.PyCdlib()
                        cd.open(hashed_image_path)
                        disk['present_as'] = 'cdrom'
                    except Exception:
                        pass

                    if disk.get('present_as', 'cdrom') == 'cdrom':
                        # There is no point in resizing or COW'ing a cdrom
                        disk['path'] = disk['path'].replace('.qcow2', '.raw')
                        disk['type'] = 'raw'
                        disk['snapshot_ignores'] = True

                        try:
                            os.link(hashed_image_path, disk['path'])
                        except OSError:
                            # Different filesystems
                            if lock:
                                lock.refresh()

                            shutil.copyfile(hashed_image_path, disk['path'])

                            if lock:
                                lock.refresh()

                        # Due to limitations in some installers, cdroms are always on IDE
                        disk['device'] = 'hd%s' % disk['device'][-1]
                        disk['bus'] = 'ide'
                    else:
                        with util.RecordedOperation('transcode image',
                                                    self) as _:
                            if lock:
                                lock.refresh()

                            images.transcode(hashed_image_path)

                        with util.RecordedOperation('resize image', self) as _:
                            if lock:
                                lock.refresh()

                            resized_image_path = images.resize(
                                hashed_image_path, disk['size'])

                        with util.RecordedOperation(
                                'create copy on write layer', self) as _:
                            if lock:
                                lock.refresh

                            images.create_cow(resized_image_path, disk['path'])

                elif not os.path.exists(disk['path']):
                    processutils.execute('qemu-img create -f qcow2 %s %sG' %
                                         (disk['path'], disk['size']),
                                         shell=True)

                modified_disks.append(disk)

            self.db_entry['block_devices']['devices'] = modified_disks
            self.db_entry['block_devices']['finalized'] = True

        db.persist_block_devices(self.db_entry['uuid'],
                                 self.db_entry['block_devices'])

        # Create the actual instance
        with util.RecordedOperation('create domain XML', self) as _:
            self._create_domain_xml()
        with util.RecordedOperation('create domain', self) as _:
            self.power_on()

        db.update_instance_state(self.db_entry['uuid'], 'created')
Ejemplo n.º 4
0
 def test_create_cow(self, mock_exists, mock_execute):
     images.create_cow('/a/b/c/base', '/a/b/c/cow')
     mock_execute.assert_called_with(
         'qemu-img create -b /a/b/c/base -f qcow2 /a/b/c/cow', shell=True)