2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-22 09:32:21 +00:00

Begin migration of imgutil to argparse

We no longer support python 2.6, we can use argparse for better subcommand handling.
This commit is contained in:
Jarrod Johnson 2021-08-11 17:01:32 -04:00
parent 865021beff
commit 8a8e9718f9

View File

@ -5,7 +5,7 @@ import ctypes.util
from distutils.dir_util import copy_tree
import glob
import json
import optparse
import argparse
import os
import pwd
import re
@ -541,22 +541,37 @@ def run_constrained(function, args):
def main():
parser = optparse.OptionParser()
parser.add_option('-s', '--source', help='Directory to pull installation '
'from (e.g. /var/lib/confluent/distributions/rocky-8.3-x86_64')
parser.add_option(
'-v', '--volume',
parser = argparse.ArgumentParser(description='Work with confluent OS images')
sps = parser.add_subparsers(dest='subcommand')
buildp = sps.add_parser('build', help='Build a new diskless image from scratch')
buildp.add_argument('--source', help='Directory to pull installation from, typically a subdirectory of /var/lib/confluent/distributions. By default, the repositories for the build system are used.')
buildp.add_argument('scratchdir', help='Directory to build new diskless root in')
execp = sps.add_parser('exec', help='Start specified scratch directory as container')
execp.add_argument('--volume',
help='Directory to make available in install environment. -v / will '
'cause it to be mounted in image as /run/external/, -v /:/run/root '
'will override the target to be /run/root', action='append')
(opts, args) = parser.parse_args()
if not args:
execp.add_argument('scratchdir', help='Directory of an unpacked diskless root')
unpackp = sps.add_parser('unpack', help='Unpack a diskless image to a scratch directory')
unpackp.add_argument('profilename', help='The diskless OS profile to unpack')
unpackp.add_argument('scratchdir', help='Directory to extract diskless root to')
packp = sps.add_parser('pack', help='Pack a scratch directory to a diskless profile')
packp.add_argument('scratchdir', help='Directory containing diskless root')
packp.add_argument('profilename', help='The desired diskless OS profile name to pack the root into')
args = parser.parse_args()
if not args or not args.subcommand:
parser.print_usage()
sys.exit(1)
if args[0] == 'build':
if args.subcommand == 'build':
build_root(opts, args[1:])
elif args[0] == 'capture':
elif args.subcommand == 'capture':
capture_remote(opts, args[1:])
elif args.subcommand == 'unpack':
unpack_image(args)
elif args.subcommand == 'exec':
exec_root(args)
elif args.subcommand == 'pack':
pack_image(args)
elif args[0] == 'getfingerprint':
print(fingerprint_host().get_json())
elif args[0] == 'capturelocal':
@ -565,12 +580,7 @@ def main():
build_boot_tree('/run/imgutil/capout')
elif args[0] == 'capturelocalcleanup':
capture_local_cleanup()
elif args[0] == 'exec':
exec_root(opts, args[1:])
elif args[0] == 'pack':
pack_image(opts, args[1:])
elif args[0] == 'unpack':
unpack_image(opts, args[1:])
else:
parser.print_usage()
@ -619,20 +629,20 @@ def _mount(src, dst, fstype=0, flags=0, options=0, mode=None):
def build_root_backend(optargs):
opts, args, oshandler = optargs
installroot = args[0]
_mount_constrained_fs(opts, installroot)
args, oshandler = optargs
installroot = args.scratchdir
_mount_constrained_fs(args, installroot)
oshandler.prep_root()
def _mount_constrained_fs(opts, installroot):
def _mount_constrained_fs(args, installroot):
_mount('/dev', os.path.join(installroot, 'dev'), flags=MS_BIND|MS_RDONLY)
_mount('proc', os.path.join(installroot, 'proc'), fstype='proc')
_mount('sys', os.path.join(installroot, 'sys'), fstype='sysfs')
_mount('runfs', os.path.join(installroot, 'run'), fstype='tmpfs')
if opts.volume is None:
opts.volume = []
for v in opts.volume:
if args.volume is None:
args.volume = []
for v in args.volume:
if ':' in v:
src, dst = v.split(':')
while dst and dst[0] == '/':
@ -758,29 +768,29 @@ def fingerprint_host(hostpath='/'):
return oshandler
return oshandler
def build_root(opts, args):
check_root(args[0])
yumargs = ['yum', '--installroot={0}'.format(args[0])]
if opts.source:
if '/' not in opts.source and not os.path.exists(opts.source):
opts.source = os.path.join('/var/lib/confluent/distributions/', opts.source)
oshandler = fingerprint_source(opts.source)
def build_root(args):
check_root(args.scratchdir)
yumargs = ['yum', '--installroot={0}'.format(args.scratchdir)]
if args.source:
if '/' not in args.source and not os.path.exists(args.source):
args.source = os.path.join('/var/lib/confluent/distributions/', args.source)
oshandler = fingerprint_source(args.source)
if oshandler is not None:
oshandler.set_source(opts.source)
oshandler.set_source(args.source)
else:
oshandler = fingerprint_host()
if oshandler is None:
sys.stderr.write(
'Unable to recognize source directory {0}\n'.format(
opts.source))
args.source))
sys.exit(1)
oshandler.set_target(args[0])
oshandler.set_target(args.scratchdir)
oshandler.add_pkglists()
for dirname in ('proc', 'sys', 'dev', 'run'):
mkdirp(os.path.join(args[0], dirname))
run_constrained(build_root_backend, (opts, args, oshandler))
if len(args) > 1:
pack_image(opts, args)
mkdirp(os.path.join(args.scratchdir, dirname))
run_constrained(build_root_backend, (args, oshandler))
#if len(args) > 1:
# pack_image(opts, args)
def prep_decrypt(indir):
indir = os.path.abspath(indir)
@ -816,9 +826,9 @@ def prep_decrypt(indir):
return '/dev/mapper/{0}'.format(dmname)
def unpack_image(opts, args):
scratchdir = args[1]
indir = args[0]
def unpack_image(args):
scratchdir = args.scratchdir
indir = args.profilename
if not os.path.exists(indir) and '/' not in indir:
indir = os.path.join('/var/lib/confluent/public/os', indir)
if os.path.isdir(indir):
@ -846,22 +856,22 @@ def unpack_image(opts, args):
subprocess.check_call(['dmsetup', 'remove', cleandmtable])
def pack_image(opts, args):
outdir = args[1]
def pack_image(profile):
outdir = profile
if '/' in outdir:
raise Exception('Full path not supported, supply only the profile name')
privdir = os.path.join('/var/lib/confluent/private/os/', outdir)
outdir = os.path.join('/var/lib/confluent/public/os/', outdir)
kerns = glob.glob(os.path.join(args[0], 'boot/vmlinuz-*'))
kerns = glob.glob(os.path.join(profile, 'boot/vmlinuz-*'))
kvermap = {}
for kern in kerns:
if 'rescue' in kern:
continue
kvermap[get_kern_version(kern)] = kern
mostrecent = list(version_sort(kvermap))[-1]
initrdname = os.path.join(args[0], 'boot/initramfs-{0}.img'.format(mostrecent))
initrdname = os.path.join(profile, 'boot/initramfs-{0}.img'.format(mostrecent))
if not os.path.exists(initrdname):
initrdname = os.path.join(args[0], 'boot/initrd-{0}'.format(mostrecent))
initrdname = os.path.join(profile, 'boot/initrd-{0}'.format(mostrecent))
oum = os.umask(0o077)
for path in ('/var/lib/confluent', '/var/lib/confluent/private', '/var/lib/confluent/private/os'):
if not os.path.exists(path):
@ -877,25 +887,25 @@ def pack_image(opts, args):
os.path.join(outdir, 'boot/initramfs/site.cpio'))
shutil.copyfile(kvermap[mostrecent], os.path.join(outdir, 'boot/kernel'))
shutil.copyfile(initrdname, os.path.join(outdir, 'boot/initramfs/distribution'))
gather_bootloader(outdir, args[0])
gather_bootloader(outdir, profile)
tmploc = tempfile.mktemp()
subprocess.check_call(['mksquashfs', args[0],
subprocess.check_call(['mksquashfs', profile,
tmploc, '-comp', 'xz'])
encrypt_image(tmploc, os.path.join(outdir, 'rootimg.sfs'), '{}/pending/rootimg.key'.format(privdir))
os.remove(tmploc)
oshandler = fingerprint_host(args[0])
oshandler = fingerprint_host(profile)
tryupdate = False
if oshandler:
prettyname = oshandler.osname
with open(os.path.join(args[0], 'etc/os-release')) as osr:
with open(os.path.join(profile, 'etc/os-release')) as osr:
osrdata = osr.read().split('\n')
for line in osrdata:
if line.startswith('PRETTY_NAME="'):
prettyname = line.replace(
'PRETTY_NAME=', '').replace('"', '')
label = '{0} ({1})'.format(prettyname, 'Diskless Boot')
with open(os.path.join(outdir, 'profile.yaml'), 'w') as profile:
profile.write('label: {0}\nkernelargs: quiet # confluent_imagemethod=untethered|tethered\n'.format(label))
with open(os.path.join(outdir, 'profile.yaml'), 'w') as profiley:
profiley.write('label: {0}\nkernelargs: quiet # confluent_imagemethod=untethered|tethered\n'.format(label))
oscat = oshandler.oscategory
confdir = '/opt/confluent/lib/osdeploy/{}-diskless'.format(oscat)
os.symlink('{}/initramfs/addons.cpio'.format(confdir),