diff options
| -rw-r--r-- | data/templates/router-advert/radvd.conf.j2 | 7 | ||||
| -rw-r--r-- | interface-definitions/nat64.xml.in | 2 | ||||
| -rw-r--r-- | interface-definitions/nat66.xml.in | 2 | ||||
| -rw-r--r-- | interface-definitions/pki.xml.in | 2 | ||||
| -rw-r--r-- | interface-definitions/service_config-sync.xml.in | 394 | ||||
| -rw-r--r-- | interface-definitions/service_router-advert.xml.in | 30 | ||||
| -rw-r--r-- | op-mode-definitions/pki.xml.in | 2 | ||||
| -rw-r--r-- | python/vyos/system/grub.py | 36 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_service_router-advert.py | 28 | ||||
| -rwxr-xr-x | src/conf_mode/service_router-advert.py | 18 | ||||
| -rwxr-xr-x | src/helpers/vyos_config_sync.py | 26 | ||||
| -rwxr-xr-x | src/migration-scripts/policy/1-to-2 | 18 | ||||
| -rwxr-xr-x | src/op_mode/image_installer.py | 4 | ||||
| -rw-r--r-- | src/system/grub_update.py | 4 | 
14 files changed, 527 insertions, 46 deletions
| diff --git a/data/templates/router-advert/radvd.conf.j2 b/data/templates/router-advert/radvd.conf.j2 index 4ef4751dd..97180d164 100644 --- a/data/templates/router-advert/radvd.conf.j2 +++ b/data/templates/router-advert/radvd.conf.j2 @@ -50,6 +50,13 @@ interface {{ iface }} {  {%             endfor %}      };  {%         endif %} +{%         if iface_config.nat64prefix is vyos_defined %} +{%             for nat64prefix, nat64prefix_options in iface_config.nat64prefix.items() %} +    nat64prefix {{ nat64prefix }} { +        AdvValidLifetime {{ nat64prefix_options.valid_lifetime }}; +    }; +{%             endfor %} +{%         endif %}  {%         if iface_config.prefix is vyos_defined %}  {%             for prefix, prefix_options in iface_config.prefix.items() %}      prefix {{ prefix }} { diff --git a/interface-definitions/nat64.xml.in b/interface-definitions/nat64.xml.in index dfdd295d2..4b3c157cc 100644 --- a/interface-definitions/nat64.xml.in +++ b/interface-definitions/nat64.xml.in @@ -2,7 +2,7 @@  <interfaceDefinition>    <node name="nat64" owner="${vyos_conf_scripts_dir}/nat64.py">      <properties> -      <help>IPv6-to-IPv4 Network Address Translation (NAT64) Settings</help> +      <help>Network Address Translation (NAT64) parameters</help>        <priority>501</priority>      </properties>      <children> diff --git a/interface-definitions/nat66.xml.in b/interface-definitions/nat66.xml.in index 1518de8bd..32d501cce 100644 --- a/interface-definitions/nat66.xml.in +++ b/interface-definitions/nat66.xml.in @@ -2,7 +2,7 @@  <interfaceDefinition>    <node name="nat66" owner="${vyos_conf_scripts_dir}/nat66.py">      <properties> -      <help>IPv6-to-IPv6 Network Prefix Translation (NAT66/NPT) Settings</help> +      <help>Network Prefix Translation (NAT66/NPTv6) parameters</help>        <priority>500</priority>      </properties>      <children> diff --git a/interface-definitions/pki.xml.in b/interface-definitions/pki.xml.in index 7a0b073b4..b922771c1 100644 --- a/interface-definitions/pki.xml.in +++ b/interface-definitions/pki.xml.in @@ -2,7 +2,7 @@  <interfaceDefinition>    <node name="pki" owner="${vyos_conf_scripts_dir}/pki.py">      <properties> -      <help>VyOS PKI configuration</help> +      <help>Public key infrastructure (PKI)</help>        <priority>300</priority>      </properties>      <children> diff --git a/interface-definitions/service_config-sync.xml.in b/interface-definitions/service_config-sync.xml.in index 9955acfee..9e9dcdb69 100644 --- a/interface-definitions/service_config-sync.xml.in +++ b/interface-definitions/service_config-sync.xml.in @@ -73,30 +73,382 @@                </constraint>              </properties>            </leafNode> -          <leafNode name="section"> +          <node name="section">              <properties>                <help>Section for synchronization</help> -              <completionHelp> -                <list>nat nat66 firewall</list> -              </completionHelp> -              <valueHelp> -                <format>nat</format> -                <description>NAT</description> -              </valueHelp> -              <valueHelp> -                <format>nat66</format> -                <description>NAT66</description> -              </valueHelp> -              <valueHelp> -                <format>firewall</format> -                <description>firewall</description> -              </valueHelp> -              <constraint> -                <regex>(nat|nat66|firewall)</regex> -              </constraint> -              <multi/>              </properties> -          </leafNode> +            <children> +              <leafNode name="firewall"> +                <properties> +                  <help>Firewall</help> +                  <valueless/> +                </properties> +              </leafNode> +              <node name="interfaces"> +                <properties> +                  <help>Interfaces</help> +                </properties> +                <children> +                  <leafNode name="bonding"> +                    <properties> +                      <help>Bonding interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="bridge"> +                    <properties> +                      <help>Bridge interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="dummy"> +                    <properties> +                      <help>Dummy interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="ethernet"> +                    <properties> +                      <help>Ethernet interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="geneve"> +                    <properties> +                      <help>GENEVE interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="input"> +                    <properties> +                      <help>Input interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="l2tpv3"> +                    <properties> +                      <help>L2TPv3 interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="loopback"> +                    <properties> +                      <help>Loopback interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="macsec"> +                    <properties> +                      <help>MACsec interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="openvpn"> +                    <properties> +                      <help>OpenVPN interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="pppoe"> +                    <properties> +                      <help>PPPoE interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="pseudo-ethernet"> +                    <properties> +                      <help>Pseudo-Ethernet interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="sstpc"> +                    <properties> +                      <help>SSTP client interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="tunnel"> +                    <properties> +                      <help>Tunnel interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="virtual-ethernet"> +                    <properties> +                      <help>Virtual Ethernet interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="vti"> +                    <properties> +                      <help>Virtual tunnel interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="vxlan"> +                    <properties> +                      <help>VXLAN interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="wireguard"> +                    <properties> +                      <help>Wireguard interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="wireless"> +                    <properties> +                      <help>Wireless interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="wwan"> +                    <properties> +                      <help>WWAN interface</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <leafNode name="nat"> +                <properties> +                  <help>NAT</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="nat66"> +                <properties> +                  <help>NAT66</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="pki"> +                <properties> +                  <help>Public key infrastructure (PKI)</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="policy"> +                <properties> +                  <help>Routing policy</help> +                  <valueless/> +                </properties> +              </leafNode> +              <node name="protocols"> +                <properties> +                  <help>Routing protocols</help> +                </properties> +                <children> +                  <leafNode name="babel"> +                    <properties> +                      <help>Babel Routing Protocol</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="bfd"> +                    <properties> +                      <help>Bidirectional Forwarding Detection (BFD)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="bgp"> +                    <properties> +                      <help>Border Gateway Protocol (BGP)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="failover"> +                    <properties> +                      <help>Failover route</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="igmp-proxy"> +                    <properties> +                      <help>Internet Group Management Protocol (IGMP) proxy</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="isis"> +                    <properties> +                      <help>Intermediate System to Intermediate System (IS-IS)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="mpls"> +                    <properties> +                      <help>Multiprotocol Label Switching (MPLS)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="nhrp"> +                    <properties> +                      <help>Next Hop Resolution Protocol (NHRP) parameters</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="ospf"> +                    <properties> +                      <help>Open Shortest Path First (OSPF)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="ospfv3"> +                    <properties> +                      <help>Open Shortest Path First (OSPF) for IPv6</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="pim"> +                    <properties> +                      <help>Protocol Independent Multicast (PIM) and IGMP</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="pim6"> +                    <properties> +                      <help>Protocol Independent Multicast for IPv6 (PIMv6) and MLD</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="rip"> +                    <properties> +                      <help>Routing Information Protocol (RIP) parameters</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="ripng"> +                    <properties> +                      <help>Routing Information Protocol (RIPng) parameters</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="rpki"> +                    <properties> +                      <help>Resource Public Key Infrastructure (RPKI)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="segment-routing"> +                    <properties> +                      <help>Segment Routing</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="static"> +                    <properties> +                      <help>Static Routing</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <node name="service"> +                <properties> +                  <help>System services</help> +                </properties> +                <children> +                  <leafNode name="console-server"> +                    <properties> +                      <help>Serial Console Server</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="dhcp-relay"> +                    <properties> +                      <help>Host Configuration Protocol (DHCP) relay agent</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="dhcp-server"> +                    <properties> +                      <help>Dynamic Host Configuration Protocol (DHCP) for DHCP server</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="dhcpv6-relay"> +                    <properties> +                      <help>DHCPv6 Relay Agent parameters</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="dhcpv6-server"> +                    <properties> +                      <help>DHCP for IPv6 (DHCPv6) server</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="dns"> +                    <properties> +                      <help>Domain Name System (DNS) related services</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="lldp"> +                    <properties> +                      <help>LLDP settings</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="mdns"> +                    <properties> +                      <help>Multicast DNS (mDNS) parameters</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="monitoring"> +                    <properties> +                      <help>Monitoring services</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="ndp-proxy"> +                    <properties> +                      <help>Neighbor Discovery Protocol (NDP) Proxy</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="ntp"> +                    <properties> +                      <help>Network Time Protocol (NTP) configuration</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="snmp"> +                    <properties> +                      <help>Simple Network Management Protocol (SNMP)</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="tftp-server"> +                    <properties> +                      <help>Trivial File Transfer Protocol (TFTP) server</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                  <leafNode name="webproxy"> +                    <properties> +                      <help>Webproxy service settings</help> +                      <valueless/> +                    </properties> +                  </leafNode> +                </children> +              </node> +              <leafNode name="vpn"> +                <properties> +                  <help>Virtual Private Network (VPN)</help> +                  <valueless/> +                </properties> +              </leafNode> +              <leafNode name="vrf"> +                <properties> +                  <help>Virtual Routing and Forwarding</help> +                  <valueless/> +                </properties> +              </leafNode> +            </children> +          </node>          </children>        </node>      </children> diff --git a/interface-definitions/service_router-advert.xml.in b/interface-definitions/service_router-advert.xml.in index 16c29022d..166a4a0cf 100644 --- a/interface-definitions/service_router-advert.xml.in +++ b/interface-definitions/service_router-advert.xml.in @@ -225,6 +225,36 @@                    </leafNode>                  </children>                </tagNode> +              <tagNode name="nat64prefix"> +                <properties> +                  <help>NAT64 prefix included in the router advertisements</help> +                  <valueHelp> +                    <format>ipv6net</format> +                    <description>IPv6 prefix to be advertized</description> +                  </valueHelp> +                  <constraint> +                    <validator name="ipv6-prefix"/> +                  </constraint> +                </properties> +                <children> +                  <leafNode name="valid-lifetime"> +                    <properties> +                      <help>Time in seconds that the prefix will remain valid</help> +                      <completionHelp> +                        <list>infinity</list> +                      </completionHelp> +                      <valueHelp> +                        <format>u32:4-65528</format> +                        <description>Time in seconds that the prefix will remain valid</description> +                      </valueHelp> +                      <constraint> +                        <validator name="numeric" argument="--range 4-65528"/> +                      </constraint> +                    </properties> +                    <defaultValue>65528</defaultValue> +                  </leafNode> +                </children> +              </tagNode>                <tagNode name="prefix">                  <properties>                    <help>IPv6 prefix to be advertised in Router Advertisements (RAs)</help> diff --git a/op-mode-definitions/pki.xml.in b/op-mode-definitions/pki.xml.in index a81c8d4f7..a5e01bade 100644 --- a/op-mode-definitions/pki.xml.in +++ b/op-mode-definitions/pki.xml.in @@ -4,7 +4,7 @@      <children>        <node name="pki">          <properties> -          <help>Generate PKI certificates and keys</help> +          <help>Generate public key infrastructure (PKI) certificates and keys</help>          </properties>          <children>            <node name="ca"> diff --git a/python/vyos/system/grub.py b/python/vyos/system/grub.py index 2e8b20972..864ed65aa 100644 --- a/python/vyos/system/grub.py +++ b/python/vyos/system/grub.py @@ -17,6 +17,7 @@ import platform  from pathlib import Path  from re import MULTILINE, compile as re_compile +from shutil import copy2  from typing import Union  from uuid import uuid5, NAMESPACE_URL, UUID @@ -422,3 +423,38 @@ def set_kernel_cmdline_options(cmdline_options: str, version_name: str,      version_add(version_name=version_name, root_dir=root_dir,                  boot_opts_config=cmdline_options) + + +def sort_inodes(dir_path: str) -> None: +    """Sort inodes for files inside a folder +    Regenerate inodes for each file to get the same order for both inodes +    and file names + +    GRUB iterates files by inodes, not alphabetically. Therefore, if we +    want to read them in proper order, we need to sort inodes for all +    config files in a folder. + +    Args: +        dir_path (str): a path to directory +    """ +    dir_content: list[Path] = sorted(Path(dir_path).iterdir()) +    temp_list_old: list[Path] = [] +    temp_list_new: list[Path] = [] + +    # create a copy of all files, to get new inodes +    for item in dir_content: +        # skip directories +        if item.is_dir(): +            continue +        # create a new copy of file with a temporary name +        copy_path = Path(f'{item.as_posix()}_tmp') +        copy2(item, Path(copy_path)) +        temp_list_old.append(item) +        temp_list_new.append(copy_path) + +    # delete old files and rename new ones +    for item in temp_list_old: +        item.unlink() +    for item in temp_list_new: +        new_name = Path(f'{item.as_posix()[0:-4]}') +        item.rename(new_name) diff --git a/smoketest/scripts/cli/test_service_router-advert.py b/smoketest/scripts/cli/test_service_router-advert.py index 5fc2019fd..d1ff25a58 100755 --- a/smoketest/scripts/cli/test_service_router-advert.py +++ b/smoketest/scripts/cli/test_service_router-advert.py @@ -195,6 +195,34 @@ class TestServiceRADVD(VyOSUnitTestSHIM.TestCase):          for src in ra_src:              self.assertIn(f'        {src};', config) +    def test_nat64prefix(self): +        nat64prefix = '64:ff9b::/96' +        nat64prefix_invalid = '64:ff9b::/44' + +        self.cli_set(base_path + ['nat64prefix', nat64prefix]) + +        # and another invalid prefix +        # Invalid NAT64 prefix length for "2001:db8::/34", can only be one of: +        # /32, /40, /48, /56, /64, /96 +        self.cli_set(base_path + ['nat64prefix', nat64prefix_invalid]) +        with self.assertRaises(ConfigSessionError): +            self.cli_commit() +        self.cli_delete(base_path + ['nat64prefix', nat64prefix_invalid]) + +        # NAT64 valid-lifetime must not be smaller then "interval max" +        self.cli_set(base_path + ['nat64prefix', nat64prefix, 'valid-lifetime', '500']) +        with self.assertRaises(ConfigSessionError): +            self.cli_commit() +        self.cli_delete(base_path + ['nat64prefix', nat64prefix, 'valid-lifetime']) + +        # commit changes +        self.cli_commit() + +        config = read_file(RADVD_CONF) + +        tmp = f'nat64prefix {nat64prefix}' + ' {' +        self.assertIn(tmp, config) +        self.assertIn('AdvValidLifetime 65528;', config) # default  if __name__ == '__main__':      unittest.main(verbosity=2) diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py index dbb47de4e..88d767bb8 100755 --- a/src/conf_mode/service_router-advert.py +++ b/src/conf_mode/service_router-advert.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2018-2022 VyOS maintainers and contributors +# Copyright (C) 2018-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 @@ -17,6 +17,8 @@  import os  from sys import exit +from ipaddress import IPv6Network +  from vyos.base import Warning  from vyos.config import Config  from vyos.template import render @@ -47,7 +49,9 @@ def verify(rtradv):          return None      for interface, interface_config in rtradv['interface'].items(): -        if 'prefix' in interface: +        interval_max = int(interface_config['interval']['max']) + +        if 'prefix' in interface_config:              for prefix, prefix_config in interface_config['prefix'].items():                  valid_lifetime = prefix_config['valid_lifetime']                  if valid_lifetime == 'infinity': @@ -60,6 +64,15 @@ def verify(rtradv):                  if not (int(valid_lifetime) >= int(preferred_lifetime)):                      raise ConfigError('Prefix valid-lifetime must be greater then or equal to preferred-lifetime') +        if 'nat64prefix' in interface_config: +            nat64_supported_lengths = [32, 40, 48, 56, 64, 96] +            for prefix, prefix_config in interface_config['nat64prefix'].items(): +                if IPv6Network(prefix).prefixlen not in nat64_supported_lengths: +                    raise ConfigError(f'Invalid NAT64 prefix length for "{prefix}", can only be one of: /' + ', /'.join(nat64_supported_lengths)) + +                if int(prefix_config['valid_lifetime']) < interval_max: +                    raise ConfigError(f'NAT64 valid-lifetime must not be smaller then "interval max" which is "{interval_max}"!') +          if 'name_server' in interface_config:              if len(interface_config['name_server']) > 3:                  raise ConfigError('No more then 3 IPv6 name-servers supported!') @@ -72,7 +85,6 @@ def verify(rtradv):              # ensure stale RDNSS info gets removed in a timely fashion, this              # should not be greater than 2*MaxRtrAdvInterval.              lifetime = int(interface_config['name_server_lifetime']) -            interval_max = int(interface_config['interval']['max'])              if lifetime > 0:                  if lifetime < int(interval_max):                      raise ConfigError(f'RDNSS lifetime must be at least "{interval_max}" seconds!') diff --git a/src/helpers/vyos_config_sync.py b/src/helpers/vyos_config_sync.py index 7cfa8fe88..572fea61f 100755 --- a/src/helpers/vyos_config_sync.py +++ b/src/helpers/vyos_config_sync.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2023 VyOS maintainers and contributors +# Copyright (C) 2023-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 @@ -60,6 +60,7 @@ def post_request(url: str,      return response +  def retrieve_config(section: str = None) -> Optional[Dict[str, Any]]:      """Retrieves the configuration from the local server. @@ -71,8 +72,6 @@ def retrieve_config(section: str = None) -> Optional[Dict[str, Any]]:      """      if section is None:          section = [] -    else: -        section = section.split()      conf = Config()      config = conf.get_config_dict(section, get_first_key=True) @@ -101,8 +100,6 @@ def set_remote_config(      if path is None:          path = [] -    else: -        path = path.split()      headers = {'Content-Type': 'application/json'}      # Disable the InsecureRequestWarning @@ -127,17 +124,16 @@ def set_remote_config(  def is_section_revised(section: str) -> bool:      from vyos.config_mgmt import is_node_revised -    return is_node_revised([section]) +    return is_node_revised(section)  def config_sync(secondary_address: str,                  secondary_key: str, -                sections: List[str], +                sections: List[list],                  mode: str):      """Retrieve a config section from primary router in JSON format and send it to         secondary router      """ -    # Config sync only if sections changed      if not any(map(is_section_revised, sections)):          return @@ -188,5 +184,17 @@ if __name__ == '__main__':              "Missing required configuration data for config synchronization.")          exit(0) +    # Generate list_sections of sections/subsections +    # [ +    #   ['interfaces', 'pseudo-ethernet'], ['interfaces', 'virtual-ethernet'], ['nat'], ['nat66'] +    # ] +    list_sections = [] +    for section, subsections in sections.items(): +        if subsections: +            for subsection in subsections: +                list_sections.append([section, subsection]) +        else: +            list_sections.append([section]) +      config_sync(secondary_address, secondary_key, -                sections, mode) +                list_sections, mode) diff --git a/src/migration-scripts/policy/1-to-2 b/src/migration-scripts/policy/1-to-2 index c70490ce9..c7a983bba 100755 --- a/src/migration-scripts/policy/1-to-2 +++ b/src/migration-scripts/policy/1-to-2 @@ -32,23 +32,23 @@ file_name = argv[1]  with open(file_name, 'r') as f:      config_file = f.read() -base = ['policy', 'ipv6-route'] +base = ['policy']  config = ConfigTree(config_file)  if not config.exists(base):      # Nothing to do      exit(0) -config.rename(base, 'route6') -config.set_tag(['policy', 'route6']) +if config.exists(base + ['ipv6-route']): +    config.rename(base + ['ipv6-route'],'route6') +    config.set_tag(['policy', 'route6'])  for route in ['route', 'route6']: -    route_path = ['policy', route] -    if config.exists(route_path): -        for name in config.list_nodes(route_path): -            if config.exists(route_path + [name, 'rule']): -                for rule in config.list_nodes(route_path + [name, 'rule']): -                    rule_tcp_flags = route_path + [name, 'rule', rule, 'tcp', 'flags'] +    if config.exists(base + [route]): +        for name in config.list_nodes(base + [route]): +            if config.exists(base + [route, name, 'rule']): +                for rule in config.list_nodes(base + [route, name, 'rule']): +                    rule_tcp_flags = base + [route, name, 'rule', rule, 'tcp', 'flags']                      if config.exists(rule_tcp_flags):                          tmp = config.return_value(rule_tcp_flags) diff --git a/src/op_mode/image_installer.py b/src/op_mode/image_installer.py index 85ebd19ba..b0567305a 100755 --- a/src/op_mode/image_installer.py +++ b/src/op_mode/image_installer.py @@ -786,6 +786,10 @@ def install_image() -> None:              grub.install(install_target.name, f'{DIR_DST_ROOT}/boot/',                           f'{DIR_DST_ROOT}/boot/efi') +        # sort inodes (to make GRUB read config files in alphabetical order) +        grub.sort_inodes(f'{DIR_DST_ROOT}/{grub.GRUB_DIR_VYOS}') +        grub.sort_inodes(f'{DIR_DST_ROOT}/{grub.GRUB_DIR_VYOS_VERS}') +          # umount filesystems and remove temporary files          if is_raid_install(install_target):              cleanup([install_target.name], diff --git a/src/system/grub_update.py b/src/system/grub_update.py index 5a7d8eb72..5a0534195 100644 --- a/src/system/grub_update.py +++ b/src/system/grub_update.py @@ -105,4 +105,8 @@ if __name__ == '__main__':      else:          render(grub_cfg_main, grub.TMPL_GRUB_MAIN, {}) +    # sort inodes (to make GRUB read config files in alphabetical order) +    grub.sort_inodes(f'{root_dir}/{grub.GRUB_DIR_VYOS}') +    grub.sort_inodes(f'{root_dir}/{grub.GRUB_DIR_VYOS_VERS}') +      exit(0) | 
