diff options
| author | Christian Poessinger <christian@poessinger.com> | 2020-05-19 22:32:22 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-19 22:32:22 +0200 | 
| commit | b708a375010c7240d11412d92f8552dbba2abdc0 (patch) | |
| tree | 01428d83fe5375545afee1f6359d35e0ab7ad2ba | |
| parent | b645e28edb6e92fe13e781c0d29853aebaceb711 (diff) | |
| parent | 43dd945c5a45c86c491892f30546d0179751bf4a (diff) | |
| download | vyos-1x-b708a375010c7240d11412d92f8552dbba2abdc0.tar.gz vyos-1x-b708a375010c7240d11412d92f8552dbba2abdc0.zip  | |
Merge pull request #414 from thomas-mangin/T2467
util: T2467: automatically add sudo to known commands
| -rw-r--r-- | python/vyos/util.py | 50 | ||||
| -rwxr-xr-x | src/conf_mode/http-api.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/https.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/igmp_proxy.py | 2 | ||||
| -rwxr-xr-x | src/conf_mode/lldp.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/ntp.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/ssh.py | 4 | ||||
| -rwxr-xr-x | src/conf_mode/vrrp.py | 6 | ||||
| -rwxr-xr-x | src/op_mode/flow_accounting_op.py | 2 | 
9 files changed, 51 insertions, 29 deletions
diff --git a/python/vyos/util.py b/python/vyos/util.py index 381cd0358..c2479aac4 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -21,12 +21,24 @@ import sys  # where it is used so it is as local as possible to the execution  # -# There is many (too many) ways to run command with python -# os.system, subprocess.Popen, subproces.{run,call,check_output} -# which all have slighty different behaviour -from subprocess import Popen, PIPE, STDOUT, DEVNULL + +def _need_sudo(command): +    return os.path.basename(command.split()[0]) in ('systemctl', ) + + +def _add_sudo(command): +    if _need_sudo(command): +        return 'sudo ' + command +    return command + + +from subprocess import Popen +from subprocess import PIPE +from subprocess import DEVNULL + +  def popen(command, flag='', shell=None, input=None, timeout=None, env=None, -          stdout=PIPE, stderr=PIPE, decode='utf-8'): +          stdout=PIPE, stderr=PIPE, decode='utf-8', autosudo=True):      """      popen is a wrapper helper aound subprocess.Popen      with it default setting it will return a tuple (out, err) @@ -52,15 +64,22 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,               the default is explicitely utf-8 which is python's own default      usage: -    to get both stdout, and stderr: popen('command', stdout=PIPE, stderr=STDOUT) -    to discard stdout and get stderr: popen('command', stdout=DEVNUL, stderr=PIPE) +    get both stdout and stderr: popen('command', stdout=PIPE, stderr=STDOUT) +    discard stdout and get stderr: popen('command', stdout=DEVNUL, stderr=PIPE)      """ + +    # airbag must be left as an import in the function as otherwise we have a +    # a circual import dependency      from vyos import debug      from vyos import airbag +      # log if the flag is set, otherwise log if command is set      if not debug.enabled(flag):          flag = 'command' +    if autosudo: +        command = _add_sudo(command) +      cmd_msg = f"cmd '{command}'"      debug.message(cmd_msg, flag) @@ -72,9 +91,11 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,              use_shell = True          if env:              use_shell = True +      if input:          stdin = PIPE          input = input.encode() if type(input) is str else input +      p = Popen(          command,          stdin=stdin, stdout=stdout, stderr=stderr, @@ -112,9 +133,9 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,  def run(command, flag='', shell=None, input=None, timeout=None, env=None, -        stdout=DEVNULL, stderr=PIPE, decode='utf-8'): +        stdout=DEVNULL, stderr=PIPE, decode='utf-8', autosudo=True):      """ -    A wrapper around vyos.util.popen, which discard the stdout and +    A wrapper around popen, which discard the stdout and      will return the error code of a command      """      _, code = popen( @@ -128,14 +149,15 @@ def run(command, flag='', shell=None, input=None, timeout=None, env=None,  def cmd(command, flag='', shell=None, input=None, timeout=None, env=None, -        stdout=PIPE, stderr=PIPE, decode='utf-8', +        stdout=PIPE, stderr=PIPE, decode='utf-8', autosudo=True,          raising=None, message='', expect=[0]):      """ -    A wrapper around vyos.util.popen, which returns the stdout and +    A wrapper around popen, which returns the stdout and      will raise the error code of a command -    raising: specify which call should be used when raising (default is OSError) +    raising: specify which call should be used when raising               the class should only require a string as parameter +             (default is OSError) with the error code      expect:  a list of error codes to consider as normal      """      decoded, code = popen( @@ -159,9 +181,9 @@ def cmd(command, flag='', shell=None, input=None, timeout=None, env=None,  def call(command, flag='', shell=None, input=None, timeout=None, env=None, -         stdout=PIPE, stderr=PIPE, decode='utf-8'): +         stdout=PIPE, stderr=PIPE, decode='utf-8', autosudo=True):      """ -    A wrapper around vyos.util.popen, which print the stdout and +    A wrapper around popen, which print the stdout and      will return the error code of a command      """      out, code = popen( diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py index 26f4aea7f..3b8a67ef6 100755 --- a/src/conf_mode/http-api.py +++ b/src/conf_mode/http-api.py @@ -92,9 +92,9 @@ def generate(http_api):  def apply(http_api):      if http_api is not None: -        call('sudo systemctl restart vyos-http-api.service') +        call('systemctl restart vyos-http-api.service')      else: -        call('sudo systemctl stop vyos-http-api.service') +        call('systemctl stop vyos-http-api.service')      for dep in dependencies:          cmd(f'{vyos_conf_scripts_dir}/{dep}', raising=ConfigError) diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py index 7d3a1b9cb..718e8375c 100755 --- a/src/conf_mode/https.py +++ b/src/conf_mode/https.py @@ -141,9 +141,9 @@ def generate(https):  def apply(https):      if https is not None: -        call('sudo systemctl restart nginx.service') +        call('systemctl restart nginx.service')      else: -        call('sudo systemctl stop nginx.service') +        call('systemctl stop nginx.service')  if __name__ == '__main__':      try: diff --git a/src/conf_mode/igmp_proxy.py b/src/conf_mode/igmp_proxy.py index 9fa591a2c..9cd7163f0 100755 --- a/src/conf_mode/igmp_proxy.py +++ b/src/conf_mode/igmp_proxy.py @@ -121,7 +121,7 @@ def generate(igmp_proxy):  def apply(igmp_proxy):      if igmp_proxy is None or igmp_proxy['disable']:           # IGMP Proxy support is removed in the commit -         call('sudo systemctl stop igmpproxy.service') +         call('systemctl stop igmpproxy.service')           if os.path.exists(config_file):               os.unlink(config_file)      else: diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py index d128c1fe6..6446074d8 100755 --- a/src/conf_mode/lldp.py +++ b/src/conf_mode/lldp.py @@ -228,10 +228,10 @@ def generate(lldp):  def apply(lldp):      if lldp:          # start/restart lldp service -        call('sudo systemctl restart lldpd.service') +        call('systemctl restart lldpd.service')      else:          # LLDP service has been terminated -        call('sudo systemctl stop lldpd.service') +        call('systemctl stop lldpd.service')          os.unlink(config_file)          os.unlink(vyos_config_file) diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py index 6d32f7fd6..85f60293d 100755 --- a/src/conf_mode/ntp.py +++ b/src/conf_mode/ntp.py @@ -103,10 +103,10 @@ def generate(ntp):  def apply(ntp):      if ntp is not None: -        call('sudo systemctl restart ntp.service') +        call('systemctl restart ntp.service')      else:          # NTP support is removed in the commit -        call('sudo systemctl stop ntp.service') +        call('systemctl stop ntp.service')          os.unlink(config_file)      return None diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py index ae79eac2d..76fdad8ae 100755 --- a/src/conf_mode/ssh.py +++ b/src/conf_mode/ssh.py @@ -124,10 +124,10 @@ def generate(ssh):  def apply(ssh):      if ssh is not None and 'port' in ssh.keys(): -        call("sudo systemctl restart ssh.service") +        call("systemctl restart ssh.service")      else:          # SSH access is removed in the commit -        call("sudo systemctl stop ssh.service") +        call("systemctl stop ssh.service")          if os.path.isfile(config_file):              os.unlink(config_file) diff --git a/src/conf_mode/vrrp.py b/src/conf_mode/vrrp.py index f358891a5..1a5ad1f8c 100755 --- a/src/conf_mode/vrrp.py +++ b/src/conf_mode/vrrp.py @@ -227,17 +227,17 @@ def apply(data):          if not VRRP.is_running():              print("Starting the VRRP process") -            ret = call("sudo systemctl restart keepalived.service") +            ret = call("systemctl restart keepalived.service")          else:              print("Reloading the VRRP process") -            ret = call("sudo systemctl reload keepalived.service") +            ret = call("systemctl reload keepalived.service")          if ret != 0:              raise ConfigError("keepalived failed to start")      else:          # VRRP is removed in the commit          print("Stopping the VRRP process") -        call("sudo systemctl stop keepalived.service") +        call("systemctl stop keepalived.service")          os.unlink(VRRP.location['daemon'])      return None diff --git a/src/op_mode/flow_accounting_op.py b/src/op_mode/flow_accounting_op.py index 219ad6316..bf8c39fd6 100755 --- a/src/op_mode/flow_accounting_op.py +++ b/src/op_mode/flow_accounting_op.py @@ -195,7 +195,7 @@ if not _uacctd_running():  # restart pmacct daemon  if cmd_args.action == 'restart':      # run command to restart flow-accounting -    cmd('sudo systemctl restart uacctd.service', +    cmd('systemctl restart uacctd.service',          message='Failed to restart flow-accounting')  # clear in-memory collected flows  | 
