From 5ae3924234f9ffaa2ffda7e9fc52c2b3518a85e2 Mon Sep 17 00:00:00 2001 From: opswill Date: Tue, 17 Jun 2025 23:02:07 +0800 Subject: container: T7473: fix show/monitor container log failed when log-driver is journald --- data/templates/container/containers.conf.j2 | 8 ---- interface-definitions/container.xml.in | 43 ++++++++++++---------- .../include/version/container-version.xml.i | 2 +- op-mode-definitions/container.xml.in | 7 ++-- smoketest/scripts/cli/test_container.py | 10 ++--- src/conf_mode/container.py | 3 +- src/migration-scripts/container/2-to-3 | 31 ++++++++++++++++ src/op_mode/container.py | 42 +++++++++++++++++++++ 8 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 src/migration-scripts/container/2-to-3 diff --git a/data/templates/container/containers.conf.j2 b/data/templates/container/containers.conf.j2 index 65436801e..414c3e849 100644 --- a/data/templates/container/containers.conf.j2 +++ b/data/templates/container/containers.conf.j2 @@ -170,14 +170,6 @@ default_sysctls = [ # #label = true -# Logging driver for the container. Available options: k8s-file and journald. -# -{% if log_driver is vyos_defined %} -log_driver = "{{ log_driver }}" -{% else %} -#log_driver = "k8s-file" -{% endif %} - # Maximum size allowed for the container log file. Negative numbers indicate # that no size limit is imposed. If positive, it must be >= 8192 to match or # exceed conmon's read buffer. The file is truncated and re-opened so the diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 434bf7528..f20fd7690 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -532,6 +532,30 @@ + + + Configure container log driver + + k8s-file journald none + + + k8s-file + Logs to plain-text file + + + journald + Logs to systemd's journal + + + none + Disable logging for the container + + + (k8s-file|journald|none) + + + journald + @@ -627,25 +651,6 @@ - - - Configure container log driver - - k8s-file journald - - - k8s-file - Logs to plain-text json file - - - journald - Logs to systemd's journal - - - (k8s-file|journald) - - - diff --git a/interface-definitions/include/version/container-version.xml.i b/interface-definitions/include/version/container-version.xml.i index ed6e942cd..046bacfdc 100644 --- a/interface-definitions/include/version/container-version.xml.i +++ b/interface-definitions/include/version/container-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/op-mode-definitions/container.xml.in b/op-mode-definitions/container.xml.in index df28a792c..70ab4b6e5 100644 --- a/op-mode-definitions/container.xml.in +++ b/op-mode-definitions/container.xml.in @@ -89,7 +89,7 @@ container name - podman logs --follow --names "$4" + ${vyos_op_scripts_dir}/container.py show_log --follow --name "$4" @@ -132,8 +132,7 @@ container name - - podman logs --names "$4" + ${vyos_op_scripts_dir}/container.py show_log --name "$4" @@ -162,7 +161,7 @@ container name - podman logs --names "$4" + ${vyos_op_scripts_dir}/container.py show_log --name "$4" diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py index daad3a909..892d7ae0b 100755 --- a/smoketest/scripts/cli/test_container.py +++ b/smoketest/scripts/cli/test_container.py @@ -95,7 +95,7 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): '4096', ] ) - + self.cli_set(base_path + ['name', cont_name, 'log-driver', 'journald']) # commit changes self.cli_commit() @@ -110,13 +110,9 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): tmp = cmd(f'sudo podman exec -it {cont_name} sysctl kernel.msgmax') self.assertEqual(tmp, 'kernel.msgmax = 4096') - def test_log_driver(self): - self.cli_set(base_path + ['log-driver', 'journald']) - - self.cli_commit() + l = cmd_to_json(f'sudo podman container inspect {cont_name}') + self.assertEqual(l['HostConfig']['LogConfig']['Type'], 'journald') - tmp = cmd('podman info --format "{{ .Host.LogDriver }}"') - self.assertEqual(tmp, 'journald') def test_name_server(self): cont_name = 'dns-test' diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 83e6dee11..a381ace5c 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -310,6 +310,7 @@ def generate_run_arguments(name, container_config): memory = container_config['memory'] shared_memory = container_config['shared_memory'] restart = container_config['restart'] + log_driver = container_config['log_driver'] # Add sysctl options sysctl_opt = '' @@ -408,7 +409,7 @@ def generate_run_arguments(name, container_config): name_server += f'--dns {ns}' container_base_cmd = f'--detach --interactive --tty --replace {capabilities} {privileged} --cpus {cpu_quota} {sysctl_opt} ' \ - f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \ + f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} --log-driver={log_driver} ' \ f'--name {name} {hostname} {device} {port} {name_server} {volume} {tmpfs} {env_opt} {label} {uid} {host_pid}' entrypoint = '' diff --git a/src/migration-scripts/container/2-to-3 b/src/migration-scripts/container/2-to-3 new file mode 100644 index 000000000..54c6ec4c8 --- /dev/null +++ b/src/migration-scripts/container/2-to-3 @@ -0,0 +1,31 @@ +# Copyright 2024 VyOS maintainers and contributors +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T7473: container: allow log-driver to be set per container + +from vyos.configtree import ConfigTree + +def migrate(config: ConfigTree) -> None: + log_base = ['container', 'log-driver'] + container_base = ['container', 'name'] + + if not config.exists(log_base): + return + else: + log_driver = config.return_value(log_base) + for container in config.list_nodes(container_base): + # Set the log-driver for each container + config.set(container_base + [container, 'log-driver'], value=log_driver) + config.delete(log_base) diff --git a/src/op_mode/container.py b/src/op_mode/container.py index 05f65df1f..f93df0fc4 100755 --- a/src/op_mode/container.py +++ b/src/op_mode/container.py @@ -16,6 +16,7 @@ import json import sys +import subprocess from vyos.utils.process import cmd from vyos.utils.process import rc_cmd @@ -109,6 +110,47 @@ def restart(name: str): print(f'Container "{name}" restarted!') return output +def show_log(name: str, follow: bool = False, raw: bool = False): + """ + Show or monitor logs for a specific container. + Use --follow to continuously stream logs. + """ + from vyos.configquery import ConfigTreeQuery + conf = ConfigTreeQuery() + container = conf.get_config_dict(['container', 'name', name], get_first_key=True, with_recursive_defaults=True) + log_type = container.get('log-driver') + if log_type == 'k8s-file': + if follow: + log_command_list = ['sudo', 'podman', 'logs', '--follow', '--names', name] + else: + log_command_list = ['sudo', 'podman', 'logs', '--names', name] + elif log_type == 'journald': + if follow: + log_command_list = ['journalctl', '--follow', '--unit', f'vyos-container-{name}.service'] + else: + log_command_list = ['journalctl', '-e', '--no-pager', '--unit', f'vyos-container-{name}.service'] + elif log_type == 'none': + print(f'Container "{name}" has disabled logs.') + return None + else: + raise vyos.opmode.InternalError(f'Unknown log type "{log_type}" for container "{name}".') + + process = None + try: + process = subprocess.Popen(log_command_list, + stdout=sys.stdout, + stderr=sys.stderr) + process.wait() + except KeyboardInterrupt: + if process: + process.terminate() + process.wait() + return None + except Exception as e: + raise vyos.opmode.InternalError(f"Error starting logging command: {e} ") + return None + + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) -- cgit v1.2.3