summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/dynamic-dns/ddclient.conf.tmpl3
-rw-r--r--op-mode-definitions/ipoe-server.xml33
-rw-r--r--op-mode-definitions/show-ip-bgp.xml342
-rw-r--r--python/vyos/airbag.py5
-rw-r--r--python/vyos/debug.py182
-rw-r--r--python/vyos/ifconfig/control.py9
-rw-r--r--python/vyos/util.py55
-rwxr-xr-xsrc/completion/list_ipoe.py16
-rwxr-xr-xsrc/conf_mode/bcast_relay.py4
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py10
-rwxr-xr-xsrc/conf_mode/dynamic_dns.py33
-rwxr-xr-xsrc/conf_mode/flow_accounting_conf.py4
-rwxr-xr-xsrc/conf_mode/host_name.py2
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py48
-rwxr-xr-xsrc/conf_mode/le_cert.py13
-rwxr-xr-xsrc/conf_mode/mdns_repeater.py5
-rwxr-xr-xsrc/conf_mode/system-syslog.py4
-rwxr-xr-xsrc/conf_mode/tftp_server.py2
-rw-r--r--src/etc/systemd/system/pdns-recursor.service.d/override.conf5
-rwxr-xr-xsrc/op_mode/dns_forwarding_restart.sh2
-rwxr-xr-xsrc/op_mode/dynamic_dns.py9
-rwxr-xr-xsrc/op_mode/flow_accounting_op.py4
-rwxr-xr-xsrc/op_mode/generate_ssh_server_key.py11
-rwxr-xr-xsrc/op_mode/ipoe-control.py65
-rwxr-xr-xsrc/op_mode/restart_dhcp_relay.py4
-rwxr-xr-xsrc/op_mode/show_dhcp.py2
-rwxr-xr-xsrc/op_mode/show_dhcpv6.py2
-rw-r--r--src/systemd/ddclient.service14
28 files changed, 735 insertions, 153 deletions
diff --git a/data/templates/dynamic-dns/ddclient.conf.tmpl b/data/templates/dynamic-dns/ddclient.conf.tmpl
index 22cb38f4e..9c7219230 100644
--- a/data/templates/dynamic-dns/ddclient.conf.tmpl
+++ b/data/templates/dynamic-dns/ddclient.conf.tmpl
@@ -1,10 +1,7 @@
-
### Autogenerated by dynamic_dns.py ###
daemon=1m
syslog=yes
ssl=yes
-pid={{ pid_file }}
-cache={{ cache_file }}
{% for interface in interfaces -%}
diff --git a/op-mode-definitions/ipoe-server.xml b/op-mode-definitions/ipoe-server.xml
index c05e2d2c1..c20d3aa2a 100644
--- a/op-mode-definitions/ipoe-server.xml
+++ b/op-mode-definitions/ipoe-server.xml
@@ -12,24 +12,33 @@
<help>Clear ipoe-server session</help>
</properties>
<children>
- <leafNode name="username">
+ <tagNode name="username">
<properties>
<help>Clear ipoe-server session by username</help>
<completionHelp>
- <script>/usr/bin/accel-cmd -p 2002 show sessions username | sed -e 's/ \r//g' | tail -n +3</script>
+ <script>${vyos_completion_dir}/list_ipoe.py --selector="username"</script>
</completionHelp>
</properties>
- <command>/usr/bin/accel-cmd -p 2002 terminate username $5</command>
- </leafNode>
- <leafNode name="sid">
+ <command>${vyos_op_scripts_dir}/ipoe-control.py --action="terminate" --selector="username" --target="$5"</command>
+ </tagNode>
+ <tagNode name="sid">
<properties>
- <help>Clear ipoe-server session by sid</help>
+ <help>Clear ipoe-server session by Session ID</help>
<completionHelp>
- <script>/usr/bin/accel-cmd -p 2002 show sessions sid | sed -e 's/ \r//g' | tail -n +3</script>
+ <script>${vyos_completion_dir}/list_ipoe.py --selector="sid"</script>
</completionHelp>
</properties>
- <command>/usr/bin/accel-cmd -p 2002 terminate sid $5</command>
- </leafNode>
+ <command>${vyos_op_scripts_dir}/ipoe-control.py --action="terminate" --selector="sid" --target="$5"</command>
+ </tagNode>
+ <tagNode name="interface">
+ <properties>
+ <help>Clear ipoe-server session by interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_ipoe.py --selector="ifname"</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/ipoe-control.py --action="terminate" --selector="if" --target="$5"</command>
+ </tagNode>
</children>
</node>
</children>
@@ -47,13 +56,13 @@
<properties>
<help>Show active IPoE server sessions</help>
</properties>
- <command>/usr/bin/accel-cmd -p 2002 show sessions ifname,username,called-sid,calling-sid,ip,ip6,ip6-dp,rate-limit,state,uptime,sid</command>
+ <command>${vyos_op_scripts_dir}/ipoe-control.py --action="show_sessions"</command>
</leafNode>
<leafNode name="statistics">
<properties>
<help>Show IPoE server statistics</help>
</properties>
- <command>/usr/bin/accel-cmd -p 2002 show stat</command>
+ <command>${vyos_op_scripts_dir}/ipoe-control.py --action="show_stat"</command>
</leafNode>
</children>
</node>
@@ -65,7 +74,7 @@
<properties>
<help>show ipoe-server status</help>
</properties>
- <command>if [ -e /var/run/accel_ipoe.pid ]; then /usr/bin/accel-cmd restart -p 2002; else echo "ipoe-server not running"; fi</command>
+ <command>${vyos_op_scripts_dir}/ipoe-control.py --action="restart"</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-ip-bgp.xml b/op-mode-definitions/show-ip-bgp.xml
new file mode 100644
index 000000000..5eb2ae56e
--- /dev/null
+++ b/op-mode-definitions/show-ip-bgp.xml
@@ -0,0 +1,342 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="ip">
+ <children>
+ <node name="bgp">
+ <properties>
+ <help>Show Border Gateway Protocol (BGP) information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp"</command>
+ <children>
+ <leafNode name="attribute-info">
+ <properties>
+ <help>Show BGP attribute information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp attribute-info"</command>
+ </leafNode>
+ <leafNode name="cidr-only">
+ <properties>
+ <help>Display only routes with non-natural netmasks</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp cidr-only"</command>
+ </leafNode>
+ <node name="community">
+ <properties>
+ <help>Show BGP routes matching the communities</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp community"</command>
+ </node>
+ <tagNode name="community">
+ <properties>
+ <help>Display routes matching the specified communities</help>
+ <completionHelp>
+ <list>&lt;AA:NN&gt; local-AS no-advertise no-export</list>
+ </completionHelp>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp community $5"</command>
+ </tagNode>
+ <leafNode name="community-info">
+ <properties>
+ <help>List all bgp community information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp community-info"</command>
+ </leafNode>
+ <tagNode name="community-list">
+ <properties>
+ <help>Show BGP routes matching specified community list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp community-list $5"</command>
+ <children>
+ <leafNode name="exact-match">
+ <properties>
+ <help>Show BGP routes exactly matching specified community list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp community-list $5 exact-match"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ <leafNode name="dampened-paths">
+ <properties>
+ <help>Show dampened BGP paths</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp dampening dampened-paths"</command>
+ </leafNode>
+ <tagNode name="filter-list">
+ <properties>
+ <help>Show BGP information for specified word</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp filter-list $5"</command>
+ </tagNode>
+ <leafNode name="flap-statistics">
+ <properties>
+ <help>Show flap statistics of routes</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp dampening flap-statistics"</command>
+ </leafNode>
+ <node name="ipv4">
+ <properties>
+ <help>Show BGP IPv4 information</help>
+ </properties>
+ <children>
+ <node name="unicast">
+ <properties>
+ <help>Show BGP IPv4 unicast information</help>
+ </properties>
+ <children>
+ <leafNode name="cidr-only">
+ <properties>
+ <help>Display only routes with non-natural netmasks</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast cidr-only"</command>
+ </leafNode>
+ <node name="community"> <!-- START new code -->
+ <properties>
+ <help>Show BGP routes matching the communities</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast community"</command>
+ </node>
+ <tagNode name="community">
+ <properties>
+ <help>Display routes matching the specified communities</help>
+ <completionHelp>
+ <list>&lt;AA:NN&gt; local-AS no-advertise no-export</list>
+ </completionHelp>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast community $7"</command>
+ </tagNode>
+ <tagNode name="community-list">
+ <properties>
+ <help>Show BGP routes matching specified community list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast community-list $7"</command>
+ <children>
+ <leafNode name="exact-match">
+ <properties>
+ <help>Show BGP routes exactly matching specified community list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast community-list $7 exact-match"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ <tagNode name="filter-list">
+ <properties>
+ <help>Show BGP information for specified word</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp filter-list $5"</command>
+ </tagNode>
+ <tagNode name="neighbors">
+ <properties>
+ <help>Show detailed BGP IPv4 unicast neighbor information</help>
+ <completionHelp>
+ <script>vtysh -c "show ip bgp ipv4 unicast summary" | awk '{print $1}' | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"</script>
+ </completionHelp>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast neighbors $7"</command>
+ <children>
+ <leafNode name="advertised-routes">
+ <properties>
+ <help>Show routes advertised to a BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast neighbor $7 advertised-routes"</command>
+ </leafNode>
+ <leafNode name="prefix-counts">
+ <properties>
+ <help>Show detailed prefix count information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast neighbor $7 prefix-counts"</command>
+ </leafNode>
+ <leafNode name="received-routes">
+ <properties>
+ <help>Show the received routes from neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast neighbor $7 received-routes"</command>
+ </leafNode>
+ <leafNode name="routes">
+ <properties>
+ <help>Show routes learned from neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast neighbor $7 routes"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ <leafNode name="paths">
+ <properties>
+ <help>Show BGP path information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast paths"</command>
+ </leafNode>
+ <tagNode name="prefix-list">
+ <properties>
+ <help>Show BGP routes matching the specified prefix list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast prefix-list $7"</command>
+ </tagNode>
+ <tagNode name="regexp">
+ <properties>
+ <help>Show BGP routes matching the specified AS path regular expression</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp ipv4 unicast regexp $5"</command>
+ </tagNode>
+ <tagNode name="route-map">
+ <properties>
+ <help>Show BGP routes matching the specified route map</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp route-map $5"</command>
+ </tagNode>
+ <leafNode name="summary">
+ <properties>
+ <help>Show summary of BGP information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp summary"</command>
+ </leafNode>
+ </children>
+ </node>
+ <tagNode name="unicast">
+ <properties>
+ <help>Show BGP information for specified IP address or prefix</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp $6"</command>
+ </tagNode>
+ </children>
+ </node>
+ <node name="large-community">
+ <properties>
+ <help>Show BGP routes matching the specified large-communities</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp large-community"</command>
+ </node>
+ <leafNode name="large-community-info">
+ <properties>
+ <help>Show BGP large-community information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp large-community-info"</command>
+ </leafNode>
+ <tagNode name="large-community-list">
+ <properties>
+ <help>Show BGP routes matching the specified large-community list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp large-community-list $5"</command>
+ </tagNode>
+ <leafNode name="memory">
+ <properties>
+ <help>Show BGP memory usage</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp memory"</command>
+ </leafNode>
+ <tagNode name="neighbors">
+ <properties>
+ <help>Show detailed BGP IPv4 unicast neighbor information</help>
+ <completionHelp>
+ <script>vtysh -c "show ip bgp summary" | awk '{print $1}' | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"</script>
+ </completionHelp>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbors $5"</command>
+ <children>
+ <leafNode name="advertised-routes">
+ <properties>
+ <help>Show routes advertised to a BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 advertised-routes"</command>
+ </leafNode>
+ <leafNode name="dampened-routes">
+ <properties>
+ <help>Show dampened routes received from BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 dampened-routes"</command>
+ </leafNode>
+ <leafNode name="flap-statistics">
+ <properties>
+ <help>Show flap statistics of the routes learned from BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 flap-statistics"</command>
+ </leafNode>
+ <leafNode name="prefix-counts">
+ <properties>
+ <help>Show detailed prefix count information for BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 prefix-counts"</command>
+ </leafNode>
+ <node name="received">
+ <properties>
+ <help>Show information received from BGP neighbor</help>
+ </properties>
+ <children>
+ <leafNode name="prefix-filter">
+ <properties>
+ <help>Show prefixlist filter</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 received prefix-filter"</command>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="received-routes">
+ <properties>
+ <help>Show received routes from BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 received-routes"</command>
+ </leafNode>
+ <leafNode name="routes">
+ <properties>
+ <help>Show routes learned from BGP neighbor</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp neighbor $5 routes"</command>
+ </leafNode>
+ </children>
+ </tagNode>
+ <leafNode name="paths">
+ <properties>
+ <help>Show BGP path information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp paths"</command>
+ </leafNode>
+ <tagNode name="prefix-list">
+ <properties>
+ <help>Show BGP routes matching the specified prefix list</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp prefix-list $5"</command>
+ </tagNode>
+ <tagNode name="regexp">
+ <properties>
+ <help>Show BGP routes matching the specified AS path regular expression</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp regexp $5"</command>
+ </tagNode>
+ <tagNode name="route-map">
+ <properties>
+ <help>Show BGP routes matching the specified route map</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp route-map $5"</command>
+ </tagNode>
+ <leafNode name="statistics">
+ <properties>
+ <help>Show summary of BGP information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp statistics"</command>
+ </leafNode>
+ <leafNode name="summary">
+ <properties>
+ <help>Show summary of BGP information</help>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp summary"</command>
+ </leafNode>
+ </children>
+ </node>
+ <tagNode name="bgp">
+ <properties>
+ <help>Show BGP information for specified IP address or prefix</help>
+ <completionHelp>
+ <list>&lt;x.x.x.x&gt; &lt;x.x.x.x/x&gt;</list>
+ </completionHelp>
+ </properties>
+ <command>/usr/bin/vtysh -c "show ip bgp $4"</command>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/python/vyos/airbag.py b/python/vyos/airbag.py
index 664974d5f..b0565192d 100644
--- a/python/vyos/airbag.py
+++ b/python/vyos/airbag.py
@@ -19,10 +19,10 @@ import logging
import logging.handlers
from datetime import datetime
+from vyos import debug
from vyos.config import Config
from vyos.version import get_version
from vyos.util import run
-from vyos.util import debug
# we allow to disable the extra logging
@@ -77,8 +77,7 @@ def bug_report(dtype, value, trace):
# reach the end of __main__ and was not intercepted
def intercepter(dtype, value, trace):
bug_report(dtype, value, trace)
- # debug returns either '' or 'developer' if debuging is enabled
- if debug('developer'):
+ if debug.enabled('developer'):
import pdb
pdb.pm()
diff --git a/python/vyos/debug.py b/python/vyos/debug.py
new file mode 100644
index 000000000..20090fb85
--- /dev/null
+++ b/python/vyos/debug.py
@@ -0,0 +1,182 @@
+# Copyright 2019 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/>.
+
+import os
+import sys
+
+
+def message(message, flag='', destination=sys.stdout):
+ """
+ print a debug message line on stdout if debugging is enabled for the flag
+ also log it to a file if the flag 'log' is enabled
+
+ message: the message to print
+ flag: which flag must be set for it to print
+ destination: which file like object to write to (default: sys.stdout)
+
+ returns if any message was logged or not
+ """
+ enable = enabled(flag)
+ if enable:
+ destination.write(_format(flag,message))
+
+ # the log flag is special as it logs all the commands
+ # executed to a log
+ logfile = _logfile('log', '/tmp/developer-log')
+ if not logfile:
+ return enable
+
+ try:
+ # at boot the file is created as root:vyattacfg
+ # at runtime the file is created as user:vyattacfg
+ # the default permission are 644
+ mask = os.umask(0o113)
+
+ with open(logfile, 'a') as f:
+ f.write(_format('log', message))
+ finally:
+ os.umask(mask)
+
+ return enable
+
+
+def enabled(flag):
+ """
+ a flag can be set by touching the file in /tmp or /config
+
+ The current flags are:
+ - developer: the code will drop into PBD on un-handled exception
+ - log: the code will log all command to a file
+ - ifconfig: when modifying an interface,
+ prints command with result and sysfs access on stdout for interface
+ - command: print command run with result
+
+ Having the flag setup on the filesystem is required to have
+ debuging at boot time, however, setting the flag via environment
+ does not require a seek to the filesystem and is more efficient
+ it can be done on the shell on via .bashrc for the user
+
+ The function returns an empty string if the flag was not set otherwise
+ the function returns either the file or environment name used to set it up
+ """
+
+ # this is to force all new flags to be registered here to be
+ # documented both here and a reminder to update readthedocs :-)
+ if flag not in ['developer', 'log', 'ifconfig', 'command']:
+ return ''
+
+ return _fromenv(flag) or _fromfile(flag)
+
+
+def _format(flag, message):
+ """
+ format a log message
+ """
+ return f'DEBUG/{flag.upper():<7} {message}\n'
+
+
+def _fromenv(flag):
+ """
+ check if debugging is set for this flag via environment
+
+ For a given debug flag named "test"
+ The presence of the environment VYOS_TEST_DEBUG (uppercase) enables it
+
+ return empty string if not
+ return content of env value it is
+ """
+
+ flagname = f'VYOS_{flag.upper()}_DEBUG'
+ flagenv = os.environ.get(flagname, None)
+
+ if flagenv is None:
+ return ''
+ return flagenv
+
+
+def _fromfile(flag):
+ """
+ Check if debug exist for a given debug flag name
+
+ Check is a debug flag was set by the user. the flag can be set either:
+ - in /tmp for a non-persistent presence between reboot
+ - in /config for always on (an existence at boot time)
+
+ For a given debug flag named "test"
+ The presence of the file vyos.test.debug (all lowercase) enables it
+
+ The function returns an empty string if the flag was not set otherwise
+ the function returns the full flagname
+ """
+
+ for folder in ('/tmp', '/config'):
+ flagfile = f'{folder}/vyos.{flag}.debug'
+ if os.path.isfile(flagfile):
+ return flagfile
+
+ return ''
+
+
+def _contentenv(flag):
+ return os.environ.get(f'VYOS_{flag.upper()}_DEBUG', '').strip()
+
+
+def _contentfile(flag):
+ """
+ Check if debug exist for a given debug flag name
+
+ Check is a debug flag was set by the user. the flag can be set either:
+ - in /tmp for a non-persistent presence between reboot
+ - in /config for always on (an existence at boot time)
+
+ For a given debug flag named "test"
+ The presence of the file vyos.test.debug (all lowercase) enables it
+
+ The function returns an empty string if the flag was not set otherwise
+ the function returns the full flagname
+ """
+
+ for folder in ('/tmp', '/config'):
+ flagfile = f'{folder}/vyos.{flag}.debug'
+ if not os.path.isfile(flagfile):
+ continue
+ with open(flagfile) as f:
+ return f.readline().strip()
+
+ return ''
+
+
+def _logfile(flag, default):
+ """
+ return the name of the file to use for logging when the flag 'log' is set
+ if it could not be established or the location is invalid it returns
+ an empty string
+ """
+
+ # For log we return the location of the log file
+ log_location = _contentenv(flag) or _contentfile(flag)
+
+ # it was not set
+ if not log_location:
+ return ''
+
+ # Make sure that the logs can only be in /tmp, /var/log, or /tmp
+ if not log_location.startswith('/tmp/') and \
+ not log_location.startswith('/config/') and \
+ not log_location.startswith('/var/log/'):
+ return default
+ if '..' in log_location:
+ return default
+ return log_location
diff --git a/python/vyos/ifconfig/control.py b/python/vyos/ifconfig/control.py
index 464cd585e..7bb63beed 100644
--- a/python/vyos/ifconfig/control.py
+++ b/python/vyos/ifconfig/control.py
@@ -16,8 +16,9 @@
import os
-from vyos.util import debug, debug_msg
-from vyos.util import popen, cmd
+from vyos import debug
+from vyos.util import popen
+from vyos.util import cmd
from vyos.ifconfig.section import Section
@@ -35,10 +36,10 @@ class Control(Section):
# if debug is not explicitely disabled the the config, enable it
self.debug = ''
if kargs.get('debug', True):
- self.debug = debug('ifconfig')
+ self.debug = debug.enabled('ifconfig')
def _debug_msg (self, message):
- return debug_msg(message, self.debug)
+ return debug.message(message, self.debug)
def _popen(self, command):
return popen(command, self.debug)
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 14020e2d9..49c47cd85 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -21,48 +21,7 @@ from subprocess import PIPE
from subprocess import STDOUT
from subprocess import DEVNULL
-
-def debug(flag):
- """
- Check is a debug flag was set by the user.
- a flag can be set by touching the file /tmp/vyos.flag.debug
- with flag being the flag name, the current flags are:
- - developer: the code will drop into PBD on un-handled exception
- - ifconfig: prints command and sysfs access on stdout for interface
- The function returns an empty string if the flag was not set,
- """
-
- # this is to force all new flags to be registered here to be documented:
- if flag not in ['developer', 'ifconfig']:
- return ''
- for folder in ('/tmp', '/config'):
- if os.path.isfile(f'{folder}/vyos.{flag}.debug'):
- return flag
- return ''
-
-
-def debug_msg(message, flag=''):
- """
- print a debug message line on stdout if debugging is enabled for the flag
- """
-
- if debug(flag):
- print(f'DEBUG/{flag:<6} {message}')
-
- if not debug('developer'):
- return
-
- logfile = '/tmp/full-log'
- existed = os.path.exists(logfile)
-
- with open(logfile, 'a') as f:
- f.write(f'DEBUG/{flag:<6} {message}\n')
- if not existed:
- # at boot the file is created as root:vyattacfg
- # at runtime the file is created as user:vyattacfg
- # do not use run/cmd to not have a recursive call to this code
- os.system(f'chmod g+w {logfile}')
-
+from vyos import debug
# There is many (too many) ways to run command with python
# os.system, subprocess.Popen, subproces.{run,call,check_output}
@@ -98,7 +57,14 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
to get both stdout, and stderr: popen('command', stdout=PIPE, stderr=STDOUT)
to discard stdout and get stderr: popen('command', stdout=DEVNUL, stderr=PIPE)
"""
- debug_msg(f"cmd '{command}'", flag)
+
+ # log if the flag is set, otherwise log if command is set
+ if not debug.enabled(flag):
+ flag = 'command'
+
+ cmd_msg = f"cmd '{command}'"
+ debug.message(cmd_msg, flag)
+
use_shell = shell
stdin = None
if shell is None:
@@ -129,7 +95,8 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
nl = '\n' if decoded1 and decoded2 else ''
decoded = decoded1 + nl + decoded2
if decoded:
- debug_msg(f"returned:\n{decoded}", flag)
+ ret_msg = f"returned:\n{decoded}"
+ debug.message(ret_msg, flag)
return decoded, p.returncode
diff --git a/src/completion/list_ipoe.py b/src/completion/list_ipoe.py
new file mode 100755
index 000000000..c386b46a2
--- /dev/null
+++ b/src/completion/list_ipoe.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import argparse
+from vyos.util import popen
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--selector', help='Selector: username|ifname|sid', required=True)
+ args = parser.parse_args()
+
+ output, err = popen("accel-cmd -p 2002 show sessions {0}".format(args.selector))
+ if not err:
+ res = output.split("\r\n")
+ # Delete header from list
+ del res[:2]
+ print(' '.join(res))
diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py
index 0069218f6..a3bc76ef8 100755
--- a/src/conf_mode/bcast_relay.py
+++ b/src/conf_mode/bcast_relay.py
@@ -146,7 +146,7 @@ def generate(relay):
def apply(relay):
# first stop all running services
- call('sudo systemctl stop udp-broadcast-relay@{1..99}')
+ call('systemctl stop udp-broadcast-relay@{1..99}.service')
if (relay is None) or relay['disabled']:
return None
@@ -156,7 +156,7 @@ def apply(relay):
# Don't start individual instance when it's disabled
if r['disabled']:
continue
- call('sudo systemctl start udp-broadcast-relay@{0}'.format(r['id']))
+ call('systemctl start udp-broadcast-relay@{0}.service'.format(r['id']))
return None
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index a7b12fa01..567dfa4b3 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -31,7 +31,7 @@ parser = argparse.ArgumentParser()
parser.add_argument("--dhclient", action="store_true",
help="Started from dhclient-script")
-config_file = r'/etc/powerdns/recursor.conf'
+config_file = r'/run/powerdns/recursor.conf'
default_config_data = {
'allow_from': [],
@@ -152,17 +152,21 @@ def generate(dns):
if dns is None:
return None
+ dirname = os.path.dirname(config_file)
+ if not os.path.exists(dirname):
+ os.mkdir(dirname)
+
render(config_file, 'dns-forwarding/recursor.conf.tmpl', dns, trim_blocks=True)
return None
def apply(dns):
if dns is None:
# DNS forwarding is removed in the commit
- call("systemctl stop pdns-recursor")
+ call("systemctl stop pdns-recursor.service")
if os.path.isfile(config_file):
os.unlink(config_file)
else:
- call("systemctl restart pdns-recursor")
+ call("systemctl restart pdns-recursor.service")
if __name__ == '__main__':
args = parser.parse_args()
diff --git a/src/conf_mode/dynamic_dns.py b/src/conf_mode/dynamic_dns.py
index b76503419..038f77cf9 100755
--- a/src/conf_mode/dynamic_dns.py
+++ b/src/conf_mode/dynamic_dns.py
@@ -25,10 +25,7 @@ from vyos import ConfigError
from vyos.util import call
from vyos.template import render
-
-config_file = r'/etc/ddclient/ddclient.conf'
-cache_file = r'/var/cache/ddclient/ddclient.cache'
-pid_file = r'/var/run/ddclient/ddclient.pid'
+config_file = r'/run/ddclient/ddclient.conf'
# Mapping of service name to service protocol
default_service_protocol = {
@@ -47,9 +44,7 @@ default_service_protocol = {
default_config_data = {
'interfaces': [],
- 'cache_file': cache_file,
- 'deleted': False,
- 'pid_file': pid_file
+ 'deleted': False
}
def get_config():
@@ -220,39 +215,27 @@ def verify(dyndns):
def generate(dyndns):
# bail out early - looks like removal from running config
if dyndns['deleted']:
- if os.path.exists(config_file):
- os.unlink(config_file)
-
return None
- dirname = os.path.dirname(dyndns['pid_file'])
- if not os.path.exists(dirname):
- os.mkdir(dirname)
-
dirname = os.path.dirname(config_file)
if not os.path.exists(dirname):
os.mkdir(dirname)
render(config_file, 'dynamic-dns/ddclient.conf.tmpl', dyndns)
-
+
# Config file must be accessible only by its owner
os.chmod(config_file, S_IRUSR | S_IWUSR)
return None
def apply(dyndns):
- if os.path.exists(dyndns['cache_file']):
- os.unlink(dyndns['cache_file'])
-
- if os.path.exists('/etc/ddclient.conf'):
- os.unlink('/etc/ddclient.conf')
-
if dyndns['deleted']:
- call('/etc/init.d/ddclient stop')
- if os.path.exists(dyndns['pid_file']):
- os.unlink(dyndns['pid_file'])
+ call('systemctl stop ddclient.service')
+ if os.path.exists(config_file):
+ os.unlink(config_file)
+
else:
- call('/etc/init.d/ddclient restart')
+ call('systemctl restart ddclient.service')
return None
diff --git a/src/conf_mode/flow_accounting_conf.py b/src/conf_mode/flow_accounting_conf.py
index 3320075fb..1354488ac 100755
--- a/src/conf_mode/flow_accounting_conf.py
+++ b/src/conf_mode/flow_accounting_conf.py
@@ -346,9 +346,9 @@ def apply(config):
command = None
# Check if flow-accounting was removed and define command
if not config['flow-accounting-configured']:
- command = '/usr/bin/sudo /bin/systemctl stop uacctd'
+ command = 'systemctl stop uacctd.service'
else:
- command = '/usr/bin/sudo /bin/systemctl restart uacctd'
+ command = 'systemctl restart uacctd.service'
# run command to start or stop flow-accounting
cmd(command, raising=ConfigError, message='Failed to start/stop flow-accounting')
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py
index 7c2f79abc..dd5819f9f 100755
--- a/src/conf_mode/host_name.py
+++ b/src/conf_mode/host_name.py
@@ -173,7 +173,7 @@ def apply(config):
# restart pdns if it is used
ret = run('/usr/bin/rec_control ping')
if ret == 0:
- call('/etc/init.d/pdns-recursor restart >/dev/null')
+ call('systemctl restart pdns-recursor.service')
return None
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index b42765586..6733623c6 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -79,7 +79,7 @@ default_config_data = {
'server_push_route': [],
'server_reject_unconfigured': False,
'server_subnet': '',
- 'server_topology': 'net30',
+ 'server_topology': '',
'shared_secret_file': '',
'tls': False,
'tls_auth': '',
@@ -124,13 +124,10 @@ def getDefaultServer(network, topology, devtype):
Logic from openvpn's src/openvpn/helper.c.
Returns a dict with addresses or False if the input parameters were incorrect.
"""
- if not (topology and devtype):
- return False
-
if not (devtype == 'tun' or devtype == 'tap'):
return False
- if not network.prefixlen:
+ if not network.version == 4:
return False
elif (devtype == 'tun' and network.prefixlen > 29) or (devtype == 'tap' and network.prefixlen > 30):
return False
@@ -345,6 +342,7 @@ def get_config():
openvpn['server_topology'] = conf.return_value('server topology')
# Server-mode subnet (from which client IPs are allocated)
+ server_network = None
if conf.exists('server subnet'):
# server_network is used later in this function
server_network = IPv4Network(conf.return_value('server subnet'))
@@ -476,25 +474,31 @@ def get_config():
if not openvpn['tls_dh'] and openvpn['tls_key'] and checkCertHeader('-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']):
openvpn['tls_dh'] = 'none'
+ # set default server topology to net30
+ if openvpn['mode'] == 'server' and not openvpn['server_topology']:
+ openvpn['server_topology'] = 'net30'
+
# Set defaults where necessary.
- # If any of the input parameters are missing or wrong,
+ # If any of the input parameters are wrong,
# this will return False and no defaults will be set.
- default_server = getDefaultServer(server_network, openvpn['server_topology'], openvpn['type'])
- if default_server:
- # server-bridge doesn't require a pool so don't set defaults for it
- if not openvpn['bridge_member']:
- openvpn['server_pool'] = True
- if not openvpn['server_pool_start']:
- openvpn['server_pool_start'] = default_server['pool_start']
-
- if not openvpn['server_pool_stop']:
- openvpn['server_pool_stop'] = default_server['pool_stop']
-
- if not openvpn['server_pool_netmask']:
- openvpn['server_pool_netmask'] = default_server['pool_netmask']
-
- for client in openvpn['client']:
- client['remote_netmask'] = default_server['client_remote_netmask']
+ if server_network and openvpn['server_topology'] and openvpn['type']:
+ default_server = None
+ default_server = getDefaultServer(server_network, openvpn['server_topology'], openvpn['type'])
+ if default_server:
+ # server-bridge doesn't require a pool so don't set defaults for it
+ if not openvpn['bridge_member']:
+ openvpn['server_pool'] = True
+ if not openvpn['server_pool_start']:
+ openvpn['server_pool_start'] = default_server['pool_start']
+
+ if not openvpn['server_pool_stop']:
+ openvpn['server_pool_stop'] = default_server['pool_stop']
+
+ if not openvpn['server_pool_netmask']:
+ openvpn['server_pool_netmask'] = default_server['pool_netmask']
+
+ for client in openvpn['client']:
+ client['remote_netmask'] = default_server['client_remote_netmask']
return openvpn
diff --git a/src/conf_mode/le_cert.py b/src/conf_mode/le_cert.py
index 4b365a566..2db31d3fc 100755
--- a/src/conf_mode/le_cert.py
+++ b/src/conf_mode/le_cert.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2020 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
@@ -13,8 +13,6 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
import sys
import os
@@ -25,7 +23,6 @@ from vyos import ConfigError
from vyos.util import cmd
from vyos.util import call
-
vyos_conf_scripts_dir = vyos.defaults.directories['conf_mode']
dependencies = [
@@ -86,17 +83,17 @@ def generate(cert):
# certbot will attempt to reload nginx, even with 'certonly';
# start nginx if not active
- ret = call('systemctl is-active --quiet nginx.ervice')
+ ret = call('systemctl is-active --quiet nginx.service')
if ret:
- call('sudo systemctl start nginx.service')
+ call('systemctl start nginx.service')
request_certbot(cert)
def apply(cert):
if cert is not None:
- call('sudo systemctl restart certbot.timer')
+ call('systemctl restart certbot.timer')
else:
- call('sudo systemctl stop certbot.timer')
+ call('systemctl stop certbot.timer')
return None
for dep in dependencies:
diff --git a/src/conf_mode/mdns_repeater.py b/src/conf_mode/mdns_repeater.py
index bca1a537e..a652553f7 100755
--- a/src/conf_mode/mdns_repeater.py
+++ b/src/conf_mode/mdns_repeater.py
@@ -25,7 +25,6 @@ from vyos import ConfigError
from vyos.util import call
from vyos.template import render
-
config_file = r'/etc/default/mdns-repeater'
default_config_data = {
@@ -86,11 +85,11 @@ def generate(mdns):
def apply(mdns):
if (mdns is None) or mdns['disabled']:
- call('sudo systemctl stop mdns-repeater')
+ call('systemctl stop mdns-repeater.service')
if os.path.exists(config_file):
os.unlink(config_file)
else:
- call('sudo systemctl restart mdns-repeater')
+ call('systemctl restart mdns-repeater.service')
return None
diff --git a/src/conf_mode/system-syslog.py b/src/conf_mode/system-syslog.py
index 7d93ffdd5..9da3d9157 100755
--- a/src/conf_mode/system-syslog.py
+++ b/src/conf_mode/system-syslog.py
@@ -244,8 +244,8 @@ def verify(c):
def apply(c):
if not c:
- return run('systemctl stop syslog')
- return run('systemctl restart syslog')
+ return run('systemctl stop syslog.service')
+ return run('systemctl restart syslog.service')
if __name__ == '__main__':
try:
diff --git a/src/conf_mode/tftp_server.py b/src/conf_mode/tftp_server.py
index 229202304..94c8bcf03 100755
--- a/src/conf_mode/tftp_server.py
+++ b/src/conf_mode/tftp_server.py
@@ -106,7 +106,7 @@ def generate(tftpd):
def apply(tftpd):
# stop all services first - then we will decide
- call('systemctl stop tftpd@{0..20}')
+ call('systemctl stop tftpd@{0..20}.service')
# bail out early - e.g. service deletion
if tftpd is None:
diff --git a/src/etc/systemd/system/pdns-recursor.service.d/override.conf b/src/etc/systemd/system/pdns-recursor.service.d/override.conf
new file mode 100644
index 000000000..602d7b774
--- /dev/null
+++ b/src/etc/systemd/system/pdns-recursor.service.d/override.conf
@@ -0,0 +1,5 @@
+[Service]
+WorkingDirectory=
+WorkingDirectory=/run/powerdns
+ExecStart=
+ExecStart=/usr/sbin/pdns_recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no --config-dir=/run/powerdns
diff --git a/src/op_mode/dns_forwarding_restart.sh b/src/op_mode/dns_forwarding_restart.sh
index 8e556f2f0..64cc92115 100755
--- a/src/op_mode/dns_forwarding_restart.sh
+++ b/src/op_mode/dns_forwarding_restart.sh
@@ -2,7 +2,7 @@
if cli-shell-api existsEffective service dns forwarding; then
echo "Restarting the DNS forwarding service"
- systemctl restart pdns-recursor
+ systemctl restart pdns-recursor.service
else
echo "DNS forwarding is not configured"
fi
diff --git a/src/op_mode/dynamic_dns.py b/src/op_mode/dynamic_dns.py
index 405dd9f04..e4e5043d5 100755
--- a/src/op_mode/dynamic_dns.py
+++ b/src/op_mode/dynamic_dns.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2020 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
@@ -23,8 +23,7 @@ import time
from vyos.config import Config
from vyos.util import call
-
-cache_file = r'/var/cache/ddclient/ddclient.cache'
+cache_file = r'/run/ddclient/ddclient.cache'
OUT_TMPL_SRC = """
{%- for entry in hosts -%}
@@ -86,9 +85,9 @@ def show_status():
def update_ddns():
- call('systemctl stop ddclient')
+ call('systemctl stop ddclient.service')
os.remove(cache_file)
- call('systemctl start ddclient')
+ call('systemctl start ddclient.service')
def main():
diff --git a/src/op_mode/flow_accounting_op.py b/src/op_mode/flow_accounting_op.py
index 71fdfc288..bf8c39fd6 100755
--- a/src/op_mode/flow_accounting_op.py
+++ b/src/op_mode/flow_accounting_op.py
@@ -70,7 +70,7 @@ def _is_host(host):
# check if flow-accounting running
def _uacctd_running():
- command = '/usr/bin/sudo /bin/systemctl status uacctd > /dev/null'
+ command = 'systemctl status uacctd.service > /dev/null'
return run(command) == 0
# get list of interfaces
@@ -195,7 +195,7 @@ if not _uacctd_running():
# restart pmacct daemon
if cmd_args.action == 'restart':
# run command to restart flow-accounting
- cmd('/usr/bin/sudo /bin/systemctl restart uacctd',
+ cmd('systemctl restart uacctd.service',
message='Failed to restart flow-accounting')
# clear in-memory collected flows
diff --git a/src/op_mode/generate_ssh_server_key.py b/src/op_mode/generate_ssh_server_key.py
index f65d383c0..cbc9ef973 100755
--- a/src/op_mode/generate_ssh_server_key.py
+++ b/src/op_mode/generate_ssh_server_key.py
@@ -14,14 +14,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import sys
-
+from sys import exit
from vyos.util import ask_yes_no
from vyos.util import cmd
if not ask_yes_no('Do you really want to remove the existing SSH host keys?'):
- sys.exit(0)
+ exit(0)
-cmd('sudo rm -v /etc/ssh/ssh_host_*')
-cmd('sudo dpkg-reconfigure openssh-server')
-cmd('sudo systemctl restart ssh')
+cmd('rm -v /etc/ssh/ssh_host_*')
+cmd('dpkg-reconfigure openssh-server')
+cmd('systemctl restart ssh.service')
diff --git a/src/op_mode/ipoe-control.py b/src/op_mode/ipoe-control.py
new file mode 100755
index 000000000..7111498b2
--- /dev/null
+++ b/src/op_mode/ipoe-control.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 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/>.
+
+import sys
+import argparse
+
+from vyos.config import Config
+from vyos.util import popen, run
+
+cmd_dict = {
+ 'cmd_base' : '/usr/bin/accel-cmd -p 2002 ',
+ 'selector' : ['if', 'username', 'sid'],
+ 'actions' : {
+ 'show_sessions' : 'show sessions',
+ 'show_stat' : 'show stat',
+ 'terminate' : 'teminate'
+ }
+}
+
+def is_ipoe_configured():
+ if not Config().exists_effective('service ipoe-server'):
+ print("Service IPoE is not configured")
+ sys.exit(1)
+
+def main():
+ #parese args
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--action', help='Control action', required=True)
+ parser.add_argument('--selector', help='Selector username|ifname|sid', required=False)
+ parser.add_argument('--target', help='Target must contain username|ifname|sid', required=False)
+ args = parser.parse_args()
+
+
+ # Check is IPoE configured
+ is_ipoe_configured()
+
+ if args.action == "restart":
+ run(cmd_dict['cmd_base'] + "restart")
+ sys.exit(0)
+
+ if args.action in cmd_dict['actions']:
+ if args.selector in cmd_dict['selector'] and args.target:
+ run(cmd_dict['cmd_base'] + "{0} {1} {2}".format(args.action, args.selector, args.target))
+ else:
+ output, err = popen(cmd_dict['cmd_base'] + cmd_dict['actions'][args.action], decode='utf-8')
+ if not err:
+ print(output)
+ else:
+ print("IPoE server is not running")
+
+if __name__ == '__main__':
+ main()
diff --git a/src/op_mode/restart_dhcp_relay.py b/src/op_mode/restart_dhcp_relay.py
index 66dc435b3..af4fb2d15 100755
--- a/src/op_mode/restart_dhcp_relay.py
+++ b/src/op_mode/restart_dhcp_relay.py
@@ -39,7 +39,7 @@ if __name__ == '__main__':
if not c.exists_effective('service dhcp-relay'):
print("DHCP relay service not configured")
else:
- call('sudo systemctl restart isc-dhcp-relay.service')
+ call('systemctl restart isc-dhcp-server.service')
sys.exit(0)
elif args.ipv6:
@@ -47,7 +47,7 @@ if __name__ == '__main__':
if not c.exists_effective('service dhcpv6-relay'):
print("DHCPv6 relay service not configured")
else:
- call('sudo systemctl restart isc-dhcpv6-relay.service')
+ call('systemctl restart isc-dhcp-server6.service')
sys.exit(0)
else:
diff --git a/src/op_mode/show_dhcp.py b/src/op_mode/show_dhcp.py
index a79033f69..c49e604b7 100755
--- a/src/op_mode/show_dhcp.py
+++ b/src/op_mode/show_dhcp.py
@@ -193,7 +193,7 @@ if __name__ == '__main__':
sys.exit(0)
# if dhcp server is down, inactive leases may still be shown as active, so warn the user.
- if call('systemctl -q is-active isc-dhcpv4-server.service') != 0:
+ if call('systemctl -q is-active isc-dhcp-server.service') != 0:
print("WARNING: DHCP server is configured but not started. Data may be stale.")
if args.leases:
diff --git a/src/op_mode/show_dhcpv6.py b/src/op_mode/show_dhcpv6.py
index 18baa5517..d686defc0 100755
--- a/src/op_mode/show_dhcpv6.py
+++ b/src/op_mode/show_dhcpv6.py
@@ -179,7 +179,7 @@ if __name__ == '__main__':
sys.exit(0)
# if dhcp server is down, inactive leases may still be shown as active, so warn the user.
- if call('systemctl -q is-active isc-dhcpv6-server.service') != 0:
+ if call('systemctl -q is-active isc-dhcp-server6.service') != 0:
print("WARNING: DHCPv6 server is configured but not started. Data may be stale.")
if args.leases:
diff --git a/src/systemd/ddclient.service b/src/systemd/ddclient.service
new file mode 100644
index 000000000..a4d55827a
--- /dev/null
+++ b/src/systemd/ddclient.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Dynamic DNS Update Client
+RequiresMountsFor=/run
+ConditionPathExists=/run/ddclient/ddclient.conf
+After=vyos-router.service
+
+[Service]
+WorkingDirectory=/run/ddclient
+Type=forking
+PIDFile=/run/ddclient/ddclient.pid
+ExecStart=/usr/sbin/ddclient -cache /run/ddclient/ddclient.cache -pid /run/ddclient/ddclient.pid -file /run/ddclient/ddclient.conf
+
+[Install]
+WantedBy=multi-user.target