Use the python module of libguestfs to set the root password when creating images with qcow2 format. --- src/virtBootstrap/sources/docker_source.py | 4 +- src/virtBootstrap/sources/file_source.py | 4 +- src/virtBootstrap/utils.py | 63 ++++++++++++++++++++++++------ src/virtBootstrap/virt_bootstrap.py | 14 ++++--- 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/virtBootstrap/sources/docker_source.py b/src/virtBootstrap/sources/docker_source.py index 0ca3b20..74dc548 100644 --- a/src/virtBootstrap/sources/docker_source.py +++ b/src/virtBootstrap/sources/docker_source.py @@ -60,6 +60,7 @@ class DockerSource(object): self.password = kwargs['password'] self.uid_map = kwargs['uid_map'] self.gid_map = kwargs['gid_map'] + self.root_password = kwargs['root_password'] self.output_format = kwargs['fmt'] self.insecure = kwargs['not_secure'] self.no_cache = kwargs['no_cache'] @@ -265,7 +266,8 @@ class DockerSource(object): self.progress("Extracting container layers into qcow2 images", value=50, logger=logger) utils.Build_QCOW2_Image(self.tar_files, dest, self.progress, - self.uid_map, self.gid_map) + self.uid_map, self.gid_map, + self.root_password) else: raise Exception("Unknown format:" + self.output_format) diff --git a/src/virtBootstrap/sources/file_source.py b/src/virtBootstrap/sources/file_source.py index 748181f..4e73da2 100644 --- a/src/virtBootstrap/sources/file_source.py +++ b/src/virtBootstrap/sources/file_source.py @@ -46,6 +46,7 @@ class FileSource(object): self.output_format = kwargs['fmt'] self.uid_map = kwargs['uid_map'] self.gid_map = kwargs['gid_map'] + self.root_password = kwargs['root_password'] self.progress = kwargs['progress'].update_progress def unpack(self, dest): @@ -66,7 +67,8 @@ class FileSource(object): self.progress("Extracting files into qcow2 image", value=0, logger=logger) utils.Build_QCOW2_Image([self.path], dest, self.progress, - self.uid_map, self.gid_map) + self.uid_map, self.gid_map, + self.root_password) else: raise Exception("Unknown format:" + self.output_format) diff --git a/src/virtBootstrap/utils.py b/src/virtBootstrap/utils.py index 7bcffa4..6cfe63c 100644 --- a/src/virtBootstrap/utils.py +++ b/src/virtBootstrap/utils.py @@ -57,7 +57,8 @@ class Build_QCOW2_Image(object): """ Create qcow2 image with backing chains from list of tar files. """ - def __init__(self, tar_files, dest, progress, uid_map=None, gid_map=None): + def __init__(self, tar_files, dest, progress, uid_map=None, gid_map=None, + root_password=None): """ Initialize guestfs """ @@ -68,6 +69,7 @@ class Build_QCOW2_Image(object): self.progress = progress self.uid_map = uid_map self.gid_map = gid_map + self.root_password = root_password self.fmt = 'qcow2' self.qcow2_files = [os.path.join(dest, 'layer-%s.qcow2' % i) for i in range(self.nlayers)] @@ -76,6 +78,18 @@ class Build_QCOW2_Image(object): self.create_base_qcow2_layer(self.tar_files[0], self.qcow2_files[0]) if len(self.tar_files) > 1: self.create_backing_chains() + elif self.root_password is not None: + # Add base disk and launch + self.g.add_drive_opts( + self.qcow2_files[0], + readonly=False, + format=self.fmt + ) + self.g.launch() + + # Set root password + if self.root_password is not None: + self.set_root_password() self.g.shutdown() def create_and_add_disk(self, qcow2_file, backingfile=None, @@ -150,6 +164,36 @@ class Build_QCOW2_Image(object): self.tar_in(tar_file, devices[i]) + def set_root_password(self): + """ + Set root password in the shadow file of image. + + Mount the last the layer to update the shadow file with the + hash for the root password. + """ + self.progress("Setting root password", logger=logger) + + last_layer_dev = self.g.list_devices()[-1] + self.g.mount(last_layer_dev, '/') + + if not self.g.is_file('/etc/shadow'): + logger.error('showfile was not found in this image') + return + + shadow_content = self.g.read_file('/etc/shadow').split('\n') + + if not shadow_content: + logger.error('showfile was empty') + return + + new_shadow_content = set_password_in_shadow_content( + shadow_content, + self.root_password + ) + self.g.write('/etc/shadow', '\n'.join(new_shadow_content)) + self.g.umount('/') + + def map_id(self, tar_members, map_uid, map_gid): """ Remapping ownership of all files inside image. @@ -172,6 +216,13 @@ class Build_QCOW2_Image(object): self.g.lchown(new_uid, new_gid, os.path.join('/', member.name)) +def get_random_string(n=6): + """ + Return random string of lowercase characters with lenght n. + """ + return ''.join(random.choice(string.ascii_lowercase) for _ in range(n)) + + def get_compression_type(tar_file): """ Get compression type of tar file. @@ -447,16 +498,6 @@ def set_root_password_in_rootfs(rootfs, password): os.chmod(shadow_file, shadow_file_permissions) -def set_root_password_in_image(image, password): - """ - Set password on the root user within image - """ - password_hash = passlib.hosts.linux_context.hash(password) - execute(['virt-edit', - '-a', image, '/etc/shadow', - '-e', 's,^root:.*?:,root:%s:,' % re.escape(password_hash)]) - - def set_root_password(fmt, dest, root_password): """ Set root password diff --git a/src/virtBootstrap/virt_bootstrap.py b/src/virtBootstrap/virt_bootstrap.py index 54025d2..3cc7edb 100755 --- a/src/virtBootstrap/virt_bootstrap.py +++ b/src/virtBootstrap/virt_bootstrap.py @@ -128,15 +128,17 @@ def bootstrap(uri, dest, gid_map=gid_map, not_secure=not_secure, no_cache=no_cache, + root_password=root_password, progress=prog).unpack(dest) - if root_password is not None: - logger.info("Setting password of the root account") - utils.set_root_password(fmt, dest, root_password) + if fmt == "dir": + if root_password is not None: + logger.info("Setting password of the root account") + utils.set_root_password_in_rootfs(dest, root_password) - if fmt == "dir" and uid_map or gid_map: - logger.info("Mapping UID/GID") - utils.mapping_uid_gid(dest, uid_map, gid_map) + if uid_map or gid_map: + logger.info("Mapping UID/GID") + utils.mapping_uid_gid(dest, uid_map, gid_map) def set_logging_conf(loglevel=None): -- 2.13.3 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list