blob: 463254c7f21c8b58d56b2c0cf785367275849848 (
plain)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
#!/bin/sh
set -eu
ARG0="$0"
BASE="/run/rootless-cni-infra"
wait_unshare_net() {
pid="$1"
# NOTE: busybox shell doesn't support the `for ((i=0; i < $MAX; i++)); do foo; done` statement
i=0
while :; do
if [ "$(readlink /proc/self/ns/net)" != "$(readlink /proc/${pid}/ns/net)" ]; then
break
fi
sleep 0.1
if [ $i -ge 10 ]; then
echo >&2 "/proc/${pid}/ns/net cannot be unshared"
exit 1
fi
i=$((i + 1))
done
}
# CLI subcommand: "alloc $CONTAINER_ID $NETWORK_NAME $POD_NAME"
cmd_entrypoint_alloc() {
if [ "$#" -ne 3 ]; then
echo >&2 "Usage: $ARG0 alloc CONTAINER_ID NETWORK_NAME POD_NAME"
exit 1
fi
ID="$1"
NET="$2"
K8S_POD_NAME="$3"
dir="${BASE}/${ID}"
mkdir -p "${dir}/attached" "${dir}/attached-args"
pid=""
if [ -f "${dir}/pid" ]; then
pid=$(cat "${dir}/pid")
else
unshare -n sleep infinity &
pid="$!"
wait_unshare_net "${pid}"
echo "${pid}" >"${dir}/pid"
nsenter -t "${pid}" -n ip link set lo up
fi
CNI_ARGS="IgnoreUnknown=1;K8S_POD_NAME=${K8S_POD_NAME}"
nwcount=$(find "${dir}/attached" -type f | wc -l)
CNI_IFNAME="eth${nwcount}"
export CNI_ARGS CNI_IFNAME
cnitool add "${NET}" "/proc/${pid}/ns/net" >"${dir}/attached/${NET}"
echo "${CNI_ARGS}" >"${dir}/attached-args/${NET}"
# return the result
ns="/proc/${pid}/ns/net"
echo "{\"ns\":\"${ns}\"}"
}
# CLI subcommand: "dealloc $CONTAINER_ID $NETWORK_NAME"
cmd_entrypoint_dealloc() {
if [ "$#" -ne 2 ]; then
echo >&2 "Usage: $ARG0 dealloc CONTAINER_ID NETWORK_NAME"
exit 1
fi
ID=$1
NET=$2
dir="${BASE}/${ID}"
if [ ! -f "${dir}/pid" ]; then
exit 0
fi
pid=$(cat "${dir}/pid")
if [ -f "${dir}/attached-args/${NET}" ]; then
CNI_ARGS=$(cat "${dir}/attached-args/${NET}")
export CNI_ARGS
fi
cnitool del "${NET}" "/proc/${pid}/ns/net"
rm -f "${dir}/attached/${NET}" "${dir}/attached-args/${NET}"
nwcount=$(find "${dir}/attached" -type f | wc -l)
if [ "${nwcount}" = 0 ]; then
kill -9 "${pid}"
rm -rf "${dir}"
fi
# return empty json
echo "{}"
}
# CLI subcommand: "is-idle"
cmd_entrypoint_is_idle() {
if [ ! -d ${BASE} ]; then
echo '{"idle": true}'
elif [ -z "$(ls -1 ${BASE})" ]; then
echo '{"idle": true}'
else
echo '{"idle": false}'
fi
}
# CLI subcommand: "print-cni-result $CONTAINER_ID $NETWORK_NAME"
cmd_entrypoint_print_cni_result() {
if [ "$#" -ne 2 ]; then
echo >&2 "Usage: $ARG0 print-cni-result CONTAINER_ID NETWORK_NAME"
exit 1
fi
ID=$1
NET=$2
# the result shall be CNI JSON
cat "${BASE}/${ID}/attached/${NET}"
}
# CLI subcommand: "print-netns-path $CONTAINER_ID"
cmd_entrypoint_print_netns_path() {
if [ "$#" -ne 1 ]; then
echo >&2 "Usage: $ARG0 print-netns-path CONTAINER_ID"
exit 1
fi
ID=$1
pid=$(cat "${BASE}/${ID}/pid")
path="/proc/${pid}/ns/net"
# return the result
echo "{\"path\":\"${path}\"}"
}
# CLI subcommand: "help"
cmd_entrypoint_help() {
echo "Usage: ${ARG0} COMMAND"
echo
echo "Rootless CNI Infra container"
echo
echo "Commands:"
echo " alloc Allocate a netns"
echo " dealloc Deallocate a netns"
echo " is-idle Print whether the infra container is idle"
echo " print-cni-result Print CNI result"
echo " print-netns-path Print netns path"
echo " help Print help"
echo " version Print version"
}
# CLI subcommand: "version"
cmd_entrypoint_version() {
echo "{\"version\": \"${ROOTLESS_CNI_INFRA_VERSION}\"}"
}
# parse args
command="${1:-}"
if [ -z "$command" ]; then
echo >&2 "No command was specified. Run \`${ARG0} help\` to see the usage."
exit 1
fi
command_func=$(echo "cmd_entrypoint_${command}" | sed -e "s/-/_/g")
if ! command -v "${command_func}" >/dev/null 2>&1; then
echo >&2 "Unknown command: ${command}. Run \`${ARG0} help\` to see the usage."
exit 1
fi
# start the command func
shift
"${command_func}" "$@"
|