|
|
|
@ -311,7 +311,7 @@ class VirtualInstall( object ):
|
|
|
|
|
|
|
|
|
|
rc = execWithRedirect("virt-install", args)
|
|
|
|
|
if rc:
|
|
|
|
|
raise Exception("Problem starting virtual install")
|
|
|
|
|
raise InstallError("Problem starting virtual install")
|
|
|
|
|
|
|
|
|
|
conn = libvirt.openReadOnly(None)
|
|
|
|
|
dom = conn.lookupByName(self.virt_name)
|
|
|
|
@ -440,24 +440,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):
|
|
|
|
@ -571,7 +568,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)
|
|
|
|
@ -615,6 +612,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)
|
|
|
|
@ -625,18 +626,41 @@ def virt_install(opts, install_log, disk_img, disk_size):
|
|
|
|
|
if opts.proxy:
|
|
|
|
|
kernel_args += " proxy="+opts.proxy
|
|
|
|
|
|
|
|
|
|
virt = VirtualInstall(iso_mount, opts.ks, disk_img, disk_size,
|
|
|
|
|
kernel_args, opts.ram, opts.vnc, opts.arch,
|
|
|
|
|
log_check = log_monitor.server.log_check,
|
|
|
|
|
virtio_host = log_monitor.host,
|
|
|
|
|
virtio_port = log_monitor.port)
|
|
|
|
|
virt.destroy()
|
|
|
|
|
log_monitor.shutdown()
|
|
|
|
|
iso_mount.umount()
|
|
|
|
|
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:
|
|
|
|
|
qcow2_args += arg.split(" ", 1)
|
|
|
|
|
|
|
|
|
|
mkqcow2(disk_img, disk_size*1024**3, qcow2_args)
|
|
|
|
|
|
|
|
|
|
if opts.make_fsimage:
|
|
|
|
|
diskimg_path = tempfile.mktemp(prefix="disk", suffix=".img", dir=opts.tmp)
|
|
|
|
|
else:
|
|
|
|
|
diskimg_path = disk_img
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
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,
|
|
|
|
|
virtio_port = log_monitor.port)
|
|
|
|
|
virt.destroy()
|
|
|
|
|
log_monitor.shutdown()
|
|
|
|
|
except InstallError as e:
|
|
|
|
|
log.error("VirtualInstall failed: %s", e)
|
|
|
|
|
raise
|
|
|
|
|
finally:
|
|
|
|
|
log.info("unmounting the iso")
|
|
|
|
|
iso_mount.umount()
|
|
|
|
|
|
|
|
|
|
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"):
|
|
|
|
|
"""
|
|
|
|
@ -659,30 +683,28 @@ 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))
|
|
|
|
|
if not opts.keep_image:
|
|
|
|
|
if not opts.keep_image and os.path.exists(disk_img):
|
|
|
|
|
log.info("Removing bad disk image")
|
|
|
|
|
os.unlink(disk_img)
|
|
|
|
|
raise
|
|
|
|
@ -737,19 +759,11 @@ if __name__ == '__main__':
|
|
|
|
|
|
|
|
|
|
parser.add_argument( "--iso", type=os.path.abspath,
|
|
|
|
|
help="Anaconda installation .iso path to use for virt-install" )
|
|
|
|
|
parser.add_argument( "--disk-image", type=os.path.abspath,
|
|
|
|
|
help="Path to disk image to use for creating final image" )
|
|
|
|
|
parser.add_argument( "--fs-image", type=os.path.abspath,
|
|
|
|
|
help="Path to filesystem image to use for creating final image" )
|
|
|
|
|
|
|
|
|
|
parser.add_argument( "--ks", action="append", type=os.path.abspath,
|
|
|
|
|
help="Kickstart file defining the install." )
|
|
|
|
|
parser.add_argument( "--image-name", default=None,
|
|
|
|
|
help="Name of fs/disk image to create. Default is a random name." )
|
|
|
|
|
parser.add_argument( "--image-only", action="store_true",
|
|
|
|
|
help="Exit after creating fs/disk image." )
|
|
|
|
|
parser.add_argument( "--keep-image", action="store_true",
|
|
|
|
|
help="Keep raw disk image after .iso creation" )
|
|
|
|
|
parser.add_argument( "--no-virt", action="store_true",
|
|
|
|
|
help="Use Anaconda's image install instead of virt-install" )
|
|
|
|
|
parser.add_argument( "--proxy",
|
|
|
|
@ -783,6 +797,22 @@ if __name__ == '__main__':
|
|
|
|
|
parser.add_argument( "--nomacboot", action="store_false",
|
|
|
|
|
dest="domacboot")
|
|
|
|
|
|
|
|
|
|
image_group = parser.add_argument_group("disk/fs image arguments")
|
|
|
|
|
image_group.add_argument( "--disk-image", type=os.path.abspath,
|
|
|
|
|
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 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 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")
|
|
|
|
|
|
|
|
|
|
# Group of arguments for appliance creation
|
|
|
|
|
app_group = parser.add_argument_group("appliance arguments")
|
|
|
|
|
app_group.add_argument( "--app-name", default=None,
|
|
|
|
@ -894,6 +924,24 @@ if __name__ == '__main__':
|
|
|
|
|
log.error("The disk image to be created should not exist.")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
if opts.qcow2 and not os.path.exists("/usr/bin/qemu-img"):
|
|
|
|
|
log.error("qcow2 requires the qemu-img utility to be installed.")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
if opts.qcow2 and opts.make_iso:
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
@ -921,6 +969,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)
|
|
|
|
@ -960,8 +1011,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 = []
|
|
|
|
|