Some WIP linux network-namespace (reader) utils
To be re-orged once we likely formalize a new `.linux` subpkg but, provide basic `ip netns show` and lower-level `man namespaces` as read from the filesys under `/proc/{pid}/ns` once we get to supporting it more "seriously".ns_aware
parent
0a1ac80fee
commit
ead918f1b1
|
@ -0,0 +1,88 @@
|
||||||
|
# tractor: structured concurrent "actors".
|
||||||
|
# Copyright 2018-eternity Tyler Goodlet.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
|
Utils for Linux namespaces.
|
||||||
|
|
||||||
|
See `man namespaces` for the high level deats!
|
||||||
|
|
||||||
|
'''
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def get_ns_inode(
|
||||||
|
ns_type: str = 'net',
|
||||||
|
pid: int = os.getpid(),
|
||||||
|
) -> int:
|
||||||
|
'''
|
||||||
|
Return the `inode: int` for the namespace type `ns_type: str` for
|
||||||
|
the current process.
|
||||||
|
|
||||||
|
By default we use the "network namespace" since it is generallly
|
||||||
|
used to isolate all the networ-transport domains for all IPC
|
||||||
|
inside `tractor.ipc`.
|
||||||
|
|
||||||
|
See for linux:
|
||||||
|
- `man namespaces`,
|
||||||
|
- `man network_namespaces`,
|
||||||
|
> In addition, network namespaces isolate the UNIX domain
|
||||||
|
abstract socket name‐ space (see unix(7))
|
||||||
|
|
||||||
|
- `man unix`,
|
||||||
|
|
||||||
|
If pid: int` is passed then do the lookup to
|
||||||
|
`Path(f'/proc/{pid}/ns/{ns_type}') instead of for the current
|
||||||
|
pid.
|
||||||
|
|
||||||
|
'''
|
||||||
|
ns_dir = Path(f'/proc/{pid}/ns/')
|
||||||
|
ns_path: Path = ns_dir / ns_type
|
||||||
|
entry: str = os.readlink(f'{ns_path}')
|
||||||
|
_ns_type: str
|
||||||
|
boxed_inode: str
|
||||||
|
_ns_type, _, boxed_inode = entry.partition(':')
|
||||||
|
assert ns_type == _ns_type
|
||||||
|
|
||||||
|
inode_str: str = boxed_inode[1:-1]
|
||||||
|
return int(inode_str)
|
||||||
|
|
||||||
|
|
||||||
|
def get_netns(pid: int = os.getpid()) -> tuple[str|None, int]:
|
||||||
|
'''
|
||||||
|
Return the network namespace key-inode pair for the given process
|
||||||
|
id.
|
||||||
|
|
||||||
|
'''
|
||||||
|
out: str = subprocess.check_ouput([
|
||||||
|
'ip',
|
||||||
|
'netns',
|
||||||
|
'identify',
|
||||||
|
pid,
|
||||||
|
])
|
||||||
|
netns_key: str|None = None
|
||||||
|
if out.decode().strip():
|
||||||
|
netns_key: str = out
|
||||||
|
|
||||||
|
# signifies the "default" (really just not in use)
|
||||||
|
# net namespace.
|
||||||
|
return (
|
||||||
|
netns_key or 'default',
|
||||||
|
get_ns_inode(
|
||||||
|
ns_type='net',
|
||||||
|
pid=pid,
|
||||||
|
),
|
||||||
|
)
|
Loading…
Reference in New Issue