Add --make-pxe-live and --make-ostree-live (for Atomic) targets.
Resolves: rhbz#1184021 --make-pxe-live target generate live squashfs and initrd for pxe boot. Also generates pxe config template. --make-ostree-live is used for installations of Atomic Host. Additionally to --make-pxe-live it ensures using deployment root instead of physical root of installed disk image where needed. Atomic installation needs to be virt installation with /boot on separate partition (the only way supported by Anaconda currently). Content of boot partition is added to live root fs so that ostree can find deployment by boot configuration.
This commit is contained in:
parent
e087f5a33c
commit
28801d8d42
@ -238,6 +238,22 @@ eg.
|
|||||||
livemedia-creator --make-tar --iso=/path/to/boot.iso --ks=./docs/fedora-minimal.ks \
|
livemedia-creator --make-tar --iso=/path/to/boot.iso --ks=./docs/fedora-minimal.ks \
|
||||||
--image-name=fedora-root.tar.xz
|
--image-name=fedora-root.tar.xz
|
||||||
|
|
||||||
|
LIVE IMAGE FOR PXE BOOT
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The --make-pxe-live command will produce squashfs image containing live root
|
||||||
|
filesystem that can be used for pxe boot. Directory with results will contain
|
||||||
|
the live image, kernel image, initrd image and template of pxe configuration
|
||||||
|
for the images.
|
||||||
|
|
||||||
|
ATOMIC LIVE IMAGE FOR PXE BOOT
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
The --make-ostree-live command will produce the same result as --make-pxe-live
|
||||||
|
for installations of Atomic Host. Example kickstart for such an installation
|
||||||
|
using Atomic installer iso with local repo included in the image can be found
|
||||||
|
in docs/rhel-atomic-pxe-live.ks.
|
||||||
|
|
||||||
|
|
||||||
DEBUGGING PROBLEMS
|
DEBUGGING PROBLEMS
|
||||||
------------------
|
------------------
|
||||||
|
@ -4,7 +4,7 @@ livemedia-creator \- Create live install media
|
|||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
livemedia-creator [-h]
|
livemedia-creator [-h]
|
||||||
(--make-iso | --make-disk | --make-fsimage | --make-appliance | --make-ami | --make-tar)
|
(--make-iso | --make-disk | --make-fsimage | --make-appliance | --make-ami | --make-tar | --make-pxe-live | --make-ostree-live)
|
||||||
[--iso ISO] [--disk-image DISK_IMAGE]
|
[--iso ISO] [--disk-image DISK_IMAGE]
|
||||||
[--fs-image FS_IMAGE] [--ks KS]
|
[--fs-image FS_IMAGE] [--ks KS]
|
||||||
[--image-name IMAGE_NAME] [--image-only]
|
[--image-name IMAGE_NAME] [--image-only]
|
||||||
@ -69,6 +69,14 @@ Build an ami image
|
|||||||
\fB\-\-make\-tar\fR
|
\fB\-\-make\-tar\fR
|
||||||
Build a tar of the root filesystem. Defaults to root.tar.xz
|
Build a tar of the root filesystem. Defaults to root.tar.xz
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-make\-pxe\-live\fR
|
||||||
|
Build a live pxe boot squashfs image
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-make\-ostree\-live\fR
|
||||||
|
Build a live pxe boot squashfs image of Atomic Host
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-iso ISO\fR
|
\fB\-\-iso ISO\fR
|
||||||
Anaconda installation .iso path to use for virt-install
|
Anaconda installation .iso path to use for virt-install
|
||||||
|
26
docs/rhel-atomic-pxe-live.ks
Normal file
26
docs/rhel-atomic-pxe-live.ks
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Settings for unattended installation:
|
||||||
|
lang en_US.UTF-8
|
||||||
|
keyboard us
|
||||||
|
timezone America/New_York
|
||||||
|
zerombr
|
||||||
|
clearpart --all --initlabel
|
||||||
|
rootpw --plaintext atomic
|
||||||
|
network --bootproto=dhcp --device=link --activate
|
||||||
|
|
||||||
|
# We are only able to install atomic with separate /boot partition currently
|
||||||
|
part / --fstype="ext4" --size=6000
|
||||||
|
part /boot --size=500 --fstype="ext4"
|
||||||
|
|
||||||
|
shutdown
|
||||||
|
|
||||||
|
services --disabled=cloud-init,cloud-init-local,cloud-final,cloud-config,docker-storage-setup
|
||||||
|
|
||||||
|
# Using ostree repo included in installation iso. Respective ostreesetup command is included here.
|
||||||
|
# The included kickstart file with the command is created during installation iso compose.
|
||||||
|
%include /usr/share/anaconda/interactive-defaults.ks
|
||||||
|
|
||||||
|
# We copy content of separate /boot partition to root part when building live squashfs image,
|
||||||
|
# and we don't want systemd to try to mount it when pxe booting
|
||||||
|
%post
|
||||||
|
cat /dev/null > /etc/fstab
|
||||||
|
%end
|
3
share/pxe-live/pxe-config.tmpl
Normal file
3
share/pxe-live/pxe-config.tmpl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# PXE configuration template generated by livemedia-creator
|
||||||
|
kernel <PXE_DIR>${kernel}
|
||||||
|
append initrd=<PXE_DIR>${initrd} root=live:<URL>/${liveimg} ${addargs}
|
@ -82,6 +82,30 @@ def mksquashfs(rootdir, outfile, compression="default", compressargs=[]):
|
|||||||
compressargs = ["-comp", compression] + compressargs
|
compressargs = ["-comp", compression] + compressargs
|
||||||
return execWithRedirect("mksquashfs", [rootdir, outfile] + compressargs)
|
return execWithRedirect("mksquashfs", [rootdir, outfile] + compressargs)
|
||||||
|
|
||||||
|
def mkrootfsimg(rootdir, outfile, label, size=2, sysroot=""):
|
||||||
|
"""
|
||||||
|
Make rootfs image from a directory
|
||||||
|
|
||||||
|
:param str rootdir: Root directory
|
||||||
|
:param str outfile: Path of output image file
|
||||||
|
:param str label: Filesystem label
|
||||||
|
:param int size: Size of the image, if None computed automatically
|
||||||
|
:param str sysroot: path to system (deployment) root relative to physical root
|
||||||
|
"""
|
||||||
|
if size:
|
||||||
|
fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin'
|
||||||
|
else:
|
||||||
|
fssize = None # Let mkext4img figure out the needed size
|
||||||
|
|
||||||
|
mkext4img(rootdir, outfile, label=label, size=fssize)
|
||||||
|
# Reset selinux context on new rootfs
|
||||||
|
with LoopDev(outfile) as loopdev:
|
||||||
|
with Mount(loopdev) as mnt:
|
||||||
|
cmd = [ "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/install",
|
||||||
|
"/etc/selinux/targeted/contexts/files/file_contexts", "/"]
|
||||||
|
root = join(mnt, sysroot.lstrip("/"))
|
||||||
|
runcmd(cmd, root=root)
|
||||||
|
|
||||||
######## Utility functions ###############################################
|
######## Utility functions ###############################################
|
||||||
|
|
||||||
def mksparse(outfile, size):
|
def mksparse(outfile, size):
|
||||||
|
@ -155,20 +155,10 @@ class RuntimeBuilder(object):
|
|||||||
def create_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=[], size=2):
|
def create_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=[], size=2):
|
||||||
# make live rootfs image - must be named "LiveOS/rootfs.img" for dracut
|
# make live rootfs image - must be named "LiveOS/rootfs.img" for dracut
|
||||||
workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir")
|
workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir")
|
||||||
if size:
|
|
||||||
fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin'
|
|
||||||
else:
|
|
||||||
fssize = None # Let mkext4img figure out the needed size
|
|
||||||
os.makedirs(joinpaths(workdir, "LiveOS"))
|
os.makedirs(joinpaths(workdir, "LiveOS"))
|
||||||
imgutils.mkext4img(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"),
|
|
||||||
label="Anaconda", size=fssize)
|
|
||||||
|
|
||||||
# Reset selinux context on new rootfs
|
imgutils.mkrootfsimg(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"),
|
||||||
with imgutils.LoopDev( joinpaths(workdir, "LiveOS/rootfs.img") ) as loopdev:
|
"Anaconda", size=size)
|
||||||
with imgutils.Mount(loopdev) as mnt:
|
|
||||||
cmd = [ "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/install",
|
|
||||||
"/etc/selinux/targeted/contexts/files/file_contexts", "/"]
|
|
||||||
runcmd(cmd, root=mnt)
|
|
||||||
|
|
||||||
# squash the live rootfs and clean up workdir
|
# squash the live rootfs and clean up workdir
|
||||||
imgutils.mksquashfs(workdir, outfile, compression, compressargs)
|
imgutils.mksquashfs(workdir, outfile, compression, compressargs)
|
||||||
|
@ -37,6 +37,7 @@ import shutil
|
|||||||
import argparse
|
import argparse
|
||||||
import hashlib
|
import hashlib
|
||||||
import re
|
import re
|
||||||
|
import glob
|
||||||
|
|
||||||
# Use pykickstart to calculate disk image size
|
# Use pykickstart to calculate disk image size
|
||||||
from pykickstart.parser import KickstartParser
|
from pykickstart.parser import KickstartParser
|
||||||
@ -50,11 +51,12 @@ from mako.exceptions import text_error_template
|
|||||||
from pylorax import ArchData
|
from pylorax import ArchData
|
||||||
from pylorax.base import DataHolder
|
from pylorax.base import DataHolder
|
||||||
from pylorax.treebuilder import TreeBuilder, RuntimeBuilder, udev_escape
|
from pylorax.treebuilder import TreeBuilder, RuntimeBuilder, udev_escape
|
||||||
|
from pylorax.treebuilder import findkernels
|
||||||
from pylorax.sysutils import joinpaths, remove
|
from pylorax.sysutils import joinpaths, remove
|
||||||
from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach
|
from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach
|
||||||
from pylorax.imgutils import get_loop_name, dm_detach, mount, umount, Mount
|
from pylorax.imgutils import get_loop_name, dm_detach, mount, umount, Mount
|
||||||
from pylorax.imgutils import mksquashfs, mktar
|
from pylorax.imgutils import mksquashfs, mktar, mkrootfsimg
|
||||||
from pylorax.executils import execWithRedirect, execWithCapture
|
from pylorax.executils import execWithRedirect, execWithCapture, runcmd
|
||||||
|
|
||||||
# no-virt mode doesn't need libvirt, so make it optional
|
# no-virt mode doesn't need libvirt, so make it optional
|
||||||
try:
|
try:
|
||||||
@ -352,6 +354,22 @@ def is_image_mounted(disk_img):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def find_ostree_root(phys_root):
|
||||||
|
"""
|
||||||
|
Find root of ostree deployment
|
||||||
|
|
||||||
|
:param str phys_root: Path to physical root
|
||||||
|
:returns: Relative path of ostree deployment root
|
||||||
|
:rtype: str
|
||||||
|
:raise Exception: More than one deployment roots were found
|
||||||
|
"""
|
||||||
|
ostree_root = ""
|
||||||
|
ostree_sysroots = glob.glob(joinpaths(phys_root, "ostree/boot.0/*/*/0"))
|
||||||
|
if ostree_sysroots:
|
||||||
|
if len(ostree_sysroots) > 1:
|
||||||
|
raise Exception("Too many deployment roots found: %s" % ostree_sysroots)
|
||||||
|
ostree_root = os.path.relpath(ostree_sysroots[0], phys_root)
|
||||||
|
return ostree_root
|
||||||
|
|
||||||
class KernelInfo(object):
|
class KernelInfo(object):
|
||||||
"""
|
"""
|
||||||
@ -482,6 +500,99 @@ def make_runtime(opts, mount_dir, work_dir):
|
|||||||
log.info("Creating runtime")
|
log.info("Creating runtime")
|
||||||
rb.create_runtime(joinpaths(work_dir, RUNTIME), size=None)
|
rb.create_runtime(joinpaths(work_dir, RUNTIME), size=None)
|
||||||
|
|
||||||
|
def rebuild_initrds_for_live(opts, sys_root_dir, results_dir):
|
||||||
|
"""
|
||||||
|
Rebuild intrds for pxe live image (root=live:http://)
|
||||||
|
|
||||||
|
:param opts: options passed to livemedia-creator
|
||||||
|
:type opts: argparse options
|
||||||
|
:param str sys_root_dir: Path to root of the system
|
||||||
|
:param str results_dir: Path of directory for storing results
|
||||||
|
"""
|
||||||
|
if not opts.dracut_args:
|
||||||
|
dracut_args = DRACUT_DEFAULT
|
||||||
|
else:
|
||||||
|
dracut_args = []
|
||||||
|
for arg in opts.dracut_args:
|
||||||
|
dracut_args += arg.split(" ", 1)
|
||||||
|
log.info("dracut args = {0}".format(dracut_args))
|
||||||
|
|
||||||
|
dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + dracut_args
|
||||||
|
|
||||||
|
kdir = "boot"
|
||||||
|
if opts.ostree:
|
||||||
|
kernels_dir = glob.glob(joinpaths(sys_root_dir, "boot/ostree/*"))[0]
|
||||||
|
kdir = os.path.relpath(kernels_dir, sys_root_dir)
|
||||||
|
|
||||||
|
kernels = [kernel for kernel in findkernels(sys_root_dir, kdir)
|
||||||
|
if hasattr(kernel, "initrd")]
|
||||||
|
if not kernels:
|
||||||
|
raise Exception("No initrds found, cannot rebuild_initrds")
|
||||||
|
|
||||||
|
# Hush some dracut warnings. TODO: bind-mount proc in place?
|
||||||
|
open(joinpaths(sys_root_dir,"/proc/modules"),"w")
|
||||||
|
|
||||||
|
if opts.ostree:
|
||||||
|
# Dracut assumes to have some dirs in disk image
|
||||||
|
# /var/tmp for temp files
|
||||||
|
vartmp_dir = joinpaths(sys_root_dir, "var/tmp")
|
||||||
|
if not os.path.isdir(vartmp_dir):
|
||||||
|
os.mkdir(vartmp_dir)
|
||||||
|
# /root (maybe not fatal)
|
||||||
|
root_dir = joinpaths(sys_root_dir, "var/roothome")
|
||||||
|
if not os.path.isdir(root_dir):
|
||||||
|
os.mkdir(root_dir)
|
||||||
|
# /tmp (maybe not fatal)
|
||||||
|
tmp_dir = joinpaths(sys_root_dir, "sysroot/tmp")
|
||||||
|
if not os.path.isdir(tmp_dir):
|
||||||
|
os.mkdir(tmp_dir)
|
||||||
|
|
||||||
|
for kernel in kernels:
|
||||||
|
outfile = kernel.initrd.path + ".live"
|
||||||
|
log.info("rebuilding %s", outfile)
|
||||||
|
|
||||||
|
kver = kernel.version
|
||||||
|
|
||||||
|
cmd = dracut + [outfile, kver]
|
||||||
|
runcmd(cmd, root=sys_root_dir)
|
||||||
|
|
||||||
|
new_initrd_path = joinpaths(results_dir, os.path.basename(kernel.initrd.path))
|
||||||
|
shutil.move(joinpaths(sys_root_dir, outfile), new_initrd_path)
|
||||||
|
shutil.copy2(joinpaths(sys_root_dir, kernel.path), results_dir)
|
||||||
|
|
||||||
|
os.unlink(joinpaths(sys_root_dir,"/proc/modules"))
|
||||||
|
|
||||||
|
def create_pxe_config(template, images_dir, live_image_name, add_args = None):
|
||||||
|
"""
|
||||||
|
Create template for pxe to live configuration
|
||||||
|
|
||||||
|
:param str images_dir: Path of directory with images to be used
|
||||||
|
:param str live_image_name: Name of live rootfs image file
|
||||||
|
:param list add_args: Arguments to be added to initrd= pxe config
|
||||||
|
"""
|
||||||
|
|
||||||
|
add_args = add_args or []
|
||||||
|
|
||||||
|
kernels = [kernel for kernel in findkernels(images_dir, kdir="")
|
||||||
|
if hasattr(kernel, "initrd")]
|
||||||
|
if not kernels:
|
||||||
|
return
|
||||||
|
|
||||||
|
kernel = kernels[0]
|
||||||
|
|
||||||
|
add_args_str = " ".join(add_args)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = Template(filename=template).render(kernel=kernel.path,
|
||||||
|
initrd=kernel.initrd.path, liveimg=live_image_name,
|
||||||
|
addargs=add_args_str)
|
||||||
|
except Exception:
|
||||||
|
log.error(text_error_template().render())
|
||||||
|
raise
|
||||||
|
|
||||||
|
with open (joinpaths(images_dir, "PXE_CONFIG"), "w") as f:
|
||||||
|
f.write(result)
|
||||||
|
|
||||||
def make_livecd(opts, mount_dir, work_dir):
|
def make_livecd(opts, mount_dir, work_dir):
|
||||||
"""
|
"""
|
||||||
@ -543,6 +654,36 @@ def make_livecd(opts, mount_dir, work_dir):
|
|||||||
|
|
||||||
return work_dir
|
return work_dir
|
||||||
|
|
||||||
|
def mount_boot_part_over_root(img_mount):
|
||||||
|
"""
|
||||||
|
Mount boot partition to /boot of root fs mounted in img_mount
|
||||||
|
|
||||||
|
Used for OSTree so it finds deployment configurations on live rootfs
|
||||||
|
|
||||||
|
param img_mount: object with mounted disk image root partition
|
||||||
|
type img_mount: imgutils.PartitionMount
|
||||||
|
"""
|
||||||
|
root_dir = img_mount.mount_dir
|
||||||
|
is_boot_part = lambda dir: os.path.exists(dir+"/loader.0")
|
||||||
|
tmp_mount_dir = tempfile.mkdtemp()
|
||||||
|
sys_root = find_ostree_root(root_dir)
|
||||||
|
sysroot_boot_dir = None
|
||||||
|
for dev, _size in img_mount.loop_devices:
|
||||||
|
if dev is img_mount.mount_dev:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
mount("/dev/mapper/"+dev, mnt=tmp_mount_dir)
|
||||||
|
if is_boot_part(tmp_mount_dir):
|
||||||
|
umount(tmp_mount_dir)
|
||||||
|
sysroot_boot_dir = joinpaths(joinpaths(root_dir, sys_root), "boot")
|
||||||
|
mount("/dev/mapper/"+dev, mnt=sysroot_boot_dir)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
umount(tmp_mount_dir)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
log.debug("Looking for boot partition error: %s", e)
|
||||||
|
remove(tmp_mount_dir)
|
||||||
|
return sysroot_boot_dir
|
||||||
|
|
||||||
def novirt_install(opts, disk_img, disk_size, repo_url):
|
def novirt_install(opts, disk_img, disk_size, repo_url):
|
||||||
"""
|
"""
|
||||||
@ -742,6 +883,55 @@ def make_image(opts, ks):
|
|||||||
return disk_img
|
return disk_img
|
||||||
|
|
||||||
|
|
||||||
|
def make_live_images(opts, work_dir, root_dir, rootfs_image=None):
|
||||||
|
"""
|
||||||
|
Create live images from direcory or rootfs image
|
||||||
|
|
||||||
|
:param opts: options passed to livemedia-creator
|
||||||
|
:type opts: argparse options
|
||||||
|
:param str work_dir: Directory for storing results
|
||||||
|
:param str root_dir: Root directory of live filesystem tree
|
||||||
|
:param str rootfs_image: Path to live rootfs image to be used
|
||||||
|
:returns: Path of directory with created images
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
sys_root = ""
|
||||||
|
if opts.ostree:
|
||||||
|
sys_root = find_ostree_root(root_dir)
|
||||||
|
|
||||||
|
squashfs_root_dir = joinpaths(work_dir, "squashfs_root")
|
||||||
|
liveos_dir = joinpaths(squashfs_root_dir, "LiveOS")
|
||||||
|
os.makedirs(liveos_dir)
|
||||||
|
|
||||||
|
if rootfs_image:
|
||||||
|
rc = execWithRedirect("/bin/ln", [rootfs_image, joinpaths(liveos_dir, "rootfs.img")])
|
||||||
|
if rc != 0:
|
||||||
|
shutil.copy2(rootfs_image, joinpaths(liveos_dir, "rootfs.img"))
|
||||||
|
else:
|
||||||
|
log.info("Creating live rootfs image")
|
||||||
|
mkrootfsimg(root_dir, joinpaths(liveos_dir, "rootfs.img"), "LiveOS", size=None, sysroot=sys_root)
|
||||||
|
|
||||||
|
log.info("Packing live rootfs image")
|
||||||
|
add_pxe_args = []
|
||||||
|
live_image_name = "live-rootfs.squashfs.img"
|
||||||
|
mksquashfs(squashfs_root_dir,
|
||||||
|
joinpaths(work_dir, live_image_name),
|
||||||
|
opts.compression,
|
||||||
|
opts.compress_args)
|
||||||
|
|
||||||
|
remove(squashfs_root_dir)
|
||||||
|
|
||||||
|
log.info("Rebuilding initramfs for live")
|
||||||
|
rebuild_initrds_for_live(opts, joinpaths(root_dir, sys_root), work_dir)
|
||||||
|
|
||||||
|
if opts.ostree:
|
||||||
|
add_pxe_args.append("ostree=/%s" % sys_root)
|
||||||
|
template = joinpaths(opts.lorax_templates, "pxe-live/pxe-config.tmpl")
|
||||||
|
create_pxe_config(template, work_dir, live_image_name, add_pxe_args)
|
||||||
|
|
||||||
|
return work_dir
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(opts):
|
def setup_logging(opts):
|
||||||
# Setup logging to console and to logfile
|
# Setup logging to console and to logfile
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
@ -787,6 +977,11 @@ if __name__ == '__main__':
|
|||||||
help="Build an ami image" )
|
help="Build an ami image" )
|
||||||
action.add_argument( "--make-tar", action="store_true",
|
action.add_argument( "--make-tar", action="store_true",
|
||||||
help="Build a tar of the root filesystem" )
|
help="Build a tar of the root filesystem" )
|
||||||
|
action.add_argument( "--make-pxe-live", action="store_true",
|
||||||
|
help="Build a live pxe boot squashfs image" )
|
||||||
|
action.add_argument( "--make-ostree-live", action="store_true",
|
||||||
|
help="Build a live pxe boot squashfs image of Atomic Host" )
|
||||||
|
|
||||||
|
|
||||||
parser.add_argument( "--iso", type=os.path.abspath,
|
parser.add_argument( "--iso", type=os.path.abspath,
|
||||||
help="Anaconda installation .iso path to use for virt-install" )
|
help="Anaconda installation .iso path to use for virt-install" )
|
||||||
@ -969,6 +1164,12 @@ if __name__ == '__main__':
|
|||||||
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)
|
||||||
|
|
||||||
|
if opts.make_ostree_live:
|
||||||
|
opts.make_pxe_live = True
|
||||||
|
opts.ostree = True
|
||||||
|
else:
|
||||||
|
opts.ostree = False
|
||||||
|
|
||||||
tempfile.tempdir = opts.tmp
|
tempfile.tempdir = opts.tmp
|
||||||
disk_img = None
|
disk_img = None
|
||||||
|
|
||||||
@ -1048,6 +1249,31 @@ if __name__ == '__main__':
|
|||||||
make_appliance(opts.disk_image or disk_img, opts.app_name,
|
make_appliance(opts.disk_image or disk_img, opts.app_name,
|
||||||
opts.app_template, opts.app_file, networks, opts.ram,
|
opts.app_template, opts.app_file, networks, opts.ram,
|
||||||
opts.vcpus, opts.arch, opts.title, opts.project, opts.releasever)
|
opts.vcpus, opts.arch, opts.title, opts.project, opts.releasever)
|
||||||
|
elif opts.make_pxe_live:
|
||||||
|
work_dir = tempfile.mkdtemp()
|
||||||
|
log.info("working dir is {0}".format(work_dir))
|
||||||
|
|
||||||
|
if (opts.fs_image or opts.no_virt) and not opts.disk_image:
|
||||||
|
# Create pxe live images from a filesystem image
|
||||||
|
disk_img = opts.fs_image or disk_img
|
||||||
|
with Mount(disk_img, opts="loop") as mnt_dir:
|
||||||
|
result_dir = make_live_images(opts, work_dir, mnt_dir, rootfs_image=disk_img)
|
||||||
|
else:
|
||||||
|
# Create pxe live images from a partitioned disk image
|
||||||
|
disk_img = opts.disk_image or disk_img
|
||||||
|
is_root_part = None
|
||||||
|
if opts.ostree:
|
||||||
|
is_root_part = lambda dir: os.path.exists(dir+"/ostree/deploy")
|
||||||
|
with PartitionMount(disk_img, mount_ok=is_root_part) as img_mount:
|
||||||
|
if img_mount and img_mount.mount_dir:
|
||||||
|
try:
|
||||||
|
mounted_sysroot_boot_dir = None
|
||||||
|
if opts.ostree:
|
||||||
|
mounted_sysroot_boot_dir = mount_boot_part_over_root(img_mount)
|
||||||
|
result_dir = make_live_images(opts, work_dir, img_mount.mount_dir)
|
||||||
|
finally:
|
||||||
|
if mounted_sysroot_boot_dir:
|
||||||
|
umount(mounted_sysroot_boot_dir)
|
||||||
|
|
||||||
if opts.result_dir and result_dir:
|
if opts.result_dir and result_dir:
|
||||||
shutil.copytree( result_dir, opts.result_dir )
|
shutil.copytree( result_dir, opts.result_dir )
|
||||||
|
Loading…
Reference in New Issue
Block a user