From 19d830407011474e56974aa34b9e14478fe1bace Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Wed, 2 Apr 2014 16:56:28 -0700 Subject: [PATCH] livemedia-creator: Make --make-fsimage work with virt-install --make-fsimage was only working with --no-virt, this re-structures things so that virt-install partitioned disk images can be converted to a fsimage. --make-ami was actually already doing this, so change it to use --make-fsimage and set the default image name to "ami-root.img" with a label of "AMI". This also adds the ability to set the fs label on iso fsimage and fsimages created with --make-fsimage and --make-ami by passing --fs-label, but note that bootable iso's expect the Anaconda label. --- src/sbin/livemedia-creator | 79 ++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator index ce896d04..e2385ce3 100755 --- a/src/sbin/livemedia-creator +++ b/src/sbin/livemedia-creator @@ -416,24 +416,21 @@ def make_appliance(disk_img, name, template, outfile, networks=None, ram=1024, f.write(result) -def make_ami( disk_img, ami_img="ami-root.img", ami_label="AMI" ): +def make_fsimage(diskimage, fsimage, label="Anaconda"): """ - Copy the / partition to an un-partitioned disk image + Copy the / partition of a partitioned disk image to an un-partitioned + disk image. - ami_img is the filename to write, defaults to ami-root.img - ami_label is the FS label to apply to the image - - All other AMI setup is handled by the kickstart's %post + diskimage is the full path to partitioned disk image with a / + fsimage is the full path of the output fs image file + label is the label to apply to the image. Defaults to "Anaconda" """ - with PartitionMount( disk_img ) as img_mount: + with PartitionMount(diskimage) as img_mount: if not img_mount or not img_mount.mount_dir: return None - work_dir = tempfile.mkdtemp() - log.info("working dir is {0}".format(work_dir)) - log.info("creating {0}".format(ami_img)) - mkext4img(img_mount.mount_dir, joinpaths(work_dir, ami_img), label=ami_label) - return work_dir + log.info("Creating fsimage %s", fsimage) + mkext4img(img_mount.mount_dir, fsimage, label=label) def make_runtime(opts, mount_dir, work_dir): @@ -552,7 +549,7 @@ def novirt_install(opts, disk_img, disk_size, repo_url): # Make a blank fs image args += ["--dirinstall"] - mkext4img(None, disk_img, label="Anaconda", size=disk_size * 1024**3) + mkext4img(None, disk_img, label=opts.fs_label, size=disk_size * 1024**3) if not os.path.isdir(ROOT_PATH): os.mkdir(ROOT_PATH) mount(disk_img, opts="loop", mnt=ROOT_PATH) @@ -612,6 +609,10 @@ def novirt_install(opts, disk_img, disk_size, repo_url): def virt_install(opts, install_log, disk_img, disk_size): """ Use virt-install to install to a disk image + + install_log is the path to write the log from virt-install + disk_img is the full path to the final disk or filesystem image + disk_size is the size of the disk to create in GiB """ iso_mount = IsoMountpoint(opts.iso, opts.location) log_monitor = LogMonitor(install_log) @@ -622,7 +623,7 @@ def virt_install(opts, install_log, disk_img, disk_size): if opts.proxy: kernel_args += " proxy="+opts.proxy - if opts.qcow2: + if opts.qcow2 and not opts.make_fsimage: # virt-install can't take all the qcow2 options so create the image first qcow2_args = [] for arg in opts.qcow2_args: @@ -630,7 +631,12 @@ def virt_install(opts, install_log, disk_img, disk_size): mkqcow2(disk_img, disk_size*1024**3, qcow2_args) - virt = VirtualInstall(iso_mount, opts.ks, disk_img, disk_size, + if opts.make_fsimage: + diskimg_path = tempfile.mktemp(prefix="disk", suffix=".img", dir=opts.tmp) + else: + diskimg_path = disk_img + + virt = VirtualInstall(iso_mount, opts.ks, diskimg_path, disk_size, kernel_args, opts.ram, opts.vnc, opts.arch, log_check = log_monitor.server.log_check, virtio_host = log_monitor.host, @@ -644,6 +650,10 @@ def virt_install(opts, install_log, disk_img, disk_size): if log_monitor.server.log_check(): raise InstallError("virt_install failed") + if opts.make_fsimage: + make_fsimage(diskimg_path, disk_img, label=opts.fs_label) + os.unlink(diskimg_path) + def make_squashfs(disk_img, work_dir, compression="xz"): """ @@ -666,26 +676,24 @@ def make_image(opts, ks): Use virt or anaconda to install to an image. - Returns the name of the image created. + Returns the full path of of the image created. """ disk_size = 1 + (sum([p.size for p in ks.handler.partition.partitions]) / 1024) - log.info("disk_size = {0}GB".format(disk_size)) - - repo_url = ks.handler.method.url + log.info("disk_size = %sGB", disk_size) if opts.image_name: disk_img = joinpaths(opts.tmp, opts.image_name) else: disk_img = tempfile.mktemp(prefix="disk", suffix=".img", dir=opts.tmp) - install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log" - - log.info("disk_img = {0}".format(disk_img)) - log.info("install_log = {0}".format(install_log)) + log.info("disk_img = %s", disk_img) try: if opts.no_virt: - novirt_install(opts, disk_img, disk_size, repo_url) + novirt_install(opts, disk_img, disk_size, ks.handler.method.url) else: + install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log" + log.info("install_log = %s", install_log) + virt_install(opts, install_log, disk_img, disk_size) except InstallError as e: log.error("Install failed: {0}".format(e)) @@ -784,15 +792,17 @@ if __name__ == '__main__': image_group = parser.add_argument_group("disk/fs image arguments") image_group.add_argument( "--disk-image", type=os.path.abspath, - help="Path to disk image to use for creating final image" ) + help="Path to existing disk image to use for creating final image." ) image_group.add_argument( "--keep-image", action="store_true", help="Keep raw disk image after .iso creation" ) image_group.add_argument( "--fs-image", type=os.path.abspath, - help="Path to filesystem image to use for creating final image" ) + help="Path to existing filesystem image to use for creating final image." ) image_group.add_argument( "--image-name", default=None, help="Name of fs/disk image to create. Default is a random name." ) + image_group.add_argument( "--fs-label", default="Anaconda", + help="Label to set on fsimage, default is 'Anaconda'") image_group.add_argument("--qcow2", action="store_true", - help="create qcow2 image instead of raw sparse image") + help="Create qcow2 image instead of raw sparse image when making disk images.") image_group.add_argument("--qcow2-arg", action="append", dest="qcow2_args", default=[], help="Arguments to pass to qemu-img. Pass once for each argument") @@ -915,6 +925,16 @@ if __name__ == '__main__': log.error("qcow2 cannot be used to make a bootable iso.") sys.exit(1) + # TODO check for qcow2 and fsimage + + # AMI image is just a fsimage with an AMI label + if opts.make_ami: + opts.make_fsimage = True + if not opts.image_name: + opts.image_name = "ami-root.img" + if opts.fs_label == "Anaconda": + opts.fs_label = "AMI" + if opts.app_file: opts.app_file = joinpaths(opts.tmp, opts.app_file) @@ -945,6 +965,9 @@ if __name__ == '__main__': errors.append("The kickstart must not set a display mode (text, cmdline, " "graphical), this will interfere with livemedia-creator.") + # TODO add a check for fsimage partition, no autopart and only / or swap part + + if errors: for e in errors: log.error(e) @@ -984,8 +1007,6 @@ if __name__ == '__main__': os.unlink(disk_img) log.info("Disk image erased") disk_img = None - elif opts.make_ami: - result_dir = make_ami(opts.disk_image or disk_img) elif opts.make_appliance: if not opts.ks: networks = []