conlink 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/push.yml +17 -0
- package/Dockerfile +1 -1
- package/README.md +51 -16
- package/examples/test4-multiple/modes/all/deps +1 -0
- package/examples/test4-multiple/{base-compose.yaml → modes/base/compose.yaml} +3 -3
- package/examples/test4-multiple/{node1-compose.yaml → modes/node1/compose.yaml} +0 -3
- package/examples/test4-multiple/{nodes2-compose.yaml → modes/nodes2/compose.yaml} +0 -5
- package/examples/test4-multiple/modes/web/compose.yaml +5 -0
- package/examples/test4-multiple/modes/web/deps +1 -0
- package/mdc +108 -0
- package/package.json +2 -1
- package/scripts/copy.sh +52 -0
- package/scripts/wait.sh +73 -0
- package/src/conlink/core.cljs +35 -16
- package/.env +0 -3
- package/TODO +0 -34
- package/examples/data.dot +0 -457
- package/examples/net2dot-data.dot +0 -123
- package/examples/net2dot.dot +0 -457
- package/examples/test1-data.dot +0 -82
- package/examples/test1.dot +0 -286
- package/examples/test4-multiple/all-compose.yaml +0 -5
- package/examples/test4-multiple/web-network.yaml +0 -2
- package/host-build.yaml +0 -1
- package/inspect.json +0 -210
- package/modes0/a/deps +0 -1
- package/modes0/b/deps +0 -1
- package/modes0/c/deps +0 -1
- package/modes0/e/deps +0 -1
- package/modes1/a/deps +0 -1
- package/modes1/b/deps +0 -1
- package/modes1/c/deps +0 -1
- package/modes1/d/deps +0 -1
- package/modes2/a/deps +0 -1
- package/modes2/b/deps +0 -1
- package/modes2/c/deps +0 -1
- package/modes2/d/de +0 -1
- package/modes2/d/deps +0 -1
- package/modes3/accel/deps +0 -1
- package/modes4/a/deps +0 -1
- package/modes4/b/deps +0 -1
- package/net2dot.mjs +0 -21
- package/notes.txt +0 -82
- package/old/Dockerfile.bak +0 -26
- package/old/add-link.sh +0 -82
- package/old/conlink +0 -12
- package/old/conlink.cljs +0 -131
- package/old/dot_gitignore +0 -1
- package/old/examples/test2-compose.yaml +0 -32
- package/old/examples/test2-network.yaml +0 -42
- package/old/graphviz.cljs +0 -14
- package/old/move-link.sh +0 -108
- package/old/net2dot.cljs +0 -114
- package/old/net2dot.py +0 -122
- package/old/notes-old.txt +0 -97
- package/old/package.json +0 -16
- package/old/schema.yaml +0 -138
- package/old/schema.yaml.bak +0 -76
- package/old/set-cover-old.cljs +0 -205
- package/old/set-cover-old2.cljs +0 -150
- package/old/test2b-compose.yaml +0 -18
- package/old/veth-link.sh +0 -96
- package/read-stream.cljs +0 -12
- package/resolve-deps.cljs +0 -183
- package/schema-ish.yaml +0 -29
- package/tests/invalid-schema-1.yaml +0 -6
- package/tests/invalid-schema-2.yaml +0 -6
- package/tests/invalid-schema-3.yaml +0 -17
- package/tests/invalid-schema-4.yaml +0 -14
- package/tests/invalid-schema-5.yaml +0 -12
- package/tests/invalid-schema-6.yaml +0 -12
- package/tmp/conlink/.env +0 -1
- package/topo1.cljs +0 -35
- package/topo2.cljs +0 -36
- package/topo3.cljs +0 -44
- /package/{modes3/ab → examples/test4-multiple/modes/node1}/deps +0 -0
- /package/{modes3/mach3 → examples/test4-multiple/modes/nodes2}/deps +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Push (compose tests)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push: {}
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [ master ]
|
|
7
|
+
workflow_dispatch: {}
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
compose-tests:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v3
|
|
15
|
+
|
|
16
|
+
- name: stub step
|
|
17
|
+
run: "echo stub stub"
|
package/Dockerfile
CHANGED
|
@@ -24,7 +24,7 @@ FROM node:16-slim as run
|
|
|
24
24
|
RUN apt-get -y update
|
|
25
25
|
# Runtime deps and utilities
|
|
26
26
|
RUN apt-get -y install libpcap-dev tcpdump iproute2 iputils-ping curl \
|
|
27
|
-
iptables \
|
|
27
|
+
iptables bridge-utils \
|
|
28
28
|
openvswitch-switch openvswitch-testcontroller
|
|
29
29
|
|
|
30
30
|
COPY --from=build /app/ /app/
|
package/README.md
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
# conlink: Declarative Low-Level Networking for Containers
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
Create (layer 2 and layer 3) networking between containers using
|
|
4
5
|
a declarative configuration.
|
|
5
6
|
|
|
6
7
|
## Prerequisites
|
|
7
8
|
|
|
9
|
+
General:
|
|
10
|
+
* docker
|
|
8
11
|
* docker-compose version 1.25.4 or later.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
Other:
|
|
14
|
+
* For Open vSwtich (OVS) bridging, the `openvswitch` kernel module
|
|
15
|
+
must loaded on the host system (where docker engine is running).
|
|
16
|
+
* For podman usage (e.g. second part of `test3`), podman is required.
|
|
17
|
+
* For remote connections/links (e.g. `test5`), the `geneve` (and/or
|
|
18
|
+
`vxlan`) kernel module must be loaded on the host system (where
|
|
19
|
+
docker engine is running)
|
|
20
|
+
* For CloudFormation deployment (e.g. `test6`), the AWS CLI is
|
|
21
|
+
required.
|
|
12
22
|
|
|
13
23
|
## Usage Notes
|
|
14
24
|
|
|
@@ -34,6 +44,18 @@ will also be required for the conlink container. In particular, if the
|
|
|
34
44
|
container uses systemd, then it will likely use `SYS_NICE` and
|
|
35
45
|
`NET_BROADCAST` and conlink will likewise need those capabilities.
|
|
36
46
|
|
|
47
|
+
### Bridging: Open vSwtich/OVS or Linux bridge
|
|
48
|
+
|
|
49
|
+
Conlink creates bridges/switches and connects veth container links to
|
|
50
|
+
those bridges (specified by `bridge:` in the link specification).
|
|
51
|
+
By default, conlink will attempt to create Open vSwitch/OVS bridges
|
|
52
|
+
for these connections, however, if the kernel does not provide support
|
|
53
|
+
(`openvswitch` kernel module loaded), then conlink will fallback to
|
|
54
|
+
using standard Linux bridges. The fallback behavior can be changed by
|
|
55
|
+
setting the `--bridge-mode` option to either "ovs" or "linux". If the
|
|
56
|
+
bridge mode is set to "ovs" then conlink will fail to start if the
|
|
57
|
+
`openvswitch` kernel module is not detected.
|
|
58
|
+
|
|
37
59
|
## Network Configuration Syntax
|
|
38
60
|
|
|
39
61
|
Network configuration can either be loaded directly from configuration
|
|
@@ -71,8 +93,8 @@ The following table describes the link properties:
|
|
|
71
93
|
| route | * | string | | ip route add args |
|
|
72
94
|
| nat | * | IP | | DNAT/SNAT to IP |
|
|
73
95
|
| netem | * | string | | tc qdisc NetEm options |
|
|
74
|
-
| mode | 5 |
|
|
75
|
-
| vlanid | vlan |
|
|
96
|
+
| mode | 5 | string | | virt intf mode |
|
|
97
|
+
| vlanid | vlan | number | | VLAN ID |
|
|
76
98
|
|
|
77
99
|
- 1 - veth, dummy, vlan, ipvlan, macvlan, ipvtap, macvtap
|
|
78
100
|
- 2 - defaults to outer compose service
|
|
@@ -186,11 +208,11 @@ From the second node ping an address in the internet service:
|
|
|
186
208
|
docker-compose -f examples/test2-compose.yaml exec --index 2 node ping 8.8.8.8
|
|
187
209
|
```
|
|
188
210
|
|
|
189
|
-
Scale the nodes from 2 to 5 and then ping
|
|
211
|
+
Scale the nodes from 2 to 5 and then ping the fifth node from the second:
|
|
190
212
|
|
|
191
213
|
```
|
|
192
214
|
docker-compose -f examples/test2-compose.yaml up -d --scale node=5
|
|
193
|
-
docker-compose -f examples/test2-compose.yaml exec --index
|
|
215
|
+
docker-compose -f examples/test2-compose.yaml exec --index 2 node ping 10.0.1.5
|
|
194
216
|
```
|
|
195
217
|
|
|
196
218
|
|
|
@@ -258,11 +280,10 @@ container (`node1`) and switch (`s1`) that is connected to the router
|
|
|
258
280
|
defined in the first compose file.
|
|
259
281
|
|
|
260
282
|
```
|
|
261
|
-
|
|
262
|
-
docker-compose up --build --force-recreate
|
|
283
|
+
MODES_DIR=./examples/test4-multiple/modes ./mdc node1 up --build --force-recreate
|
|
263
284
|
```
|
|
264
285
|
|
|
265
|
-
Ping the router host from `
|
|
286
|
+
Ping the router host from `node1`:
|
|
266
287
|
|
|
267
288
|
```
|
|
268
289
|
docker-compose exec node1 ping 10.0.0.100
|
|
@@ -273,8 +294,7 @@ two node2 replicas and a switch (`s2`) that is connected to the
|
|
|
273
294
|
router.
|
|
274
295
|
|
|
275
296
|
```
|
|
276
|
-
|
|
277
|
-
docker-compose up --build --force-recreate
|
|
297
|
+
MODES_DIR=./examples/test4-multiple/modes ./mdc node1,nodes2 up --build --force-recreate
|
|
278
298
|
```
|
|
279
299
|
|
|
280
300
|
From both `node2` replicas, ping `node1` across the switches and `r0` router:
|
|
@@ -284,13 +304,20 @@ docker-compose exec --index 1 node2 ping 10.1.0.1
|
|
|
284
304
|
docker-compose exec --index 2 node2 ping 10.1.0.1
|
|
285
305
|
```
|
|
286
306
|
|
|
307
|
+
From `node1`, ping both `node2` replicas across the switches and `r0` router:
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
docker-compose exec node1 ping 10.2.0.1
|
|
311
|
+
docker-compose exec node1 ping 10.2.0.2
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
|
|
287
315
|
Restart the compose instance and add another compose file that starts
|
|
288
316
|
conlink using an addition network file `web-network.yaml`. The network
|
|
289
317
|
file starts up a simple web server on the router.
|
|
290
318
|
|
|
291
319
|
```
|
|
292
|
-
|
|
293
|
-
docker-compose up --build --force-recreate
|
|
320
|
+
MODES_DIR=./examples/test4-multiple/modes ./mdc node1,nodes2,web up --build --force-recreate
|
|
294
321
|
```
|
|
295
322
|
|
|
296
323
|
From the second `node2`, perform a download from the web server running on the
|
|
@@ -300,6 +327,14 @@ router host:
|
|
|
300
327
|
docker-compose exec --index 2 node2 wget -O- 10.0.0.100
|
|
301
328
|
```
|
|
302
329
|
|
|
330
|
+
We can simplify the above launch by using the `all` mode, which contains
|
|
331
|
+
depends on `node1`, `nodes2`, and `web`. Each of those modes depends on
|
|
332
|
+
`base`, so there's no need to specify that again (transitive deps).
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
MODES_DIR=./examples/test4-multiple/modes ./mdc all up --build --force-recreate
|
|
336
|
+
```
|
|
337
|
+
|
|
303
338
|
Remove the `.env` file as a final cleanup step:
|
|
304
339
|
|
|
305
340
|
```
|
|
@@ -390,8 +425,8 @@ Show the links in both node containers to see that the MAC addresses
|
|
|
390
425
|
are `00:0a:0b:0c:0d:0*` and the MTUs are set to `4111`.
|
|
391
426
|
|
|
392
427
|
```
|
|
393
|
-
docker-compose -f examples/test7-compose.yaml exec --index 1 ip link
|
|
394
|
-
docker-compose -f examples/test7-compose.yaml exec --index 2 ip link
|
|
428
|
+
docker-compose -f examples/test7-compose.yaml exec --index 1 node ip link
|
|
429
|
+
docker-compose -f examples/test7-compose.yaml exec --index 2 node ip link
|
|
395
430
|
```
|
|
396
431
|
|
|
397
432
|
Ping the second node from the first to show the the NetEm setting is
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node1 nodes2 web
|
|
@@ -10,7 +10,7 @@ services:
|
|
|
10
10
|
- {bridge: s0, dev: e0, ip: "10.0.0.100/24"}
|
|
11
11
|
|
|
12
12
|
network:
|
|
13
|
-
build: {context:
|
|
13
|
+
build: {context: .}
|
|
14
14
|
image: conlink
|
|
15
15
|
pid: host
|
|
16
16
|
network_mode: none
|
|
@@ -19,7 +19,7 @@ services:
|
|
|
19
19
|
volumes:
|
|
20
20
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
21
21
|
- /var/lib/docker:/var/lib/docker
|
|
22
|
-
-
|
|
22
|
+
- ./:/test
|
|
23
23
|
working_dir: /test
|
|
24
|
-
command: /app/build/conlink.js --compose-file ${COMPOSE_FILE
|
|
24
|
+
command: /app/build/conlink.js --compose-file ${COMPOSE_FILE:?COMPOSE_FILE must be set}
|
|
25
25
|
|
|
@@ -4,11 +4,7 @@ x-network:
|
|
|
4
4
|
links:
|
|
5
5
|
- {service: r0, bridge: s2, dev: e2, ip: "10.2.0.100/24"}
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
services:
|
|
9
|
-
network:
|
|
10
|
-
command: /app/build/conlink.js --compose-file ${COMPOSE_FILE:-examples/test4-multiple/nodes2-compose.yaml}
|
|
11
|
-
|
|
12
8
|
node2:
|
|
13
9
|
image: alpine
|
|
14
10
|
scale: 2
|
|
@@ -17,4 +13,3 @@ services:
|
|
|
17
13
|
x-network:
|
|
18
14
|
links:
|
|
19
15
|
- {bridge: s2, ip: "10.2.0.1/16", route: "default via 10.2.0.100"}
|
|
20
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
base
|
package/mdc
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
shopt -s dotglob # recursive copy of dot files too
|
|
5
|
+
|
|
6
|
+
die() { echo >&2 "${*}"; exit 1; }
|
|
7
|
+
vecho() { [ "${VERBOSE}" ] && echo >&2 "${*}" || true; }
|
|
8
|
+
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
|
9
|
+
|
|
10
|
+
[ "${*}" ] || die "Usage: ${0} MODES [DOCKER-COMPOSE-ARGS]"
|
|
11
|
+
|
|
12
|
+
VERBOSE="${VERBOSE:-}"
|
|
13
|
+
MODES_DIR="${MODES_DIR:-./modes}"
|
|
14
|
+
ENV_FILE="${ENV_FILE:-.env}"
|
|
15
|
+
MDC_FILES_DIR="${MDC_FILES_DIR:-./.files}"
|
|
16
|
+
LS=$(which ls)
|
|
17
|
+
RESOLVE_DEPS="${RESOLVE_DEPS-./node_modules/@lonocloud/resolve-deps/resolve-deps.py}"
|
|
18
|
+
DOCKER_COMPOSE="${DOCKER_COMPOSE:-docker-compose}"
|
|
19
|
+
|
|
20
|
+
MODE_SPEC="${1}"; shift
|
|
21
|
+
if [ "${RESOLVE_DEPS}" ]; then
|
|
22
|
+
MODES="$(${RESOLVE_DEPS} "${MODES_DIR}" ${MODE_SPEC})"
|
|
23
|
+
else
|
|
24
|
+
MODES="${MODE_SPEC//,/ }"
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
echo >&2 "MODES: ${MODES}"
|
|
28
|
+
vecho "ENV_FILE: ${ENV_FILE}"
|
|
29
|
+
|
|
30
|
+
declare -A FINISHED
|
|
31
|
+
COMPOSE_FILE=./.compose-empty.yaml
|
|
32
|
+
COMPOSE_PROFILES=
|
|
33
|
+
MDC_MODE_DIRS=
|
|
34
|
+
cat /dev/null > ${ENV_FILE}-mdc-tmp
|
|
35
|
+
echo -e "version: '2.4'\nservices: {}" > ./.compose-empty.yaml
|
|
36
|
+
|
|
37
|
+
vecho "Removing ${MDC_FILES_DIR}"
|
|
38
|
+
case "$(basename ${MDC_FILES_DIR})" in
|
|
39
|
+
.|/) die "MDC_FILES_DIR must not be '.' or '/'";;
|
|
40
|
+
esac
|
|
41
|
+
[ -d "${MDC_FILES_DIR}" ] && rm -r${VERBOSE:+v} ${MDC_FILES_DIR}/
|
|
42
|
+
mkdir -p "${MDC_FILES_DIR}"
|
|
43
|
+
|
|
44
|
+
for mode in ${MODES}; do
|
|
45
|
+
# Only process each mode once
|
|
46
|
+
[ "${FINISHED[${mode}]}" ] && continue
|
|
47
|
+
FINISHED["${mode}"]=1
|
|
48
|
+
|
|
49
|
+
# mode dir must exist
|
|
50
|
+
[ -d "${MODES_DIR}/${mode}" ] || \
|
|
51
|
+
die "No mode dir found for ${mode}"
|
|
52
|
+
|
|
53
|
+
MDC_MODE_DIRS="${MDC_MODE_DIRS},${MODES_DIR}/${mode}"
|
|
54
|
+
|
|
55
|
+
# mode can refer to a compose file in multiple ways
|
|
56
|
+
cfiles="${MODES_DIR}/${mode}/compose.yaml ${MODES_DIR}/${mode}/compose.yml ${MODES_DIR}/${mode}/docker-compose.yaml ${MODES_DIR}/${mode}/docker-compose.yml"
|
|
57
|
+
for cfile in ${cfiles}; do
|
|
58
|
+
if [ -e "${cfile}" ]; then
|
|
59
|
+
COMPOSE_FILE="${COMPOSE_FILE}:${cfile}"
|
|
60
|
+
break
|
|
61
|
+
fi
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
# Add MODE_ prefixed compose profile for each mode
|
|
65
|
+
COMPOSE_PROFILES="${COMPOSE_PROFILES},MODE_${mode}"
|
|
66
|
+
|
|
67
|
+
# if there is a mode specific env file then include it
|
|
68
|
+
efiles="${MODES_DIR}/${mode}/env ${MODES_DIR}/${mode}/.env"
|
|
69
|
+
for efile in ${efiles}; do
|
|
70
|
+
if [ -e "${efile}" ]; then
|
|
71
|
+
echo "### mdc begin mode ${mode}" >> ${ENV_FILE}-mdc-tmp
|
|
72
|
+
vecho "cat ${efile} >> ${ENV_FILE}-mdc-tmp"
|
|
73
|
+
cat ${efile} >> ${ENV_FILE}-mdc-tmp
|
|
74
|
+
echo "### mdc end mode ${mode}" >> ${ENV_FILE}-mdc-tmp
|
|
75
|
+
fi
|
|
76
|
+
done
|
|
77
|
+
|
|
78
|
+
# if there are mode specific files then copy them to MDC_FILES_DIR
|
|
79
|
+
if [ -d "${MODES_DIR}/${mode}" ]; then
|
|
80
|
+
for vfd in $(cd ${MODES_DIR}/${mode} && $LS -d */files 2>/dev/null || true); do
|
|
81
|
+
dest=${MDC_FILES_DIR}/${vfd%/files}
|
|
82
|
+
mkdir -p ${dest}
|
|
83
|
+
vecho cp -a ${MODES_DIR}/${mode}/${vfd}/* ${dest}
|
|
84
|
+
cp -a ${MODES_DIR}/${mode}/${vfd}/* ${dest}
|
|
85
|
+
done
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
COMPOSE_FILE="${COMPOSE_FILE#:}"
|
|
90
|
+
vecho "COMPOSE_FILE: ${COMPOSE_FILE}"
|
|
91
|
+
echo "COMPOSE_FILE=${COMPOSE_FILE}" >> ${ENV_FILE}-mdc-tmp
|
|
92
|
+
echo "COMPOSE_DIR=$(realpath $(dirname ${ENV_FILE}))" >> ${ENV_FILE}-mdc-tmp
|
|
93
|
+
|
|
94
|
+
COMPOSE_PROFILES="${COMPOSE_PROFILES#,}"
|
|
95
|
+
vecho "COMPOSE_PROFILES: ${COMPOSE_PROFILES}"
|
|
96
|
+
echo "COMPOSE_PROFILES=${COMPOSE_PROFILES}" >> ${ENV_FILE}-mdc-tmp
|
|
97
|
+
|
|
98
|
+
MDC_MODE_DIRS="${MDC_MODE_DIRS#,}"
|
|
99
|
+
vecho "MDC_MODE_DIRS: ${MDC_MODE_DIRS}"
|
|
100
|
+
echo "MDC_MODE_DIRS=\"${MDC_MODE_DIRS}\"" >> ${ENV_FILE}-mdc-tmp
|
|
101
|
+
|
|
102
|
+
vecho mv ${ENV_FILE}-mdc-tmp ${ENV_FILE}
|
|
103
|
+
mv ${ENV_FILE}-mdc-tmp ${ENV_FILE}
|
|
104
|
+
|
|
105
|
+
if [ "${*}" ]; then
|
|
106
|
+
vecho "Running: ${DOCKER_COMPOSE} --env-file "${ENV_FILE}" ${@}"
|
|
107
|
+
exec ${DOCKER_COMPOSE} --env-file "${ENV_FILE}" "${@}"
|
|
108
|
+
fi
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conlink",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "conlink - Declarative Low-Level Networking for Containers",
|
|
5
5
|
"repository": "https://github.com/LonoCloud/conlink",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"dependencies": {
|
|
8
|
+
"@lonocloud/resolve-deps": "^0.0.2",
|
|
8
9
|
"ajv": "^8.12.0",
|
|
9
10
|
"dockerode": "^3.3.4",
|
|
10
11
|
"nbb": "^1.2.179",
|
package/scripts/copy.sh
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Viasat, Inc
|
|
4
|
+
# Licensed under MPL 2.0
|
|
5
|
+
|
|
6
|
+
# Add files from SRC_DIR to DST_DIR with string interpolation.
|
|
7
|
+
# Any '{{FOO}}' tokens are replaced with value of corresponding
|
|
8
|
+
# environment variable FOO (but only if defined).
|
|
9
|
+
|
|
10
|
+
die() { local ret=${1}; shift; echo >&2 "${*}"; exit $ret; }
|
|
11
|
+
|
|
12
|
+
case "${1}" in -T|--template) TEMPLATE=1; shift ;; esac
|
|
13
|
+
|
|
14
|
+
src_dir="${1}"; shift || die 2 "Usage: ${0} [-T|--template] SRC_DIR DST_DIR"
|
|
15
|
+
dst_dir="${1}"; shift || die 2 "Usage: ${0} [-T|--template] SRC_DIR DST_DIR"
|
|
16
|
+
[ "${1}" = "--" ] && shift
|
|
17
|
+
|
|
18
|
+
[ -d "${src_dir}" ] || die 2 "Not a directory: '${src_dir}'"
|
|
19
|
+
[ -d "${dst_dir}" ] || die 2 "Not a directory: '${dst_dir}'"
|
|
20
|
+
|
|
21
|
+
(cd "${src_dir}" && find . -type f) | while read src_file; do
|
|
22
|
+
src="${src_dir}/${src_file}"
|
|
23
|
+
dst="${dst_dir}/${src_file}"
|
|
24
|
+
mkdir -p $(dirname "${dst}") || die 1 "Failed to make target directory"
|
|
25
|
+
echo cp -a "${src}" "${dst}"
|
|
26
|
+
cp -a "${src}" "${dst}" || die 1 "Failed to copy file"
|
|
27
|
+
# TODO: make this configurable
|
|
28
|
+
chown root.root "${dst}" || die 1 "Unable to set ownership"
|
|
29
|
+
chmod +w "${dst}" || die 1 "Unable to make writable"
|
|
30
|
+
|
|
31
|
+
[ -z "${TEMPLATE}" ] && continue
|
|
32
|
+
|
|
33
|
+
tmpfile="$(mktemp)"
|
|
34
|
+
# match all {{FOO}} style variables and replace from environment
|
|
35
|
+
for v in $(cat "${dst}" | grep -o '{{[^ }{]*}}' | sed 's/[}{]//g' | sort -u); do
|
|
36
|
+
if set | grep -qs "^${v}="; then
|
|
37
|
+
val=$(set | grep "^${v}=" | cut -f 2 -d '=' \
|
|
38
|
+
| sed "s/^['\"]\(.*\)['\"]$/\1/" \
|
|
39
|
+
| sed 's/[\/&]/\\&/g')
|
|
40
|
+
echo "Replacing '{{${v}}}' with '${val}' in '${dst}'"
|
|
41
|
+
sed "s/{{${v}}}/${val}/g" "${dst}" > "${tmpfile}"
|
|
42
|
+
cp "${tmpfile}" "${dst}"
|
|
43
|
+
fi
|
|
44
|
+
done
|
|
45
|
+
rm -f "${tmpfile}"
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
if [ "${*}" ]; then
|
|
49
|
+
exec "${@}"
|
|
50
|
+
else
|
|
51
|
+
true
|
|
52
|
+
fi
|
package/scripts/wait.sh
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2023, Viasat, Inc
|
|
4
|
+
# Licensed under MPL 2.0
|
|
5
|
+
|
|
6
|
+
die() { local ret=${1}; shift; echo >&2 "${*}"; exit $ret; }
|
|
7
|
+
|
|
8
|
+
NC=$(command -v nc 2>/dev/null)
|
|
9
|
+
SOCAT=$(command -v socat 2>/dev/null)
|
|
10
|
+
BASH=$(command -v bash 2>/dev/null)
|
|
11
|
+
WAIT_SLEEP=${WAIT_SLEEP:-1}
|
|
12
|
+
|
|
13
|
+
do_sleep() {
|
|
14
|
+
echo "Failed: '${typ} ${arg}'. Sleep ${WAIT_SLEEP} seconds before retry"
|
|
15
|
+
sleep ${WAIT_SLEEP}
|
|
16
|
+
}
|
|
17
|
+
check_tcp() {
|
|
18
|
+
if [ "${NC}" ]; then ${NC} -z -w 1 ${1} ${2} > /dev/null
|
|
19
|
+
elif [ "${SOCAT}" ]; then ${SOCAT} /dev/null TCP:${1}:${2},connect-timeout=2
|
|
20
|
+
elif [ "${BASH}" ]; then timeout 1 ${BASH} -c "echo > /dev/tcp/${1}/${2}"
|
|
21
|
+
else die 1 "Could not find nc, socat, or bash"
|
|
22
|
+
fi
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
while [ "${*}" ]; do
|
|
26
|
+
typ="${1}"; shift
|
|
27
|
+
arg="${1}"
|
|
28
|
+
[ "${arg}" = "--" ] && die 2 "No arg found for type '${typ}'"
|
|
29
|
+
case "${typ}" in
|
|
30
|
+
--) break; ;;
|
|
31
|
+
-f|--file)
|
|
32
|
+
while [ ! -e "${arg}" ]; do do_sleep; done
|
|
33
|
+
echo "File '${arg}' exists"
|
|
34
|
+
;;
|
|
35
|
+
-i|--if|--intf)
|
|
36
|
+
while [ ! -e /sys/class/net/${arg}/ifindex ]; do do_sleep; done
|
|
37
|
+
echo "Interface '${arg}' exists"
|
|
38
|
+
;;
|
|
39
|
+
-I|--ip)
|
|
40
|
+
while ! grep -qs "^${arg}\>" /proc/net/route; do do_sleep; done
|
|
41
|
+
echo "Interface '${arg}' has IP/routing"
|
|
42
|
+
;;
|
|
43
|
+
-t|--tcp)
|
|
44
|
+
host=${arg%:*}
|
|
45
|
+
port=${arg##*:}
|
|
46
|
+
[ "${host}" -a "${port}" ] || die 2 "Illegal host/port '${arg}'"
|
|
47
|
+
while ! check_tcp ${host} ${port}; do do_sleep; done
|
|
48
|
+
echo "TCP listener is reachable at '${arg}' "
|
|
49
|
+
;;
|
|
50
|
+
-u|--umask)
|
|
51
|
+
umask ${arg}
|
|
52
|
+
echo "Set umask to ${arg}"
|
|
53
|
+
;;
|
|
54
|
+
-c|--cmd|--command)
|
|
55
|
+
while ! ${arg}; do do_sleep; done
|
|
56
|
+
echo "Command successful: ${arg}"
|
|
57
|
+
;;
|
|
58
|
+
-s|--sleep)
|
|
59
|
+
WAIT_SLEEP=${arg}
|
|
60
|
+
echo "Changed WAIT_SLEEP from ${WAIT_SLEEP} to ${arg}"
|
|
61
|
+
;;
|
|
62
|
+
*)
|
|
63
|
+
echo "Unknown option: ${typ}"
|
|
64
|
+
exit 1
|
|
65
|
+
;;
|
|
66
|
+
esac
|
|
67
|
+
shift
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
if [ "${*}" ]; then
|
|
71
|
+
echo "Running: ${*}"
|
|
72
|
+
exec ${*}
|
|
73
|
+
fi
|
package/src/conlink/core.cljs
CHANGED
|
@@ -27,9 +27,9 @@ General Options:
|
|
|
27
27
|
-v, --verbose Show verbose output (stderr)
|
|
28
28
|
[env: VERBOSE]
|
|
29
29
|
--show-config Print loaded network config JSON and exit
|
|
30
|
-
--bridge-mode BRIDGE-MODE Bridge mode (ovs or
|
|
31
|
-
bridge/switch connections
|
|
32
|
-
[default:
|
|
30
|
+
--bridge-mode BRIDGE-MODE Bridge mode (ovs, linux, or auto)
|
|
31
|
+
to use for bridge/switch connections
|
|
32
|
+
[default: auto] [env: CONLINK_BRIDGE_MODE]
|
|
33
33
|
--network-file NETWORK-FILE... Network config file
|
|
34
34
|
--compose-file COMPOSE-FILE... Docker compose file with network config
|
|
35
35
|
--compose-project NAME Docker compose project name for resolving
|
|
@@ -651,17 +651,38 @@ General Options:
|
|
|
651
651
|
(fatal 2 "Could not find config-schema" orig-config-schema)))
|
|
652
652
|
|
|
653
653
|
(defn startup-checks
|
|
654
|
-
"Check startup state and
|
|
655
|
-
|
|
656
|
-
|
|
654
|
+
"Check startup state and return map of :bridge-mode, :docker, and
|
|
655
|
+
:podman. If bridge-mode is :auto then return :ovs if the
|
|
656
|
+
'openvswitch' kernel module is loaded otherwise fall back to :linux.
|
|
657
|
+
Exit with an error if bridge-mode is :ovs and the 'openvswitch'
|
|
658
|
+
kernel module is not loaded or if neither a docker or podman
|
|
659
|
+
connection could be established."
|
|
660
|
+
[{:keys [bridge-mode docker-socket podman-socket]}]
|
|
657
661
|
(P/let
|
|
658
|
-
[
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
662
|
+
[{:keys [info warn]} @ctx
|
|
663
|
+
ovs? (kmod-loaded? "openvswitch")
|
|
664
|
+
bridge-mode (condp = [bridge-mode ovs?]
|
|
665
|
+
[:auto true]
|
|
666
|
+
:ovs
|
|
667
|
+
|
|
668
|
+
[:auto false]
|
|
669
|
+
(do
|
|
670
|
+
(warn (str "bridge-mode is 'auto' but no 'openvswitch' "
|
|
671
|
+
"kernel module loaded, so using 'linux'"))
|
|
672
|
+
:linux)
|
|
673
|
+
|
|
674
|
+
[:ovs false]
|
|
675
|
+
(fatal 1 (str "bridge-mode is 'ovs', but no 'openvswitch' "
|
|
676
|
+
"kernel module loaded"))
|
|
677
|
+
|
|
678
|
+
bridge-mode)
|
|
679
|
+
docker (docker-client docker-socket)
|
|
680
|
+
podman (docker-client podman-socket)]
|
|
663
681
|
(when (and (not docker) (not podman))
|
|
664
|
-
(fatal 1 "Failed to start either docker or podman client/listener"))
|
|
682
|
+
(fatal 1 "Failed to start either docker or podman client/listener"))
|
|
683
|
+
{:bridge-mode bridge-mode
|
|
684
|
+
:docker docker
|
|
685
|
+
:podman podman}))
|
|
665
686
|
|
|
666
687
|
(defn server
|
|
667
688
|
"Process:
|
|
@@ -691,7 +712,7 @@ General Options:
|
|
|
691
712
|
_ (arg-checks opts)
|
|
692
713
|
_ (info (str "User options:\n" (indent-pprint-str opts " ")))
|
|
693
714
|
|
|
694
|
-
{:keys [network-file compose-file compose-project
|
|
715
|
+
{:keys [network-file compose-file compose-project]} opts
|
|
695
716
|
env (js->clj (js/Object.assign #js {} js/process.env))
|
|
696
717
|
self-pid js/process.pid
|
|
697
718
|
schema (load-config (:config-schema opts))
|
|
@@ -703,9 +724,7 @@ General Options:
|
|
|
703
724
|
(println (js/JSON.stringify (->js network-config)))
|
|
704
725
|
(js/process.exit 0))
|
|
705
726
|
|
|
706
|
-
|
|
707
|
-
podman (docker-client (:podman-socket opts))
|
|
708
|
-
_ (startup-checks bridge-mode docker podman)
|
|
727
|
+
{:keys [bridge-mode docker podman]} (startup-checks opts)
|
|
709
728
|
self-cid (get-container-id)
|
|
710
729
|
self-container-obj (when self-cid
|
|
711
730
|
(get-container (or docker podman) self-cid))
|
package/.env
DELETED
package/TODO
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
- MVP for ViaBox:
|
|
2
|
-
- [x] compose/x-network file loading
|
|
3
|
-
- [x] multiple config sources and merging
|
|
4
|
-
- [x] link route config
|
|
5
|
-
- [x] filtering on project and workdir
|
|
6
|
-
- [x] interface and MAC iteration
|
|
7
|
-
- [x] variable templating
|
|
8
|
-
- [x] *vlan type interfaces
|
|
9
|
-
|
|
10
|
-
- Near term:
|
|
11
|
-
- [x] dummy interfaces
|
|
12
|
-
- [x] arbitrary container commands
|
|
13
|
-
- [x] schema validation
|
|
14
|
-
- [x] code comments/documentation
|
|
15
|
-
- [x] tunnel interfaces
|
|
16
|
-
- [x] tc/qdisc settings
|
|
17
|
-
- [x] fix/test all examples (6 and 9 remaining)
|
|
18
|
-
- [x] add net2dot
|
|
19
|
-
- [ ] add outer-netem (and match all link-add params to link keys)
|
|
20
|
-
|
|
21
|
-
- Further term:
|
|
22
|
-
- [ ] CNI networking support
|
|
23
|
-
- conlink runs in container listening for events on a UDS
|
|
24
|
-
(intead of docker events)
|
|
25
|
-
- an outer conlink command is the CNI client that formats
|
|
26
|
-
events to send over the UDS to the inner conlink
|
|
27
|
-
- [ ] multiple routes
|
|
28
|
-
- [ ] ovs flow config
|
|
29
|
-
- [ ] Multiple bridge-modes
|
|
30
|
-
- bridge-mode as part of the domain definition so that the
|
|
31
|
-
same conlink instances can support multiple bridge modes
|
|
32
|
-
simultaneously (with a default for links that don't
|
|
33
|
-
specify).
|
|
34
|
-
|