186 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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)
 |