def test_resolve_image(self, mock_mkdirs, mock_exists, mock_ubuntu, mock_centos): img = images.Image('win10') self.assertEqual('win10', img.url) img = images.Image('http://example.com/image') self.assertEqual('http://example.com/image', img.url) img = images.Image('cirros') self.assertEqual('!!!cirros!!!', img.url) img = images.Image('ubuntu') self.assertEqual('!!!ubuntu!!!', img.url)
def test_fetch_image_old(self, mock_loads, mock_get, mock_makedirs, mock_exists, mock_config): mock_open = mock.mock_open() with mock.patch.object(six.moves.builtins, 'open', new=mock_open): img = images.Image('http://example.com') dirty_fields, _ = img._requires_fetch() self.assertEqual({}, dirty_fields)
def test_get_always_corrupt(self, mock_refresh_locks, mock_put, mock_open): test_checksum = '097c42989a9e5d9dcced7b35ec4b0486' image = images.Image(self.id(), test_checksum, None, None, None, 0) self.addCleanup(os.remove, image.image_path + '.v001') self.addCleanup(os.remove, image.image_path + '.v002') self.addCleanup(os.remove, image.image_path + '.v003') self.assertRaises(exceptions.BadCheckSum, image.get, None, None)
def test_get(self, mock_refresh_locks, mock_put, mock_open, mock_transcode): test_checksum = '097c42989a9e5d9dcced7b35ec4b0486' image = images.Image(self.id(), test_checksum, None, None, None, 0) self.addCleanup(os.remove, image.image_path + '.v001') ret = image.get(None, None) self.assertEqual( '/tmp/image_cache/a428fe2fb5e893a6a875e921334e8ebbf9913ba3e74cd2bd3397b6c76b867539.v001', ret) self.assertTrue(image.correct_checksum(image.version_image_path()))
def image_fetch(url, instance_uuid): try: instance = None if instance_uuid: instance = virt.from_db(instance_uuid) img = images.Image(url) img.get([], instance) except exceptions.LockException: pass
def test_get_one_corrupt(self, mock_refresh_locks, mock_put, mock_open, mock_transcode): test_checksum = '097c42989a9e5d9dcced7b35ec4b0486' image = images.Image(self.id(), test_checksum, None, None, None, 0) self.addCleanup(os.remove, image.image_path + '.v001') ret = image.get(None, None) self.assertEqual( '/tmp/image_cache/318549312751bc53373bf5470d298956be5097c0e492158d03594c44035463eb.v001', ret) self.assertTrue(image.correct_checksum(image.version_image_path()))
def test_requires_fetch(self, mock_mkdirs, mock_read_local_info, mock_request_head): img = images.Image('http://example.com') dirty_fields, _ = img._requires_fetch() self.assertEqual(0, img.info['version']) self.assertEqual( { 'Last-Modified': { 'after': 'Tue, 10 Sep 2019 07:24:40 GMT', 'before': 'Tue, 10 Sep 2017 07:24:40 GMT' } }, dirty_fields)
def test_correct_checksum(self): test_file = '/tmp/' + self.id() test_checksum = 'a5890ace30a3e84d9118196c161aeec2' image = images.Image('testurl', test_checksum, None, None, None, 0) with open(test_file, 'w') as f: f.write('this is a test file') self.addCleanup(os.remove, test_file) # Correct checksum self.assertTrue(image.correct_checksum(test_file)) # Bad checksum image.checksum = 'wrong' self.assertFalse(image.correct_checksum(test_file))
def test_fetch_image_changed(self, mock_execute, mock_read_local_info, mock_makedirs, mock_exists, mock_config): img = images.Image('http://example.com') image_dirty, _ = img._requires_fetch() self.assertEqual( { 'Content-Length': { 'after': '648', 'before': 100000 }, 'Last-Modified': { 'after': 'Thu, 17 Oct 2019 07:18:26 GMT', 'before': 'Tue, 10 Sep 2018 07:24:40 GMT' } }, image_dirty)
def test_fetch_image_new(self, mock_get, mock_makedirs, mock_exists, mock_config): img = images.Image('http://example.com') dirty_fields, _ = img._requires_fetch() self.assertEqual( { 'Content-Length': { 'after': 200000, 'before': None }, 'Last-Modified': { 'after': 'Tue, 10 Sep 2019 07:24:40 GMT', 'before': None } }, dirty_fields)
def test__fetch(self, mock_refresh_locks): test_checksum = '097c42989a9e5d9dcced7b35ec4b0486' image = images.Image(self.id(), test_checksum, None, None, None, 0) # Data matching checksum self.addCleanup(os.remove, image.image_path + '.v001') resp = FakeResp(chunks=[(b'chunk1', b'chunk2')]) ret = image._fetch(resp) self.assertEqual( '/tmp/image_cache/d025021483c8f33152ffee46fa274ab00a9be367e19822fa07f25c9650197036.v001', ret) self.assertTrue(image.correct_checksum(image.version_image_path())) # Data does not match checksum self.addCleanup(os.remove, image.image_path + '.v002') resp = FakeResp(chunks=[(b'chunk1', b'badchunk2')]) ret = image._fetch(resp) self.assertEqual( '/tmp/image_cache/d025021483c8f33152ffee46fa274ab00a9be367e19822fa07f25c9650197036.v002', ret) self.assertFalse(image.correct_checksum(image.version_image_path()))
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')
def test_does_not_require_fetch(self, mock_mkdirs, mock_read_local_info, mock_request_head): img = images.Image('http://example.com') dirty_fields, _ = img._requires_fetch() self.assertEqual(0, img.info['version']) self.assertEqual({}, dirty_fields)
def test_hash_image(self, mock_mkdirs, mock_exists): img = images.Image('http://example.com') self.assertEqual( 'f0e6a6a97042a4f1f1c87f5f7d44315b2d' '852c2df5c7991cc66241bf7072d1c4', img.hashed_image_url)