]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/munet/mucmd.py
1 # -*- coding: utf-8 eval: (blacken-mode 1) -*-
2 # SPDX-License-Identifier: GPL-2.0-or-later
4 # December 5 2021, Christian Hopps <chopps@labn.net>
6 # Copyright 2021, LabN Consulting, L.L.C.
8 """A command that allows external command execution inside nodes."""
15 from pathlib
import Path
18 def newest_file_in(filename
, paths
, has_sibling
=None):
21 items
= (x
for y
in paths
for x
in Path(y
).rglob(filename
))
24 if has_sibling
and not e
.parent
.joinpath(has_sibling
).exists():
26 if not new
or st
.st_mtime_ns
> newst
.st_mtime_ns
:
34 ap
= argparse
.ArgumentParser(args
)
35 ap
.add_argument("-d", "--rundir", help="runtime directory for tempfiles, logs, etc")
36 ap
.add_argument("node", nargs
="?", help="node to enter or run command inside")
39 nargs
=argparse
.REMAINDER
,
40 help="optional shell-command to execute on NODE",
42 args
= ap
.parse_args()
44 configpath
= Path(args
.rundir
).joinpath("config.json")
46 configpath
, _
= newest_file_in(
48 ["/tmp/munet", "/tmp/mutest", "/tmp/unet-test"],
49 has_sibling
=args
.node
,
51 print(f
'Using "{configpath}"')
53 if not configpath
.exists():
54 print(f
'"{configpath}" not found')
56 rundir
= configpath
.parent
59 config
= json
.load(open(configpath
, encoding
="utf-8"))
60 nodes
= list(config
.get("topology", {}).get("nodes", []))
61 envcfg
= config
.get("mucmd", {}).get("env", {})
63 # If args.node is not a node it's part of shellcmd
64 if args
.node
and args
.node
not in nodes
:
66 args
.shellcmd
[0:0] = [args
.node
]
71 nodedir
= rundir
.joinpath(name
)
72 if not nodedir
.exists():
73 print('"{name}" node doesn\'t exist in "{rundir}"')
78 pidpath
= rundir
.joinpath("nspid")
79 pid
= open(pidpath
, encoding
="ascii").read().strip()
82 env
["MUNET_NODENAME"] = name
83 env
["MUNET_RUNDIR"] = str(rundir
)
86 envcfg
[k
] = envcfg
[k
].replace("%NAME%", str(name
))
87 envcfg
[k
] = envcfg
[k
].replace("%RUNDIR%", str(rundir
))
89 # Can't use -F if it's a new pid namespace
90 ecmd
= "/usr/bin/nsenter"
93 output
= subprocess
.check_output(["/usr/bin/nsenter", "--help"], encoding
="utf-8")
98 for flag
in ["-u", "-i", "-m", "-n", "-C", "-T"]:
99 if f
" {flag}," in output
:
101 eargs
.append(f
"--pid=/proc/{pid}/ns/pid_for_children")
102 eargs
.append(f
"--wd={rundir}")
103 eargs
.extend(["-t", pid
])
104 eargs
+= args
.shellcmd
105 # print("Using ", eargs)
106 return os
.execvpe(ecmd
, eargs
, {**env
, **envcfg
})
109 if __name__
== "__main__":
111 sys
.exit(exit_status
)