diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/container.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/vrf.py | 7 | ||||
-rw-r--r-- | src/migration-scripts/container/2-to-3 | 31 | ||||
-rw-r--r-- | src/migration-scripts/firewall/18-to-19 | 35 | ||||
-rw-r--r-- | src/migration-scripts/quagga/8-to-9 | 18 | ||||
-rwxr-xr-x | src/op_mode/container.py | 42 | ||||
-rw-r--r-- | src/tests/test_template.py | 4 |
7 files changed, 134 insertions, 6 deletions
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/conf_mode/vrf.py b/src/conf_mode/vrf.py index 8baf55857..6e9d4147a 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -18,6 +18,8 @@ from sys import exit from jmespath import search from json import loads +import vyos.defaults + from vyos.config import Config from vyos.configdict import node_changed from vyos.configverify import verify_route_map @@ -163,6 +165,11 @@ def verify(vrf): if 'table' not in vrf_config: raise ConfigError(f'VRF "{name}" table id is mandatory!') + if int(vrf_config['table']) == vyos.defaults.rt_global_vrf: + raise ConfigError( + f'VRF "{name}" table id {vrf_config["table"]} cannot be used!' + ) + # routing table id can't be changed - OS restriction if interface_exists(name): tmp = get_vrf_tableid(name) 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 <maintainers@vyos.io> +# +# 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 <http://www.gnu.org/licenses/>. + +# 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/migration-scripts/firewall/18-to-19 b/src/migration-scripts/firewall/18-to-19 new file mode 100644 index 000000000..3564e0e01 --- /dev/null +++ b/src/migration-scripts/firewall/18-to-19 @@ -0,0 +1,35 @@ +# Copyright (C) 2024-2025 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 <http://www.gnu.org/licenses/>. + +# From +# set firewall global-options apply-to-bridged-traffic invalid-connections +# To +# set firewall global-options apply-to-bridged-traffic accept-invalid ethernet-type <ethertype> + +from vyos.configtree import ConfigTree + +base = ['firewall', 'global-options', 'apply-to-bridged-traffic'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base + ['invalid-connections']): + # Nothing to do + return + + ether_types = ['dhcp', 'arp', 'pppoe-discovery', 'pppoe', '802.1q', '802.1ad', 'wol'] + + for ether_type in ether_types: + config.set(base + ['accept-invalid', 'ethernet-type'], value=ether_type, replace=False) + + config.delete(base + ['invalid-connections']) diff --git a/src/migration-scripts/quagga/8-to-9 b/src/migration-scripts/quagga/8-to-9 index eece6c15d..c28e07e5c 100644 --- a/src/migration-scripts/quagga/8-to-9 +++ b/src/migration-scripts/quagga/8-to-9 @@ -16,6 +16,7 @@ # - T2450: drop interface-route and interface-route6 from "protocols static" from vyos.configtree import ConfigTree +from vyos.template import is_ip def migrate_interface_route(config, base, path, route_route6): """ Generic migration function which can be called on every instance of @@ -31,11 +32,18 @@ def migrate_interface_route(config, base, path, route_route6): tmp = base + path + [route, 'next-hop-interface'] for interface in config.list_nodes(tmp): - new_base = base + [route_route6, route, 'interface'] - config.set(new_base) - config.set_tag(base + [route_route6]) - config.set_tag(new_base) - config.copy(tmp + [interface], new_base + [interface]) + if is_ip(interface): # not prohibited in 1.3.x, hence allowed + new_base = base + [route_route6, route, 'next-hop'] + config.set(new_base) + config.set_tag(base + [route_route6]) + config.set_tag(new_base) + config.copy(tmp + [interface], new_base + [interface]) + else: + new_base = base + [route_route6, route, 'interface'] + config.set(new_base) + config.set_tag(base + [route_route6]) + config.set_tag(new_base) + config.copy(tmp + [interface], new_base + [interface]) config.delete(base + path) 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__]) diff --git a/src/tests/test_template.py b/src/tests/test_template.py index 4660c0038..09315d398 100644 --- a/src/tests/test_template.py +++ b/src/tests/test_template.py @@ -199,8 +199,12 @@ class TestVyOSTemplate(TestCase): vyos.template.get_default_config_file('UNKNOWN') with self.assertRaises(RuntimeError): vyos.template.get_default_port('UNKNOWN') + with self.assertRaises(RuntimeError): + vyos.template.nft_accept_invalid('UNKNOWN') self.assertEqual(vyos.template.get_default_config_file('sshd_user_ca'), config_files['sshd_user_ca']) self.assertEqual(vyos.template.get_default_port('certbot_haproxy'), internal_ports['certbot_haproxy']) + self.assertEqual(vyos.template.nft_accept_invalid('arp'), + 'ct state invalid ether type arp counter accept') |