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.
This commit is contained in:
Brian C. Lane 2014-04-02 16:56:28 -07:00
parent ac1f2254e2
commit 19d8304070

View File

@ -416,24 +416,21 @@ def make_appliance(disk_img, name, template, outfile, networks=None, ram=1024,
f.write(result) 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 diskimage is the full path to partitioned disk image with a /
ami_label is the FS label to apply to the image fsimage is the full path of the output fs image file
label is the label to apply to the image. Defaults to "Anaconda"
All other AMI setup is handled by the kickstart's %post
""" """
with PartitionMount( disk_img ) as img_mount: with PartitionMount(diskimage) as img_mount:
if not img_mount or not img_mount.mount_dir: if not img_mount or not img_mount.mount_dir:
return None return None
work_dir = tempfile.mkdtemp() log.info("Creating fsimage %s", fsimage)
log.info("working dir is {0}".format(work_dir)) mkext4img(img_mount.mount_dir, fsimage, label=label)
log.info("creating {0}".format(ami_img))
mkext4img(img_mount.mount_dir, joinpaths(work_dir, ami_img), label=ami_label)
return work_dir
def make_runtime(opts, mount_dir, work_dir): 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 # Make a blank fs image
args += ["--dirinstall"] 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): if not os.path.isdir(ROOT_PATH):
os.mkdir(ROOT_PATH) os.mkdir(ROOT_PATH)
mount(disk_img, opts="loop", mnt=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): def virt_install(opts, install_log, disk_img, disk_size):
""" """
Use virt-install to install to a disk image 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) iso_mount = IsoMountpoint(opts.iso, opts.location)
log_monitor = LogMonitor(install_log) log_monitor = LogMonitor(install_log)
@ -622,7 +623,7 @@ def virt_install(opts, install_log, disk_img, disk_size):
if opts.proxy: if opts.proxy:
kernel_args += " proxy="+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 # virt-install can't take all the qcow2 options so create the image first
qcow2_args = [] qcow2_args = []
for arg in opts.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) 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, kernel_args, opts.ram, opts.vnc, opts.arch,
log_check = log_monitor.server.log_check, log_check = log_monitor.server.log_check,
virtio_host = log_monitor.host, 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(): if log_monitor.server.log_check():
raise InstallError("virt_install failed") 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"): 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. 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) disk_size = 1 + (sum([p.size for p in ks.handler.partition.partitions]) / 1024)
log.info("disk_size = {0}GB".format(disk_size)) log.info("disk_size = %sGB", disk_size)
repo_url = ks.handler.method.url
if opts.image_name: if opts.image_name:
disk_img = joinpaths(opts.tmp, opts.image_name) disk_img = joinpaths(opts.tmp, opts.image_name)
else: else:
disk_img = tempfile.mktemp(prefix="disk", suffix=".img", dir=opts.tmp) 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 = %s", disk_img)
log.info("disk_img = {0}".format(disk_img))
log.info("install_log = {0}".format(install_log))
try: try:
if opts.no_virt: 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: 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) virt_install(opts, install_log, disk_img, disk_size)
except InstallError as e: except InstallError as e:
log.error("Install failed: {0}".format(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 = parser.add_argument_group("disk/fs image arguments")
image_group.add_argument( "--disk-image", type=os.path.abspath, 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", image_group.add_argument( "--keep-image", action="store_true",
help="Keep raw disk image after .iso creation" ) help="Keep raw disk image after .iso creation" )
image_group.add_argument( "--fs-image", type=os.path.abspath, 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, image_group.add_argument( "--image-name", default=None,
help="Name of fs/disk image to create. Default is a random name." ) 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", 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=[], image_group.add_argument("--qcow2-arg", action="append", dest="qcow2_args", default=[],
help="Arguments to pass to qemu-img. Pass once for each argument") 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.") log.error("qcow2 cannot be used to make a bootable iso.")
sys.exit(1) 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: if opts.app_file:
opts.app_file = joinpaths(opts.tmp, 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, " errors.append("The kickstart must not set a display mode (text, cmdline, "
"graphical), this will interfere with livemedia-creator.") "graphical), this will interfere with livemedia-creator.")
# TODO add a check for fsimage partition, no autopart and only / or swap part
if errors: if errors:
for e in errors: for e in errors:
log.error(e) log.error(e)
@ -984,8 +1007,6 @@ if __name__ == '__main__':
os.unlink(disk_img) os.unlink(disk_img)
log.info("Disk image erased") log.info("Disk image erased")
disk_img = None disk_img = None
elif opts.make_ami:
result_dir = make_ami(opts.disk_image or disk_img)
elif opts.make_appliance: elif opts.make_appliance:
if not opts.ks: if not opts.ks:
networks = [] networks = []