Skip to content

Instantly share code, notes, and snippets.

@jkeifer
Last active June 9, 2020 01:03
Show Gist options
  • Save jkeifer/13dbe30f47b8ea0e83db76cb29a8609a to your computer and use it in GitHub Desktop.
Save jkeifer/13dbe30f47b8ea0e83db76cb29a8609a to your computer and use it in GitHub Desktop.
Simple tool to manage network namespaces as files
#!/bin/sh -eu
usage() {
cat <<EOF
$0 - utility to manage network namespaces through arbitrary files
Supported commands:
add FILE
create a network namespace referenced by FILE
del FILE
delete a network namespace referenced by FILE
exec FILE [ CMD ] [ CMD ARGS ]
run CMD in netns referenced by FILE. If no CMD is provided, \$SHELL will be run.
EOF
}
fatal() {
local EXIT=$1; shift
echo >&2 "$0: $@"
exit $EXIT
}
_mk() {
local MOUNT=${1}
if findmnt -t nsfs $MOUNT >/dev/null 2>&1; then
fatal 0 "Already a namespace mount: $MOUNT"
fi
# we need the file to exist to be a mount point
[ -e $MOUNT ] || touch $MOUNT
! mountpoint -q $MOUNT || fatal 1 "Already a mount point: $MOUNT"
unshare --net=${MOUNT} true
}
_rm() {
local MOUNT=${1}
# if the mount doesn't exist we can simply return
[ -e $MOUNT ] || return 0
umount $MOUNT
rm $MOUNT
}
_exec() {
local MOUNT=${1}; shift
MOUNT=$(realpath $MOUNT)
[ -f $MOUNT ] || fatal 1 "Not a file: $MOUNT"
[ -r $MOUNT ] || fatal 1 "Cannot read: $MOUNT"
findmnt -t nsfs $MOUNT >/dev/null 2>&1 || fatal 1 "Not a namespace mount: $MOUNT"
exec nsenter --net=$MOUNT "$@"
}
main() {
[ $(id -u) -eq 0 ] || fatal 1 "Must be run as root"
local CMD=${1:-help}; shift
local MOUNT=${1:?path to network namespace mount}; shift
case $CMD in
add|create|mk) _mk $MOUNT "$@" ;;
del|delete|remove|rm) _rm $MOUNT "$@" ;;
enter|run|exec) _exec $MOUNT "$@" ;;
*) usage ;;
esac
}
main ${@}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment