ansible_gentooimgr/gentooimgr/__main__.py

186 lines
9.6 KiB
Python

import os
import sys
import json
import argparse
import pathlib
import copy
import logging
try:
import coloredlogs
os.environ['COLOREDLOGS_LEVEL_STYLES'] = 'spam=22;debug=28;verbose=34;notice=220;warning=202;success=118,bold;error=124;critical=background=red'
except ImportError as e:
logging.log(logging.DEBUG, f"coloredlogs not available: {e}")
coloredlogs = None
from gentooimgr import LOG
import gentooimgr.common
import gentooimgr.config
import gentooimgr.configs
def main(args):
'''Gentoo Cloud Image Builder Utility'''
import gentooimgr.config
configjson = gentooimgr.config.determine_config(args)
prefix = args.temporary_dir
LOG.info(f'Gentoo Cloud Image Builder Utility {args.action}')
if args.action == "build":
import gentooimgr.builder
gentooimgr.builder.build(args, configjson)
elif args.action == "run":
import gentooimgr.run
gentooimgr.run.run(args, configjson)
elif args.action == "test":
# empty
import gentooimgr.test
elif args.action == "clean":
# empty
import gentooimgr.clean
elif args.action == "status":
import gentooimgr.status
gentooimgr.status.print_template(args, configjson)
elif args.action == "install":
import gentooimgr.install
gentooimgr.install.configure(args, configjson)
elif args.action == "command":
import gentooimgr.command
gentooimgr.command.command(configjson)
elif args.action == "chroot":
import gentooimgr.chroot
gentooimgr.chroot.chroot(path=args.mountpoint, shell="/bin/bash")
elif args.action == "unchroot":
import gentooimgr.chroot
gentooimgr.chroot.unchroot(path=args.mountpoint)
elif args.action == "shrink":
import gentooimgr.shrink
fname = gentooimgr.shrink.shrink(args, configjson, stamp=args.stamp)
print(f"Shrunken image at {fname}, {os.path.getsize(fname)}")
elif args.action == "kernel":
import gentooimgr.kernel
gentooimgr.kernel.build_kernel(args, configjson)
return 0
if __name__ == "__main__":
"""Gentoo Cloud Image Builder Utility"""
parser = argparse.ArgumentParser(prog="gentooimgr", description="Gentoo Image Builder Utility")
parser.add_argument("-c", "--config", nargs='?', type=pathlib.Path,
help="Path to a custom conf file")
parser.add_argument("--config-cloud", action="store_const", const="cloud.json", dest="config",
help="Use cloud init configuration")
parser.add_argument("--config-base", action="store_const", const="base.json", dest="config",
help="Use a minimal base Gentoo configuration")
parser.add_argument("-t", "--temporary-dir", nargs='?', type=pathlib.Path,
default=pathlib.Path(os.getcwd()), help="Path to temporary directory for downloading files")
parser.add_argument("-j", "--threads", type=int, default=gentooimgr.config.THREADS,
help="Number of threads to use for building and emerging software")
parser.add_argument("-l", "--loglevel", type=int, default=logging.INFO,
help="python logging level <= 50, INFO=20")
parser.add_argument("-y", "--days", type=int, default=7, # gentooimgr.config.DAYS
help="Number of days before the files are redownloaded")
parser.add_argument("-d", "--download-dir", type=pathlib.Path, default=os.getcwd(),
help="Path to the desired download directory (default: current)")
parser.add_argument("--openrc", dest="profile", action="store_const", const="openrc",
help="Select OpenRC as the Gentoo Init System")
parser.add_argument("--systemd", dest="profile", action="store_const", const="systemd",
help="Select SystemD as the Gentoo Init System")
parser.add_argument("-f", "--force", action="store_true",
help="Let action occur at potential expense of data loss or errors (applies to clean and cloud-cfg)")
parser.add_argument("--format", default="qcow2", help="Image format to generate, default qcow2")
parser.add_argument("--portage", default=None, type=pathlib.Path, nargs='?',
help="Extract the specified portage package onto the filesystem")
parser.add_argument("--stage3", default=None, type=pathlib.Path, nargs='?',
help="Extract the specified stage3 package onto the filesystem")
parser.add_argument("--kernel-dir", default="/usr/src/linux",
help="Where kernel is specified. By default uses the active linux kernel")
subparsers = parser.add_subparsers(help="gentooimgr actions", dest="action")
subparsers.required = True
# Build action
parser_build = subparsers.add_parser('build', help="Download and verify all the downloaded components for cloud image")
parser_build.add_argument("image", default=gentooimgr.config.GENTOO_IMG_NAME, type=str, nargs='?',
help="Specify the exact image (date) you want to build; ex: 20231112T170154Z. Defaults to downloading the latest image. If image exists, will automatically use that one instead of checking online.")
parser_build.add_argument("--size", default="12G", help="Size of image to build")
parser_build.add_argument("--no-verify", dest="verify", action="store_false", help="Do not verify downloaded iso")
parser_build.add_argument("--verify", dest="verify", action="store_true", default=True,
help="Verify downloaded iso")
parser_build.add_argument("--redownload", action="store_true", help="Overwrite downloaded files")
parser_run = subparsers.add_parser('run', help="Run a Gentoo Image in QEMU to process it into a cloud image")
parser_run.add_argument("--iso", default=None, type=pathlib.Path, nargs='?',
help="Mount the specified iso in qemu, should be reserved for live cd images")
parser_run.add_argument("image", default=gentooimgr.config.GENTOO_IMG_NAME,
type=pathlib.Path, nargs="?",
help="Run the specified image in qemu")
parser_run.add_argument("-m", "--mounts", nargs='+', default=[],
help="Path to iso files to mount into the running qemu instance")
parser_test = subparsers.add_parser('test', help="Test whether image is a legitamite cloud configured image")
parser_clean = subparsers.add_parser('clean', help="Remove all downloaded files")
# --force also applies to clean action
parser_status = subparsers.add_parser('status', help="Review information, downloaded images and configurations")
parser_install = subparsers.add_parser("install", help="Install Gentoo on a qemu guest. Defaults to "
"--config-base with --kernel-dist if the respective --config or --kernel options are not provided.")
parser_install.add_argument("--kernel-dist", action="store_true",
help="Use a distribution kernel in the installation. Overrides all other kernel options.")
parser_install.add_argument("--kernel-virtio", action="store_true", help="Include virtio support in non-dist kernels")
parser_install.add_argument("--kernel-g5", action="store_true", help="Include all kernel config options for PowerMac G5 compatibility")
parser_chroot = subparsers.add_parser("chroot", help="Bind mounts and enter chroot with shell on guest. Unmounts binds on shell exit")
parser_chroot.add_argument("mountpoint", nargs='?', default=gentooimgr.config.GENTOO_MOUNT,
help="Point to mount and run the chroot and shell")
parser_unchroot = subparsers.add_parser("unchroot", help="Unmounts chroot filesystems")
parser_unchroot.add_argument("mountpoint", nargs='?', default=gentooimgr.config.GENTOO_MOUNT,
help="Point to mount and run the chroot and shell")
parser_cmd = subparsers.add_parser('command', help="Handle bind mounts and run command(s) in guest chroot, then unmount binds")
parser_cmd.add_argument("cmds", nargs='*',
help="Commands to run (quote each command if more than one word, ie: \"grep 'foo'\" \"echo foo\")")
parser_shrink = subparsers.add_parser('shrink', help="Take a finalized Gentoo image and rearrange it for smaller size")
parser_shrink.add_argument("img", type=pathlib.Path, help="Image to shrink")
parser_shrink.add_argument("--stamp", nargs='?', default=None,
help="By default a timestamp will be added to the image name, otherwise provide "
"a hardcoded string to add to the image name. Result: gentoo-[stamp].img")
parser_kernel = subparsers.add_parser('kernel', help="Build the kernel based on configuration and optional --kernel-dist flag")
args = parser.parse_args()
assert args.loglevel < 59
if coloredlogs:
# https://pypi.org/project/coloredlogs/
coloredlogs.install(level=args.loglevel,
logger=LOG,
# %(asctime)s,%(msecs)03d %(hostname)s [%(process)d]
fmt='%(name)s %(levelname)s %(message)s'
)
else:
logging.basicConfig(level=args.loglevel) # logging.INFO
logging.basicConfig(level=args.loglevel)
isos = gentooimgr.common.find_iso(args.download_dir)
if args.action == "run" and args.iso is None and len(isos) > 1:
LOG.error(f"Error: multiple iso files were found in {args.download_dir}, please specify one using `--iso [iso]`")
sys.exit(1)
main(args)