From c16953797509bcc8c5db713d7dee8c797084a138 Mon Sep 17 00:00:00 2001 From: Benedek Nagy Date: Fri, 29 Mar 2024 11:50:46 -0700 Subject: [PATCH] action_utils: Add generic utils for managing podman containers Signed-off-by: Benedek Nagy [sunil: Rename methods] [sunil: yapf formatting] Signed-off-by: Sunil Mohan Adapa Reviewed-by: Sunil Mohan Adapa --- plinth/action_utils.py | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/plinth/action_utils.py b/plinth/action_utils.py index 4bf5a1a1b..c6286632b 100644 --- a/plinth/action_utils.py +++ b/plinth/action_utils.py @@ -487,3 +487,71 @@ def is_package_manager_busy(): return True except subprocess.CalledProcessError: return False + + +def podman_run(network_name, subnet, bridge_ip, host_port, container_port, + container_ip, volume_name, container_name, image_name, + extra_run_options=None, extra_network_options=None): + """Remove, recreate and run a podman container.""" + try: + service_stop(container_name) + subprocess.run(['podman', 'network', 'rm', '--force', network_name], + check=False) + finally: + network_create_command = [ + 'podman', 'network', 'create', '--driver', 'bridge', '--subnet', + subnet, '--gateway', bridge_ip, '--dns', bridge_ip, + '--interface-name', network_name, network_name + ] + if extra_network_options: + network_create_command.extend(extra_network_options) + # create bridge network + subprocess.run(network_create_command, check=True) + + run_command = [ + 'podman', + 'run', + '--detach', + # Only listen on localhost. This is to prevent + # exposing the host port to the internet + '--publish', + f'127.0.0.1:{host_port}:{container_port}', + '--network', + network_name, + '--ip', + container_ip, + '--volume', + f'{volume_name}:/var/www/html', + '--name', + container_name, + '--restart', + 'unless-stopped', + '--quiet', + # enable automatic updates + '--label', + 'io.containers.autoupdate=registry', + # If another container with the same name already + # exists, replace and remove it. + '--replace', + ] + (extra_run_options or []) + [image_name] + subprocess.run(run_command, check=True) + + systemd_content = subprocess.run( + ['podman', 'generate', 'systemd', '--new', container_name], + capture_output=True, check=True).stdout.decode() + pathlib.Path('/etc/systemd/system/' + '{container_name}.service').write_text( + systemd_content, encoding='utf-8') + service_daemon_reload() + + +def podman_uninstall(container_name, network_name, volume_name, image_name): + """Remove a podman container's components and systemd unit.""" + components = [('network', network_name), ('volume', volume_name), + ('image', image_name)] + for component in components: + subprocess.run(['podman', component[0], 'rm', component[1]], + check=True) + pathlib.Path('/etc/systemd/system/{container_name}.service').unlink( + missing_ok=True) + service_daemon_reload()