def _populate_one_volume(self, name, volume): for partnum, part in enumerate(volume.structures): part_img = volume.part_images[partnum] part_dir = os.path.join(volume.basedir, 'part{}'.format(partnum)) if part.role is StructureRole.system_data: # The root partition needs to be ext4, which may or may not be # populated at creation time, depending on the version of # e2fsprogs. mkfs_ext4(part_img, self.rootfs, self.args.cmd, part.filesystem_label, preserve_ownership=True) elif part.filesystem is FileSystemType.none: image = Image(part_img, part.size) offset = 0 for content in part.content: src = os.path.join(self.unpackdir, 'gadget', content.image) file_size = os.path.getsize(src) assert content.size is None or content.size >= file_size, ( 'Spec size {} < actual size {} of: {}'.format( content.size, file_size, content.image)) if content.size is not None: file_size = content.size # TODO: We need to check for overlapping images. if content.offset is not None: offset = content.offset end = offset + file_size if end > part.size: if part.name is None: if part.role is None: whats_wrong = part.type else: whats_wrong = part.role.value else: whats_wrong = part.name part_path = 'volumes:<{}>:structure:<{}>'.format( name, whats_wrong) self.exitcode = 1 raise DoesNotFit(partnum, part_path, end - part.size) image.copy_blob(src, bs=1, seek=offset, conv='notrunc') offset += file_size elif part.filesystem is FileSystemType.vfat: sourcefiles = SPACE.join( os.path.join(part_dir, filename) for filename in os.listdir(part_dir)) env = dict(MTOOLS_SKIP_CHECK='1') env.update(os.environ) run('mcopy -s -i {} {} ::'.format(part_img, sourcefiles), env=env) elif part.filesystem is FileSystemType.ext4: mkfs_ext4(part_img, part_dir, self.args.cmd, part.filesystem_label) else: raise AssertionError('Invalid part filesystem type: {}'.format( part.filesystem))
def _populate_one_volume(self, name, volume): for partnum, part in enumerate(volume.structures): part_img = volume.part_images[partnum] part_dir = os.path.join(volume.basedir, 'part{}'.format(partnum)) if part.role is StructureRole.system_data: # The root partition needs to be ext4, which may or may not be # populated at creation time, depending on the version of # e2fsprogs. mkfs_ext4(part_img, self.rootfs, self.args.cmd, part.filesystem_label, preserve_ownership=True) elif part.filesystem is FileSystemType.none: image = Image(part_img, part.size) offset = 0 for content in part.content: src = os.path.join(self.unpackdir, 'gadget', content.image) file_size = os.path.getsize(src) assert content.size is None or content.size >= file_size, ( 'Spec size {} < actual size {} of: {}'.format( content.size, file_size, content.image)) if content.size is not None: file_size = content.size # TODO: We need to check for overlapping images. if content.offset is not None: offset = content.offset end = offset + file_size if end > part.size: if part.name is None: if part.role is None: whats_wrong = part.type else: whats_wrong = part.role.value else: whats_wrong = part.name part_path = 'volumes:<{}>:structure:<{}>'.format( name, whats_wrong) self.exitcode = 1 raise DoesNotFit(partnum, part_path, end - part.size) image.copy_blob(src, bs=1, seek=offset, conv='notrunc') offset += file_size elif part.filesystem is FileSystemType.vfat: sourcefiles = SPACE.join( os.path.join(part_dir, filename) for filename in os.listdir(part_dir) ) env = dict(MTOOLS_SKIP_CHECK='1') env.update(os.environ) run('mcopy -s -i {} {} ::'.format(part_img, sourcefiles), env=env) elif part.filesystem is FileSystemType.ext4: mkfs_ext4(part_img, part_dir, self.args.cmd, part.filesystem_label) else: raise AssertionError('Invalid part filesystem type: {}'.format( part.filesystem))
def test_mkfs_ext4_no_contents(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) results_dir = os.path.join(tmpdir, 'results') mock = MountMocker(results_dir) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) # Create a temporary directory, but this time without contents. contents_dir = resources.enter_context(TemporaryDirectory()) # And a fake image file. img_file = resources.enter_context(NamedTemporaryFile()) mkfs_ext4(img_file, contents_dir, 'snap') # Because there were no contents, the `sudo cp` was never called, # the mock's shutil.copytree() was also never called, therefore # the results_dir was never created. self.assertFalse(os.path.exists(results_dir))
def test_mkfs_ext4_preserve_ownership(self): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) results_dir = os.path.join(tmpdir, 'results') mock = MountMocker(results_dir) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) # Create a temporary directory and populate it with some stuff. contents_dir = resources.enter_context(TemporaryDirectory()) with open(os.path.join(contents_dir, 'a.dat'), 'wb') as fp: fp.write(b'01234') # And a fake image file. img_file = resources.enter_context(NamedTemporaryFile()) mkfs_ext4(img_file, contents_dir, 'snap', preserve_ownership=True) with open(os.path.join(mock.results_dir, 'a.dat'), 'rb') as fp: self.assertEqual(fp.read(), b'01234') self.assertTrue(mock.preserves_ownership)
def aux_test_mkfs_ext4(self, cmd): with ExitStack() as resources: tmpdir = resources.enter_context(TemporaryDirectory()) results_dir = os.path.join(tmpdir, 'results') mock = MountMocker(results_dir) resources.enter_context( patch('ubuntu_image.helpers.run', mock.run)) # Create a temporary directory and populate it with some stuff. contents_dir = resources.enter_context(TemporaryDirectory()) with open(os.path.join(contents_dir, 'a.dat'), 'wb') as fp: fp.write(b'01234') with open(os.path.join(contents_dir, 'b.dat'), 'wb') as fp: fp.write(b'56789') # And a fake image file. img_file = resources.enter_context(NamedTemporaryFile()) mkfs_ext4(img_file, contents_dir, cmd) # Two files were put in the "mountpoint" directory, but because of # above, we have to check them in the results copy. with open(os.path.join(mock.results_dir, 'a.dat'), 'rb') as fp: self.assertEqual(fp.read(), b'01234') with open(os.path.join(mock.results_dir, 'b.dat'), 'rb') as fp: self.assertEqual(fp.read(), b'56789')
def _populate_one_volume(self, name, volume): # For the LK bootloader we need to copy boot.img and snapbootsel.bin to # the gadget folder so they can be used as partition content. The first # one comes from the kernel snap, while the second one is modified by # 'snap prepare-image' to set the right core and kernel for the kernel # command line. if volume.bootloader is BootLoader.lk: boot = os.path.join(self.unpackdir, 'image', 'boot', 'lk') gadget = os.path.join(self.unpackdir, 'gadget') if os.path.isdir(boot): os.makedirs(gadget, exist_ok=True) for filename in os.listdir(boot): src = os.path.join(boot, filename) dst = os.path.join(gadget, filename) shutil.copy(src, dst) for partnum, part in enumerate(volume.structures): part_img = volume.part_images[partnum] # In seeded images, the system-seed partition is basically the # rootfs partition - at least from the ubuntu-image POV. if part.role is StructureRole.system_seed: part_dir = self.rootfs else: part_dir = os.path.join(volume.basedir, 'part{}'.format(partnum)) if part.role is StructureRole.system_data: # The root partition needs to be ext4, which may or may not be # populated at creation time, depending on the version of # e2fsprogs. mkfs_ext4(part_img, self.rootfs, self.args.cmd, part.filesystem_label, preserve_ownership=True) elif part.filesystem is FileSystemType.none: image = Image(part_img, part.size) offset = 0 for content in part.content: src = os.path.join(self.unpackdir, 'gadget', content.image) file_size = os.path.getsize(src) assert content.size is None or content.size >= file_size, ( 'Spec size {} < actual size {} of: {}'.format( content.size, file_size, content.image)) if content.size is not None: file_size = content.size # TODO: We need to check for overlapping images. if content.offset is not None: offset = content.offset end = offset + file_size if end > part.size: if part.name is None: if part.role is None: whats_wrong = part.type else: whats_wrong = part.role.value else: whats_wrong = part.name part_path = 'volumes:<{}>:structure:<{}>'.format( name, whats_wrong) self.exitcode = 1 raise DoesNotFit(partnum, part_path, end - part.size) image.copy_blob(src, bs=1, seek=offset, conv='notrunc') offset += file_size elif part.filesystem is FileSystemType.vfat: sourcefiles = SPACE.join( os.path.join(part_dir, filename) for filename in os.listdir(part_dir)) env = dict(MTOOLS_SKIP_CHECK='1') env.update(os.environ) run('mcopy -s -i {} {} ::'.format(part_img, sourcefiles), env=env) elif part.filesystem is FileSystemType.ext4: mkfs_ext4(part_img, part_dir, self.args.cmd, part.filesystem_label) else: raise AssertionError('Invalid part filesystem type: {}'.format( part.filesystem))