diff options
-rw-r--r-- | interface-definitions/container.xml.in | 4 | ||||
-rw-r--r-- | interface-definitions/include/version/container-version.xml.i | 2 | ||||
-rw-r--r-- | smoketest/config-tests/container-simple | 12 | ||||
-rw-r--r-- | smoketest/configs/container-simple | 46 | ||||
-rwxr-xr-x | src/conf_mode/container.py | 13 | ||||
-rwxr-xr-x | src/conf_mode/service_dhcp-server.py | 1 | ||||
-rwxr-xr-x | src/migration-scripts/container/1-to-2 | 50 | ||||
-rwxr-xr-x | src/migration-scripts/ipoe-server/1-to-2 | 67 |
8 files changed, 149 insertions, 46 deletions
diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 7e1f4811a..94f2e92f5 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -21,9 +21,9 @@ <valueless/> </properties> </leafNode> - <leafNode name="cap-add"> + <leafNode name="capability"> <properties> - <help>Container capabilities/permissions</help> + <help>Grant individual Linux capability to container instance</help> <completionHelp> <list>net-admin net-bind-service net-raw setpcap sys-admin sys-module sys-time</list> </completionHelp> diff --git a/interface-definitions/include/version/container-version.xml.i b/interface-definitions/include/version/container-version.xml.i index 129469cec..ed6e942cd 100644 --- a/interface-definitions/include/version/container-version.xml.i +++ b/interface-definitions/include/version/container-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/container-version.xml.i --> -<syntaxVersion component='container' version='1'></syntaxVersion> +<syntaxVersion component='container' version='2'></syntaxVersion> <!-- include end --> diff --git a/smoketest/config-tests/container-simple b/smoketest/config-tests/container-simple new file mode 100644 index 000000000..299af64cb --- /dev/null +++ b/smoketest/config-tests/container-simple @@ -0,0 +1,12 @@ +set system config-management commit-revisions '50' +set system host-name 'vyos' +set system login user vyos authentication encrypted-password '$6$r/Yw/07NXNY$/ZB.Rjf9jxEV.BYoDyLdH.kH14rU52pOBtrX.4S34qlPt77chflCHvpTCq9a6huLzwaMR50rEICzA5GoIRZlM0' +set system login user vyos authentication plaintext-password '' +set system console device ttyS0 speed '115200' +set container name c01 allow-host-networks +set container name c01 capability 'net-bind-service' +set container name c01 capability 'net-raw' +set container name c01 image 'busybox:stable' +set container name c02 allow-host-networks +set container name c02 capability 'sys-time' +set container name c02 image 'busybox:stable' diff --git a/smoketest/configs/container-simple b/smoketest/configs/container-simple new file mode 100644 index 000000000..05efe05e9 --- /dev/null +++ b/smoketest/configs/container-simple @@ -0,0 +1,46 @@ +container { + name c01 { + allow-host-networks + cap-add net-bind-service + cap-add net-raw + image busybox:stable + } + name c02 { + allow-host-networks + cap-add sys-time + image busybox:stable + } +} +interfaces { + ethernet eth0 { + duplex auto + speed auto + } + ethernet eth1 { + duplex auto + speed auto + } +} +system { + config-management { + commit-revisions 50 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$r/Yw/07NXNY$/ZB.Rjf9jxEV.BYoDyLdH.kH14rU52pOBtrX.4S34qlPt77chflCHvpTCq9a6huLzwaMR50rEICzA5GoIRZlM0 + plaintext-password "" + } + } + } +} + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:container@1:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@23:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3.6 diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 910a92a7c..0b57221b2 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -262,12 +262,11 @@ def generate_run_arguments(name, container_config): restart = container_config['restart'] # Add capability options. Should be in uppercase - cap_add = '' - if 'cap_add' in container_config: - for c in container_config['cap_add']: - c = c.upper() - c = c.replace('-', '_') - cap_add += f' --cap-add={c}' + capabilities = '' + if 'capability' in container_config: + for cap in container_config['capability']: + cap = cap.upper().replace('-', '_') + capabilities += f' --cap-add={cap}' # Add a host device to the container /dev/x:/dev/x device = '' @@ -330,7 +329,7 @@ def generate_run_arguments(name, container_config): prop = vol_config['propagation'] volume += f' --volume {svol}:{dvol}:{mode},{prop}' - container_base_cmd = f'--detach --interactive --tty --replace {cap_add} ' \ + container_base_cmd = f'--detach --interactive --tty --replace {capabilities} ' \ f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \ f'--name {name} {hostname} {device} {port} {volume} {env_opt} {label} {uid}' diff --git a/src/conf_mode/service_dhcp-server.py b/src/conf_mode/service_dhcp-server.py index f4fb78f57..3b9198ed0 100755 --- a/src/conf_mode/service_dhcp-server.py +++ b/src/conf_mode/service_dhcp-server.py @@ -165,7 +165,6 @@ def verify(dhcp): # Inspect shared-network/subnet listen_ok = False subnets = [] - failover_ok = False shared_networks = len(dhcp['shared_network_name']) disabled_shared_networks = 0 diff --git a/src/migration-scripts/container/1-to-2 b/src/migration-scripts/container/1-to-2 new file mode 100755 index 000000000..408faf978 --- /dev/null +++ b/src/migration-scripts/container/1-to-2 @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# T6208: container: rename "cap-add" CLI node to "capability" + +from sys import argv +from sys import exit +from vyos.configtree import ConfigTree + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +base = ['container', 'name'] +config = ConfigTree(config_file) + +# Check if containers exist and we need to perform image manipulation +if not config.exists(base): + # Nothing to do + exit(0) + +for container in config.list_nodes(base): + cap_path = base + [container, 'cap-add'] + if config.exists(cap_path): + config.rename(cap_path, 'capability') + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print(f'Failed to save the modified config: {e}') + exit(1) diff --git a/src/migration-scripts/ipoe-server/1-to-2 b/src/migration-scripts/ipoe-server/1-to-2 index f1335b5a5..6a7111541 100755 --- a/src/migration-scripts/ipoe-server/1-to-2 +++ b/src/migration-scripts/ipoe-server/1-to-2 @@ -62,7 +62,6 @@ for interface in config.list_nodes(base + ['interface']): base_path = base + ['interface', interface] for vlan in ['vlan-id', 'vlan-range']: if config.exists(base_path + [vlan]): - print(interface, vlan) for tmp in config.return_values(base_path + [vlan]): config.set(base_path + ['vlan'], value=tmp, replace=False) config.delete(base_path + [vlan]) @@ -74,40 +73,38 @@ for interface in config.list_nodes(base + ['interface']): config.set(base_path + ['mode'], value=tmp.lower()) pool_base = base + ['client-ip-pool'] -if not config.exists(pool_base): - exit(0) - -default_pool = '' -gateway = '' - -#named pool migration -namedpools_base = pool_base + ['name'] - -for pool_name in config.list_nodes(namedpools_base): - pool_path = namedpools_base + [pool_name] - if config.exists(pool_path + ['subnet']): - subnet = config.return_value(pool_path + ['subnet']) - config.set(pool_base + [pool_name, 'range'], value=subnet, replace=False) - # Get netmask from subnet - mask = subnet.split("/")[1] - if config.exists(pool_path + ['next-pool']): - next_pool = config.return_value(pool_path + ['next-pool']) - config.set(pool_base + [pool_name, 'next-pool'], value=next_pool) - if not default_pool: - default_pool = pool_name - if config.exists(pool_path + ['gateway-address']) and mask: - gateway = f'{config.return_value(pool_path + ["gateway-address"])}/{mask}' - config.set(base + ['gateway-address'], value=gateway, replace=False) - -if not default_pool and config.list_nodes(namedpools_base): - default_pool = config.list_nodes(namedpools_base)[0] - -config.delete(namedpools_base) - -if default_pool: - config.set(base + ['default-pool'], value=default_pool) -# format as tag node -config.set_tag(pool_base) +if config.exists(pool_base): + default_pool = '' + gateway = '' + + #named pool migration + namedpools_base = pool_base + ['name'] + + for pool_name in config.list_nodes(namedpools_base): + pool_path = namedpools_base + [pool_name] + if config.exists(pool_path + ['subnet']): + subnet = config.return_value(pool_path + ['subnet']) + config.set(pool_base + [pool_name, 'range'], value=subnet, replace=False) + # Get netmask from subnet + mask = subnet.split("/")[1] + if config.exists(pool_path + ['next-pool']): + next_pool = config.return_value(pool_path + ['next-pool']) + config.set(pool_base + [pool_name, 'next-pool'], value=next_pool) + if not default_pool: + default_pool = pool_name + if config.exists(pool_path + ['gateway-address']) and mask: + gateway = f'{config.return_value(pool_path + ["gateway-address"])}/{mask}' + config.set(base + ['gateway-address'], value=gateway, replace=False) + + if not default_pool and config.list_nodes(namedpools_base): + default_pool = config.list_nodes(namedpools_base)[0] + + config.delete(namedpools_base) + + if default_pool: + config.set(base + ['default-pool'], value=default_pool) + # format as tag node + config.set_tag(pool_base) try: with open(file_name, 'w') as f: |