diff options
| -rw-r--r-- | data/templates/high-availability/10-override.conf.j2 (renamed from src/etc/systemd/system/keepalived.service.d/override.conf) | 4 | ||||
| -rw-r--r-- | interface-definitions/high-availability.xml.in | 6 | ||||
| -rw-r--r-- | python/vyos/config_mgmt.py | 31 | ||||
| -rwxr-xr-x | src/conf_mode/high-availability.py | 20 | ||||
| -rwxr-xr-x | src/helpers/vyos-save-config.py | 5 | 
5 files changed, 48 insertions, 18 deletions
| diff --git a/src/etc/systemd/system/keepalived.service.d/override.conf b/data/templates/high-availability/10-override.conf.j2 index d91a824b9..d1cb25581 100644 --- a/src/etc/systemd/system/keepalived.service.d/override.conf +++ b/data/templates/high-availability/10-override.conf.j2 @@ -1,3 +1,5 @@ +### Autogenerated by ${vyos_conf_scripts_dir}/high-availability.py ### +{% set snmp = '' if vrrp.disable_snmp is vyos_defined else '--snmp' %}  [Unit]  After=vyos-router.service  # Only start if there is our configuration file - remove Debian default @@ -10,5 +12,5 @@ KillMode=process  Type=simple  # Read configuration variable file if it is present  ExecStart= -ExecStart=/usr/sbin/keepalived --use-file /run/keepalived/keepalived.conf --pid /run/keepalived/keepalived.pid --dont-fork --snmp +ExecStart=/usr/sbin/keepalived --use-file /run/keepalived/keepalived.conf --pid /run/keepalived/keepalived.pid --dont-fork {{ snmp }}  PIDFile=/run/keepalived/keepalived.pid diff --git a/interface-definitions/high-availability.xml.in b/interface-definitions/high-availability.xml.in index 4f55916fa..47a772d04 100644 --- a/interface-definitions/high-availability.xml.in +++ b/interface-definitions/high-availability.xml.in @@ -12,6 +12,12 @@            <help>Virtual Router Redundancy Protocol settings</help>          </properties>          <children> +          <leafNode name="disable-snmp"> +            <properties> +              <valueless/> +              <help>Disable SNMP</help> +            </properties> +          </leafNode>            <node name="global-parameters">              <properties>                <help>VRRP global parameters</help> diff --git a/python/vyos/config_mgmt.py b/python/vyos/config_mgmt.py index 0fc72e660..9caf6da2b 100644 --- a/python/vyos/config_mgmt.py +++ b/python/vyos/config_mgmt.py @@ -31,6 +31,7 @@ from vyos.configtree import ConfigTree, ConfigTreeError, show_diff  from vyos.defaults import directories  from vyos.version import get_full_version_data  from vyos.utils.io import ask_yes_no +from vyos.utils.boot import boot_configuration_complete  from vyos.utils.process import is_systemd_service_active  from vyos.utils.process import rc_cmd @@ -200,9 +201,9 @@ Proceed ?'''              raise ConfigMgmtError(out)          entry = self._read_tmp_log_entry() -        self._add_log_entry(**entry)          if self._archive_active_config(): +            self._add_log_entry(**entry)              self._update_archive()          msg = 'Reboot timer stopped' @@ -334,10 +335,10 @@ Proceed ?'''              user = self._get_user()              via = 'init'              comment = '' -            self._add_log_entry(user, via, comment)              # add empty init config before boot-config load for revision              # and diff consistency              if self._archive_active_config(): +                self._add_log_entry(user, via, comment)                  self._update_archive()          os.umask(mask) @@ -352,9 +353,8 @@ Proceed ?'''              self._new_log_entry(tmp_file=tmp_log_entry)              return -        self._add_log_entry() -          if self._archive_active_config(): +            self._add_log_entry()              self._update_archive()      def commit_archive(self): @@ -475,22 +475,26 @@ Proceed ?'''          conf_file.chmod(0o644)      def _archive_active_config(self) -> bool: +        use_tmp = (boot_configuration_complete() or not +                   os.path.isfile(archive_config_file))          mask = os.umask(0o113) -        ext = os.getpid() -        tmp_save = f'/tmp/config.boot.{ext}' -        save_config(tmp_save) +        if use_tmp: +            ext = os.getpid() +            cmp_saved = f'/tmp/config.boot.{ext}' +            save_config(cmp_saved) +        else: +            cmp_saved = config_file          try: -            if cmp(tmp_save, archive_config_file, shallow=False): -                # this will be the case on boot, as well as certain -                # re-initialiation instances after delete/set -                os.unlink(tmp_save) +            if cmp(cmp_saved, archive_config_file, shallow=False): +                if use_tmp: os.unlink(cmp_saved) +                os.umask(mask)                  return False          except FileNotFoundError:              pass -        rc, out = rc_cmd(f'sudo mv {tmp_save} {archive_config_file}') +        rc, out = rc_cmd(f'sudo mv {cmp_saved} {archive_config_file}')          os.umask(mask)          if rc != 0: @@ -522,9 +526,8 @@ Proceed ?'''          return len(l)      def _check_revision_number(self, rev: int) -> bool: -        # exclude init revision:          maxrev = self._get_number_of_revisions() -        if not 0 <= rev < maxrev - 1: +        if not 0 <= rev < maxrev:              return False          return True diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py index 0121df11c..70f43ab52 100755 --- a/src/conf_mode/high-availability.py +++ b/src/conf_mode/high-availability.py @@ -15,6 +15,7 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>. +import os  import time  from sys import exit @@ -24,6 +25,7 @@ from ipaddress import IPv6Interface  from vyos.base import Warning  from vyos.config import Config +from vyos.configdict import leaf_node_changed  from vyos.ifconfig.vrrp import VRRP  from vyos.template import render  from vyos.template import is_ipv4 @@ -35,6 +37,9 @@ from vyos import airbag  airbag.enable() +systemd_override = r'/run/systemd/system/keepalived.service.d/10-override.conf' + +  def get_config(config=None):      if config:          conf = config @@ -54,6 +59,9 @@ def get_config(config=None):      if conf.exists(conntrack_path):          ha['conntrack_sync_group'] = conf.return_value(conntrack_path) +    if leaf_node_changed(conf, base + ['vrrp', 'disable-snmp']): +        ha.update({'restart_required': {}}) +      return ha  def verify(ha): @@ -164,19 +172,23 @@ def verify(ha):  def generate(ha):      if not ha or 'disable' in ha: +        if os.path.isfile(systemd_override): +            os.unlink(systemd_override)          return None      render(VRRP.location['config'], 'high-availability/keepalived.conf.j2', ha) +    render(systemd_override, 'high-availability/10-override.conf.j2', ha)      return None  def apply(ha):      service_name = 'keepalived.service' +    call('systemctl daemon-reload')      if not ha or 'disable' in ha:          call(f'systemctl stop {service_name}')          return None      # Check if IPv6 address is tentative T5533 -    for group, group_config in ha['vrrp']['group'].items(): +    for group, group_config in ha.get('vrrp', {}).get('group', {}).items():          if 'hello_source_address' in group_config:              if is_ipv6(group_config['hello_source_address']):                  ipv6_address = group_config['hello_source_address'] @@ -187,7 +199,11 @@ def apply(ha):                      if is_ipv6_tentative(interface, ipv6_address):                          time.sleep(interval) -    call(f'systemctl reload-or-restart {service_name}') +    systemd_action = 'reload-or-restart' +    if 'restart_required' in ha: +        systemd_action = 'restart' + +    call(f'systemctl {systemd_action} {service_name}')      return None  if __name__ == '__main__': diff --git a/src/helpers/vyos-save-config.py b/src/helpers/vyos-save-config.py index 2812155e8..8af4a7916 100755 --- a/src/helpers/vyos-save-config.py +++ b/src/helpers/vyos-save-config.py @@ -44,7 +44,10 @@ ct = config.get_config_tree(effective=True)  write_file = save_file if remote_save is None else NamedTemporaryFile(delete=False).name  with open(write_file, 'w') as f: -    f.write(ct.to_string()) +    # config_tree is None before boot configuration is complete; +    # automated saves should check boot_configuration_complete +    if ct is not None: +        f.write(ct.to_string())      f.write("\n")      f.write(system_footer()) | 
