-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathnetns
executable file
·94 lines (82 loc) · 3.16 KB
/
netns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/bash
# Copyright (c) 2018 Austin Adams
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# This script is a wrapper around `ip netns add/delete' that allows
# network namespaces to have custom configuration files in /etc/, such
# as /etc/resolv.conf. It imitates how iproute2 persists network
# namespaces by bind-mounting /proc/self/ns/net to files in
# /var/run/netns, except with mount namespaces in /var/run/mountns
# instead, and then mounts an overlayfs merging /etc/ with /etc/netns/X
# to /etc/. nsdo will setns() to /var/run/mountns/X if it exists, making
# the program it runs use the netns-specific /etc/ changes.
set -e
usage() {
printf 'usage: netns.sh <add|del> <nsname>\n' >&2
exit 1
}
[[ $# -ne 2 ]] && {
usage
}
action=$1
nsname=$2
mountns_dir=/var/run/mountns
mountns_path=$mountns_dir/$nsname
# Can't use overlayfs to mount /etc/netns/X/ back onto /etc/ because
# this creates a loop: https://unix.stackexchange.com/q/578196/62375
# So put the /etc/ overlay directories at /var/ns-etc instead
etc_path=/var/ns-etc/$nsname
# This needs to be on the same filesystem as $etc_path
workdir_path=/var/ns-workdir/$nsname
_setup_mountns() {
# Overlayfs docs say the workdir needs to be empty
rm -rvf "$workdir_path"
mkdir -p "$mountns_dir" "$etc_path" "$workdir_path"
# systemd makes mountpoints shared by default, but they need to
# be private to bind-mount /proc/self/ns/mnt to /run/mountns/X.
# See:
# https://github.com/karelzak/util-linux/issues/289#issuecomment-188224471
if ! mountpoint "$mountns_dir" >/dev/null; then
mount --bind "$mountns_dir" "$mountns_dir"
mount --make-private "$mountns_dir"
fi
touch "$mountns_path"
unshare --mount="$mountns_path" \
mount -t overlay overlay -o "upperdir=$etc_path,lowerdir=/etc/,workdir=$workdir_path" /etc/
}
_teardown_mountns() {
if [[ -e $mountns_path ]]; then
nsenter --mount="$mountns_path" umount /etc/
umount "$mountns_path"
rm "$mountns_path"
fi
}
add() {
ip netns add "$nsname"
_setup_mountns
}
del() {
ip netns delete "$nsname"
_teardown_mountns
}
case $action in
add|del) $action ;;
*) usage ;;
esac