diff --git a/TODO b/TODO index 9d87db7d573bc49c63dcbf36b2786d3f33d6d641..33132311fe6d4510b82660757a12470a48de3635 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ -- more colors -- "shc CONTAINER start" vs. "shc CONTAINER shell" - Albireo cleanup: - prerouting rule - containers diff --git a/shipcat/main.py b/shipcat/main.py index 9d17d343bef0bb82efc8652526746e6caa3ef8f2..fa7f0187bb4bf5a00a6e0c213b36e09eac070f75 100755 --- a/shipcat/main.py +++ b/shipcat/main.py @@ -11,13 +11,13 @@ import sys from typing import List, Optional from shipcat.config import GlobalConfig, ContainerConfig, ConfigError -from shipcat.util import die, verbose, set_verbose, run_command +from shipcat.util import die, progress, verbose, set_verbose, run_command config: GlobalConfig -def progress(msg: str) -> None: +def trace(msg: str) -> None: print(msg, file=sys.stderr, end="", flush=True) @@ -107,68 +107,68 @@ def cmd_init(args: argparse.Namespace) -> None: name = args.name cc = setup_container(args, True) - progress(f'User {cc.user_name}: ') + trace(f'User {cc.user_name}: ') try: pwd = getpwnam(cc.user_name) - progress('already exists\n') + trace('already exists\n') except KeyError: - progress('creating\n') + trace('creating\n') run_command( ['adduser', '--system', '--group', '--gecos', f'Container {name}', '--disabled-password', cc.user_name] ) pwd = getpwnam(cc.user_name) uid = pwd.pw_uid - progress('Subuid range: ') + trace('Subuid range: ') subuids = SubIds('/etc/subuid') sur = subuids.find_range(uid, cc.user_name, 65536) if sur is not None: - progress('already exists\n') + trace('already exists\n') else: - progress('allocating\n') + trace('allocating\n') sur = subuids.alloc_range(cc.user_name, 65536) run_command( ['usermod', '--add-subuids', f'{sur.first}-{sur.first + sur.count - 1}', cc.user_name] ) - progress('Subgid range: ') + trace('Subgid range: ') subgids = SubIds('/etc/subgid') sgr = subgids.find_range(uid, cc.user_name, 65536) if sgr is not None: - progress('already exists\n') + trace('already exists\n') else: - progress('allocating\n') + trace('allocating\n') sgr = subgids.alloc_range(cc.user_name, 65536) run_command( ['usermod', '--add-subgids', f'{sgr.first}-{sgr.first + sgr.count - 1}', cc.user_name] ) - progress(f'Using user {cc.user_name}, uid {uid}, subuids {sur.first}+{sur.count}, subgids {sgr.first}+{sgr.count}\n') + trace(f'Using user {cc.user_name}, uid {uid}, subuids {sur.first}+{sur.count}, subgids {sgr.first}+{sgr.count}\n') root_path = cc.root_path - progress(f'Container directory {root_path}: ') + trace(f'Container directory {root_path}: ') if root_path.is_dir(): - progress('already exists\n') + trace('already exists\n') else: root_path.mkdir(mode=0o750, exist_ok=True) os.chown(root_path, 0, sgr.first) - progress('created\n') + trace('created\n') data_path = cc.data_path - progress(f'Data directory {data_path}: ') + trace(f'Data directory {data_path}: ') if data_path.is_dir(): - progress('already exists\n') + trace('already exists\n') else: data_path.mkdir(mode=0o755, exist_ok=True) os.chown(data_path, sur.first, sgr.first) - progress('created\n') + trace('created\n') - progress('IP address: ') + trace('IP address: ') try: ip = socket.gethostbyname(name) except OSError as e: die(str(e)) - progress(f'{ip}\n') + trace(f'{ip}\n') def service_action(cc: ContainerConfig, action: str) -> None: @@ -177,16 +177,23 @@ def service_action(cc: ContainerConfig, action: str) -> None: ) -def cmd_create(args: argparse.Namespace) -> None: +def cmd_update(args: argparse.Namespace) -> None: cc = setup_container(args, False) + progress('Pulling new image') run_command( ['podman', 'pull', cc.image] ) + progress('Stopping container') service_action(cc, 'stop') + + progress('Creating container') create_container(cc) + progress('Starting container') + service_action(cc, 'start') + def create_container(cc: ContainerConfig) -> None: ip = socket.gethostbyname(cc.name) @@ -343,9 +350,6 @@ def main() -> None: parser.add_argument('--verbose', '-v', default=False, action='store_true', help='be chatty and explain what is going on') subparsers = parser.add_subparsers(help='action to perform', dest='action', required=True, metavar='ACTION') - create_parser = subparsers.add_parser('create', help='create a container from an image', description='Create a container from an image.') - create_parser.add_argument('name', help='name of the container') - create_parser = subparsers.add_parser('disable', help='disable automatic startup of a container', description='Disable automatic startup of a container.') create_parser.add_argument('name', help='name of the container') @@ -385,10 +389,12 @@ def main() -> None: stop_parser = subparsers.add_parser('stop', help='stop a container', description='Stop a container') stop_parser.add_argument('name', help='name of the container') + update_parser = subparsers.add_parser('update', help='update a container from an image', description='Update a container from an image and start it.') + update_parser.add_argument('name', help='name of the container') + args = parser.parse_args() actions = { - 'create': cmd_create, 'disable': cmd_disable, 'enable': cmd_enable, 'exec': cmd_exec, @@ -399,6 +405,7 @@ def main() -> None: 'start': cmd_start, 'status': cmd_status, 'stop': cmd_stop, + 'update': cmd_update, } global config