From 6d78f12b7eca797c00075eb190b7df2ee092391e Mon Sep 17 00:00:00 2001 From: Nataliia Solomko Date: Mon, 23 Dec 2024 15:17:56 +0200 Subject: [PATCH] utils: T6975: Add 'vrf' and 'netns' arguments to functions in 'vyos.utils.process' --- python/vyos/utils/process.py | 45 ++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/python/vyos/utils/process.py b/python/vyos/utils/process.py index d8aabb8226..da3d3f7fd0 100644 --- a/python/vyos/utils/process.py +++ b/python/vyos/utils/process.py @@ -20,10 +20,23 @@ from subprocess import STDOUT from subprocess import DEVNULL + +def get_wrapper(vrf, netns, auth): + wrapper = '' + if vrf: + wrapper = f'ip vrf exec {vrf} ' + elif netns: + wrapper = f'ip netns exec {netns} ' + if auth: + wrapper = f'{auth} {wrapper}' + return wrapper + + 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', auth='', vrf=None, + netns=None): """ - popen is a wrapper helper aound subprocess.Popen + popen is a wrapper helper around subprocess.Popen with it default setting it will return a tuple (out, err) out: the output of the program run err: the error code returned by the program @@ -45,6 +58,8 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None, - DEVNULL, discard the output decode: specify the expected text encoding (utf-8, ascii, ...) the default is explicitely utf-8 which is python's own default + vrf: run command in a VRF context + netns: run command in the named network namespace usage: get both stdout and stderr: popen('command', stdout=PIPE, stderr=STDOUT) @@ -60,6 +75,9 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None, if not debug.enabled(flag): flag = 'command' + wrapper = get_wrapper(vrf, netns, auth) + command = wrapper + command + cmd_msg = f"cmd '{command}'" debug.message(cmd_msg, flag) @@ -111,7 +129,7 @@ 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', vrf=None, netns=None): """ A wrapper around popen, which discard the stdout and will return the error code of a command @@ -122,13 +140,15 @@ def run(command, flag='', shell=None, input=None, timeout=None, env=None, input=input, timeout=timeout, env=env, shell=shell, decode=decode, + vrf=vrf, + netns=netns, ) return code def cmd(command, flag='', shell=None, input=None, timeout=None, env=None, stdout=PIPE, stderr=PIPE, decode='utf-8', raising=None, message='', - expect=[0], auth=''): + expect=[0], auth='', vrf=None, netns=None): """ A wrapper around popen, which returns the stdout and will raise the error code of a command @@ -139,13 +159,18 @@ def cmd(command, flag='', shell=None, input=None, timeout=None, env=None, expect: a list of error codes to consider as normal """ decoded, code = popen( - f'{auth} {command}'.strip(), flag, + command, flag, stdout=stdout, stderr=stderr, input=input, timeout=timeout, env=env, shell=shell, decode=decode, + auth=auth, + vrf=vrf, + netns=netns, ) if code not in expect: + wrapper = get_wrapper(vrf, netns, auth='') + command = wrapper + command feedback = message + '\n' if message else '' feedback += f'failed to run command: {command}\n' feedback += f'returned: {decoded}\n' @@ -159,7 +184,7 @@ def cmd(command, flag='', shell=None, input=None, timeout=None, env=None, def rc_cmd(command, flag='', shell=None, input=None, timeout=None, env=None, - stdout=PIPE, stderr=STDOUT, decode='utf-8'): + stdout=PIPE, stderr=STDOUT, decode='utf-8', vrf=None, netns=None): """ A wrapper around popen, which returns the return code of a command and stdout @@ -175,11 +200,14 @@ def rc_cmd(command, flag='', shell=None, input=None, timeout=None, env=None, input=input, timeout=timeout, env=env, shell=shell, decode=decode, + vrf=vrf, + netns=netns, ) return code, out + def call(command, flag='', shell=None, input=None, timeout=None, env=None, - stdout=None, stderr=None, decode='utf-8'): + stdout=None, stderr=None, decode='utf-8', vrf=None, netns=None): """ A wrapper around popen, which print the stdout and will return the error code of a command @@ -190,11 +218,14 @@ def call(command, flag='', shell=None, input=None, timeout=None, env=None, input=input, timeout=timeout, env=env, shell=shell, decode=decode, + vrf=vrf, + netns=netns, ) if out: print(out) return code + def process_running(pid_file): """ Checks if a process with PID in pid_file is running """ from psutil import pid_exists