Example #1
0
 def test_resize_image_resize(self, mock_link, mock_identify, mock_exists,
                              mock_execute, mock_copyfile):
     images.resize('/a/b/c/hash', 8)
     mock_link.assert_not_called()
     mock_execute.assert_called_with(
         'qemu-img resize /a/b/c/hash.qcow2.8G 8G', shell=True)
     mock_copyfile.assert_called_with('/a/b/c/hash.qcow2',
                                      '/a/b/c/hash.qcow2.8G')
Example #2
0
 def test_resize_image_resize(self, mock_link, mock_identify, mock_exists,
                              mock_execute):
     images.resize(None, '/a/b/c/hash', 8)
     mock_link.assert_not_called()
     mock_execute.assert_has_calls([
         mock.call(None, 'cp /a/b/c/hash.qcow2 /a/b/c/hash.qcow2.8G'),
         mock.call(None, 'qemu-img resize /a/b/c/hash.qcow2.8G 8G')
     ])
Example #3
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):
            logutil.debug(
                [self], '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(disk['base'])
                    hashed_image_path = img.get([lock], self)

                    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:
                        with util.RecordedOperation('resize image', self):
                            resized_image_path = images.resize(
                                [lock], hashed_image_path, disk['size'])

                        if config.parsed.get('DISK_FORMAT') == 'qcow':
                            with util.RecordedOperation('create copy on write layer', self):
                                images.create_cow(
                                    [lock], resized_image_path, disk['path'])

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

                        elif config.parsed.get('DISK_FORMAT') == 'qcow_flat':
                            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('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:
                    logutil.warning(
                        [self], 'Instance required an additional attempt to power on')
                    time.sleep(5)
                    attempts += 1

        if self.is_powered_on():
            logutil.info([self], 'Instance now powered on')
        else:
            logutil.info([self], 'Instance failed to power on')
        db.update_instance_state(self.db_entry['uuid'], 'created')
Example #4
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')
Example #5
0
 def test_resize_image_link(self, mock_link, mock_identify, mock_exists,
                            mock_execute, mock_copyfile):
     images.resize('/a/b/c/hash', 8)
     mock_link.assert_called_with('/a/b/c/hash', '/a/b/c/hash.qcow2.8G')
     mock_execute.assert_not_called()
     mock_copyfile.assert_not_called()
Example #6
0
 def test_resize_image_noop(self, mock_link, mock_identify, mock_exists,
                            mock_execute):
     images.resize(None, '/a/b/c/hash', 8)
     mock_link.assert_not_called()
     mock_execute.assert_not_called()