conlink 2.2.0 → 2.4.0
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 +3 -3
- package/Dockerfile +1 -1
- package/README.md +200 -12
- package/examples/test10-compose.yaml +14 -3
- package/examples/test7-compose.yaml +6 -1
- package/examples/test9-compose.yaml +8 -3
- package/link-add.sh +19 -14
- package/link-forward.sh +2 -1
- package/link-mirred.sh +8 -29
- package/mdc +38 -25
- package/net2dot.cljs +3 -3
- package/package.json +3 -2
- package/schema.yaml +12 -5
- package/scripts/copy.sh +3 -2
- package/scripts/wait.sh +1 -1
- package/src/conlink/core.cljs +107 -53
- package/src/conlink/util.cljs +1 -1
- package/test/test1.yaml +26 -0
- package/test/test10.yaml +46 -0
- package/test/test2.yaml +37 -0
- package/test/test4.yaml +80 -0
- package/test/test7.yaml +34 -0
- package/test/test9.yaml +110 -0
- package/run-tests.sh +0 -219
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conlink",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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
|
|
8
|
+
"@lonocloud/resolve-deps": "^0.1.0",
|
|
9
9
|
"ajv": "^8.12.0",
|
|
10
10
|
"dockerode": "^3.3.4",
|
|
11
11
|
"nbb": "^1.2.179",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"yaml": "^2.2.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
+
"@lonocloud/dctest": "0.1.1",
|
|
17
18
|
"shadow-cljs": "^2.25.7",
|
|
18
19
|
"source-map-support": "^0.5.21"
|
|
19
20
|
}
|
package/schema.yaml
CHANGED
|
@@ -3,6 +3,7 @@ $defs:
|
|
|
3
3
|
ip: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+$"}
|
|
4
4
|
mac: {type: string, pattern: "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$"}
|
|
5
5
|
intf: {type: string, pattern: "^.{1,15}$"}
|
|
6
|
+
fwd: {type: string, pattern: "^[0-9]{1,5}:[0-9]{1,5}/(tcp|udp)$"}
|
|
6
7
|
|
|
7
8
|
type: object
|
|
8
9
|
additionalProperties: false
|
|
@@ -40,14 +41,18 @@ properties:
|
|
|
40
41
|
ip: { "$ref": "#/$defs/cidr" }
|
|
41
42
|
mac: { "$ref": "#/$defs/mac" }
|
|
42
43
|
mtu: {type: number}
|
|
43
|
-
route: {type: string}
|
|
44
44
|
nat: { "$ref": "#/$defs/ip" }
|
|
45
|
-
netem: {type: string}
|
|
46
45
|
mode: {type: string}
|
|
47
46
|
vlanid: {type: number}
|
|
47
|
+
route:
|
|
48
|
+
oneOf: [{type: string},
|
|
49
|
+
{type: array, items: {type: string}}]
|
|
48
50
|
forward:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
oneOf: [{ "$ref": "#/$defs/fwd" },
|
|
52
|
+
{type: array, items: { "$ref": "#/$defs/fwd" }}]
|
|
53
|
+
netem:
|
|
54
|
+
oneOf: [{type: string},
|
|
55
|
+
{type: array, items: {type: string}}]
|
|
51
56
|
|
|
52
57
|
bridges:
|
|
53
58
|
type: array
|
|
@@ -66,7 +71,9 @@ properties:
|
|
|
66
71
|
bridge: {type: string}
|
|
67
72
|
remote: { "$ref": "#/$defs/ip" }
|
|
68
73
|
vni: {type: number}
|
|
69
|
-
netem:
|
|
74
|
+
netem:
|
|
75
|
+
oneOf: [{type: string},
|
|
76
|
+
{type: array, items: {type: string}}]
|
|
70
77
|
|
|
71
78
|
commands:
|
|
72
79
|
type: array
|
package/scripts/copy.sh
CHANGED
package/scripts/wait.sh
CHANGED
package/src/conlink/core.cljs
CHANGED
|
@@ -77,6 +77,11 @@ General Options:
|
|
|
77
77
|
(defn indent-pprint-str [o pre]
|
|
78
78
|
(indent (trim (with-out-str (pprint o))) pre))
|
|
79
79
|
|
|
80
|
+
(defn random-mac
|
|
81
|
+
"Return a random MAC address starting with '0xc2'"
|
|
82
|
+
[]
|
|
83
|
+
(addrs/int->mac (reduce #(+ (rand-int 256) (* %1 256))
|
|
84
|
+
0xc2 [1 2 3 4 5])))
|
|
80
85
|
|
|
81
86
|
(defn load-configs
|
|
82
87
|
"Load network configs from a list of compose file paths and a list
|
|
@@ -104,31 +109,44 @@ General Options:
|
|
|
104
109
|
- Add default values to a link:
|
|
105
110
|
- type: veth
|
|
106
111
|
- dev: eth0
|
|
112
|
+
- mac: random MAC starting with first octet of 'c2'
|
|
107
113
|
- mtu: --default-mtu (for non *vlan type)
|
|
108
114
|
- base: :conlink for veth type, :host for *vlan types, :local otherwise"
|
|
109
|
-
[{:as link :keys [type base bridge ip forward]} bridges]
|
|
110
|
-
(let [{:keys [
|
|
115
|
+
[{:as link :keys [type base bridge ip route forward netem]} bridges opts]
|
|
116
|
+
(let [{:keys [docker-eth0? docker-eth0-address]} @ctx
|
|
117
|
+
{:keys [default-mtu]} opts
|
|
111
118
|
type (keyword (or type "veth"))
|
|
112
119
|
dev (get link :dev "eth0")
|
|
120
|
+
mac (get link :mac (random-mac))
|
|
113
121
|
base-default (cond (= :veth type) :conlink
|
|
114
122
|
(VLAN-TYPES type) :host
|
|
115
123
|
:else :local)
|
|
116
124
|
base (get link :base base-default)
|
|
117
125
|
bridge (get bridges bridge)
|
|
126
|
+
route (if (string? route) [route] route)
|
|
127
|
+
forward (if (string? forward) [forward] forward)
|
|
128
|
+
netem (if (string? netem) [netem] netem)
|
|
118
129
|
link (merge
|
|
119
130
|
link
|
|
120
131
|
{:type type
|
|
121
132
|
:dev dev
|
|
122
|
-
:base base
|
|
133
|
+
:base base
|
|
134
|
+
:mac mac}
|
|
123
135
|
(when bridge
|
|
124
136
|
{:bridge bridge})
|
|
125
137
|
(when (not (VLAN-TYPES type))
|
|
126
138
|
{:mtu (get link :mtu default-mtu)})
|
|
139
|
+
(when route
|
|
140
|
+
{:route route})
|
|
127
141
|
(when forward
|
|
128
142
|
{:forward
|
|
129
143
|
(map #(let [[port_a port_b proto] (S/split % #"[:/]")]
|
|
130
144
|
[(js/parseInt port_a) (js/parseInt port_b) proto])
|
|
131
|
-
forward)})
|
|
145
|
+
forward)})
|
|
146
|
+
(when (and forward docker-eth0-address)
|
|
147
|
+
{:route (conj route (str docker-eth0-address "/32"))})
|
|
148
|
+
(when netem
|
|
149
|
+
{:netem netem}))]
|
|
132
150
|
(when forward
|
|
133
151
|
(let [link-id (str (or (:service link) (:container link)) ":" dev)
|
|
134
152
|
pre (str "link '" link-id "' has forward setting")]
|
|
@@ -148,8 +166,9 @@ General Options:
|
|
|
148
166
|
is loaded otherwise fall back to :linux. Exit with an error if mode is :ovs
|
|
149
167
|
or :patch and the 'openvswitch' or 'act_mirred' kernel modules are not
|
|
150
168
|
loaded respectively."
|
|
151
|
-
[{:as bridge-opts :keys [bridge mode]}]
|
|
152
|
-
(let [{:keys [warn
|
|
169
|
+
[{:as bridge-opts :keys [bridge mode]} opts]
|
|
170
|
+
(let [{:keys [warn kmod-ovs? kmod-mirred?]} @ctx
|
|
171
|
+
{:keys [default-bridge-mode]} opts
|
|
153
172
|
mode (keyword (or mode default-bridge-mode))
|
|
154
173
|
_ (when (and (= :ovs mode) (not kmod-ovs?))
|
|
155
174
|
(fatal 1 (str "bridge " bridge " mode is 'ovs', "
|
|
@@ -157,11 +176,11 @@ General Options:
|
|
|
157
176
|
_ (when (and (= :patch mode) (not kmod-mirred?))
|
|
158
177
|
(warn (str "bridge " bridge " mode is 'patch', "
|
|
159
178
|
"but no 'act_mirred' kernel module loaded, "
|
|
160
|
-
"
|
|
179
|
+
"assuming it will load when needed.")))
|
|
161
180
|
_ (when (and (= :auto mode) (not kmod-ovs?))
|
|
162
181
|
(warn (str "bridge " bridge " mode is 'auto', "
|
|
163
|
-
"
|
|
164
|
-
"
|
|
182
|
+
"but no 'openvswitch' kernel module loaded, "
|
|
183
|
+
"so falling back to 'linux'")))
|
|
165
184
|
mode (if (= :auto mode)
|
|
166
185
|
(if kmod-ovs? :ovs :linux)
|
|
167
186
|
mode)]
|
|
@@ -172,8 +191,9 @@ General Options:
|
|
|
172
191
|
add :bridges, :containers, and :services maps with restructured bridge, link,
|
|
173
192
|
and command configuration to provide a more efficient structure for looking
|
|
174
193
|
up configuration later."
|
|
175
|
-
[{:as cfg :keys [links commands
|
|
176
|
-
(let [bridge-map (reduce (fn [
|
|
194
|
+
[{:as cfg :keys [links bridges tunnels commands]} opts]
|
|
195
|
+
(let [bridge-map (reduce (fn [bs b]
|
|
196
|
+
(assoc bs (:bridge b) b))
|
|
177
197
|
{} bridges)
|
|
178
198
|
;; Add bridges specified in links only
|
|
179
199
|
all-bridges (reduce (fn [bs b]
|
|
@@ -181,21 +201,33 @@ General Options:
|
|
|
181
201
|
bridge-map
|
|
182
202
|
(keep :bridge links))
|
|
183
203
|
;; Enrich each bridge
|
|
184
|
-
bridges (reduce (fn [bs [k v]]
|
|
204
|
+
bridges (reduce (fn [bs [k v]]
|
|
205
|
+
(assoc bs k (enrich-bridge v opts)))
|
|
185
206
|
{} all-bridges)
|
|
186
|
-
links
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
207
|
+
;; Restructure links into map to merge and enrich.
|
|
208
|
+
;; Merge key is server/container + dev
|
|
209
|
+
link-map (reduce (fn [ls link]
|
|
210
|
+
(let [elink (enrich-link link bridges opts)
|
|
211
|
+
lid (str (or (:service link)
|
|
212
|
+
(:container link))
|
|
213
|
+
":" (:dev elink))
|
|
214
|
+
mlink (deep-merge (get ls lid) elink)]
|
|
215
|
+
(assoc ls lid mlink)))
|
|
216
|
+
{} links)
|
|
217
|
+
|
|
218
|
+
cfg {:bridges bridges
|
|
219
|
+
:tunnels tunnels
|
|
220
|
+
:containers {}
|
|
221
|
+
:services {}}
|
|
191
222
|
rfn (fn [kind cfg {:as x :keys [container service]}]
|
|
192
223
|
(cond-> cfg
|
|
193
224
|
container (update-in [:containers container kind] conjv x)
|
|
194
225
|
service (update-in [:services service kind] conjv x)))
|
|
195
|
-
cfg (reduce (partial rfn :links) cfg
|
|
226
|
+
cfg (reduce (partial rfn :links) cfg (vals link-map))
|
|
196
227
|
cfg (reduce (partial rfn :commands) cfg commands)]
|
|
197
228
|
cfg))
|
|
198
229
|
|
|
230
|
+
|
|
199
231
|
(defn ajv-error-to-str [error]
|
|
200
232
|
(let [path (:instancePath error)
|
|
201
233
|
params (dissoc (:params error) :type :pattern :missingProperty)]
|
|
@@ -204,8 +236,7 @@ General Options:
|
|
|
204
236
|
(if (not (empty? params)) (str " " params) ""))))
|
|
205
237
|
|
|
206
238
|
(defn check-schema [data schema verbose]
|
|
207
|
-
(let [{:
|
|
208
|
-
ajv (Ajv. #js {:allErrors true})
|
|
239
|
+
(let [ajv (Ajv. #js {:allErrors true})
|
|
209
240
|
validator (.compile ajv (->js schema))
|
|
210
241
|
valid (validator (->js data))]
|
|
211
242
|
(if valid
|
|
@@ -272,7 +303,6 @@ General Options:
|
|
|
272
303
|
container properties from an event and the current pid of the
|
|
273
304
|
network container. Updates iterable properties of the link
|
|
274
305
|
(via link-add-offset) and adds the following keys:
|
|
275
|
-
- :container - the container properties (passed in)
|
|
276
306
|
- :outer-pid - PID of the network namespace (passed in)
|
|
277
307
|
- :pid - PID of this container
|
|
278
308
|
- :dev-id - container name + container interface name
|
|
@@ -288,8 +318,7 @@ General Options:
|
|
|
288
318
|
link (if (and outer-pid (not (:outer-dev link)))
|
|
289
319
|
(assoc link :outer-dev (link-outer-dev link id index))
|
|
290
320
|
link)
|
|
291
|
-
link (merge link {:
|
|
292
|
-
:dev-id dev-id
|
|
321
|
+
link (merge link {:dev-id dev-id
|
|
293
322
|
:pid pid
|
|
294
323
|
:outer-pid outer-pid})]
|
|
295
324
|
link))
|
|
@@ -350,6 +379,19 @@ General Options:
|
|
|
350
379
|
res (run cmd {:quiet true})]
|
|
351
380
|
(= 0 (:code res))))
|
|
352
381
|
|
|
382
|
+
(defn intf-ipv4-addresses
|
|
383
|
+
"Return a sequence of IPv4 addresses for the interface."
|
|
384
|
+
[intf]
|
|
385
|
+
(P/let [cmd (str "ip -json addr show dev " intf)
|
|
386
|
+
res (run cmd {:quiet true})
|
|
387
|
+
addrs (when (= 0 (:code res))
|
|
388
|
+
(js->clj (js/JSON.parse (:stdout res))
|
|
389
|
+
:keywordize-keys true))]
|
|
390
|
+
(->> addrs
|
|
391
|
+
(mapcat :addr_info)
|
|
392
|
+
(filter #(= "inet" (:family %)))
|
|
393
|
+
(map :local))))
|
|
394
|
+
|
|
353
395
|
(defn rename-docker-eth0
|
|
354
396
|
"Rename docker's provided eth0 to DOCKER-INTF to prevent 'RTNETLINK
|
|
355
397
|
answers: File exists' errors during creation of links that use
|
|
@@ -411,7 +453,8 @@ General Options:
|
|
|
411
453
|
(if (not cmd)
|
|
412
454
|
(info (str "Ignoring bridge/switch " bridge " for mode " mode))
|
|
413
455
|
(P/let [_ (info "Creating bridge/switch" bridge)
|
|
414
|
-
res (run* [cmd (str "ip link set " bridge " up")]
|
|
456
|
+
res (run* [cmd (str "ip link set " bridge " up")]
|
|
457
|
+
{:id "bridge-create"})]
|
|
415
458
|
(if (not= 0 (:code res))
|
|
416
459
|
(error (str "Unable to create bridge/switch " bridge))
|
|
417
460
|
(swap! ctx assoc-in [:network-state :bridges bridge :status] :created))
|
|
@@ -510,9 +553,10 @@ General Options:
|
|
|
510
553
|
(when outer-pid (str " --pid1 " outer-pid))
|
|
511
554
|
(when outer-dev (str " --intf1 " outer-dev))
|
|
512
555
|
(S/join ""
|
|
513
|
-
(for [o LINK-ADD-OPTS
|
|
514
|
-
|
|
515
|
-
|
|
556
|
+
(for [o LINK-ADD-OPTS
|
|
557
|
+
:let [v (get link o [])]
|
|
558
|
+
vo (if (sequential? v) v [v])]
|
|
559
|
+
(str " --" (name o) " '" vo "'"))))
|
|
516
560
|
res (run cmd {:id dev-id})]
|
|
517
561
|
(when (not= 0 (:code res))
|
|
518
562
|
(error (str "Unable to add " (name type) " " dev-id)))
|
|
@@ -540,7 +584,7 @@ General Options:
|
|
|
540
584
|
forwards defined by :forward property of 'link'."
|
|
541
585
|
[link action]
|
|
542
586
|
(P/let [{:keys [error]} @ctx
|
|
543
|
-
{:keys [
|
|
587
|
+
{:keys [dev-id bridge ip forward]} link]
|
|
544
588
|
(P/all (for [fwd forward]
|
|
545
589
|
(P/let [[port_a port_b proto] fwd
|
|
546
590
|
ip (S/replace ip #"/.*" "")
|
|
@@ -562,8 +606,9 @@ General Options:
|
|
|
562
606
|
running in a container)"
|
|
563
607
|
[]
|
|
564
608
|
(P/let [[cgroup mountinfo]
|
|
565
|
-
, (P/all [(read-file "/proc/self/cgroup" "utf8")
|
|
566
|
-
|
|
609
|
+
, (P/catch (P/all [(read-file "/proc/self/cgroup" "utf8")
|
|
610
|
+
(read-file "/proc/self/mountinfo" "utf8")])
|
|
611
|
+
#(vector "" ""))
|
|
567
612
|
;; docker
|
|
568
613
|
d-cgroups (map second (re-seq #"/docker/([^/\n]*)" cgroup))
|
|
569
614
|
;; podman (root)
|
|
@@ -604,6 +649,18 @@ General Options:
|
|
|
604
649
|
(S/replace #"\." "-")))
|
|
605
650
|
v])))
|
|
606
651
|
|
|
652
|
+
(defn query-container-data
|
|
653
|
+
[container-obj]
|
|
654
|
+
(P/let
|
|
655
|
+
[container (inspect-container container-obj)
|
|
656
|
+
clabels (get-compose-labels container)
|
|
657
|
+
svc-num (:container-number clabels)]
|
|
658
|
+
{:name (->> container :Name (re-seq #"(.*/)?(.*)") first last)
|
|
659
|
+
:index (if svc-num (js/parseInt svc-num) 1)
|
|
660
|
+
:service (:service clabels)
|
|
661
|
+
:pid (-> container :State :Pid)
|
|
662
|
+
:labels clabels}))
|
|
663
|
+
|
|
607
664
|
;;;
|
|
608
665
|
|
|
609
666
|
(defn docker-client
|
|
@@ -659,7 +716,7 @@ General Options:
|
|
|
659
716
|
(condp = action
|
|
660
717
|
"start"
|
|
661
718
|
(if link-status
|
|
662
|
-
(error (str "Link " dev-id " already
|
|
719
|
+
(error (str "Link " dev-id " already in state: " link-status))
|
|
663
720
|
(P/do
|
|
664
721
|
(swap! ctx assoc-in status-path :creating)
|
|
665
722
|
(link-add link)
|
|
@@ -730,29 +787,26 @@ General Options:
|
|
|
730
787
|
if all containers/services are connected."
|
|
731
788
|
[client {:keys [status id]}]
|
|
732
789
|
(P/let
|
|
733
|
-
[{:keys [log info network-config compose-opts self-pid]} @ctx
|
|
790
|
+
[{:keys [log info network-config network-state compose-opts self-pid]} @ctx
|
|
734
791
|
container-obj (get-container client id)
|
|
735
|
-
container (
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
:index cindex
|
|
746
|
-
:service svc-name
|
|
747
|
-
:pid pid
|
|
748
|
-
:labels clabels}
|
|
792
|
+
container-data (if (= "die" status)
|
|
793
|
+
(P/let [ci (get-in network-state [:containers id])]
|
|
794
|
+
(swap! ctx update-in [:network-state :containers]
|
|
795
|
+
dissoc id)
|
|
796
|
+
ci)
|
|
797
|
+
(P/let [ci (query-container-data container-obj)]
|
|
798
|
+
(swap! ctx update-in [:network-state :containers]
|
|
799
|
+
assoc id ci)
|
|
800
|
+
ci))
|
|
801
|
+
{cname :name clabels :labels} container-data
|
|
749
802
|
|
|
750
803
|
svc-match? (and (let [p (:project compose-opts)]
|
|
751
804
|
(or (not p) (= p (:project clabels))))
|
|
752
805
|
(let [d (:project-working_dir compose-opts)]
|
|
753
806
|
(or (not d) (= d (:project-working_dir clabels)))))
|
|
754
807
|
containers (get-in network-config [:containers cname])
|
|
755
|
-
services (when svc-match?
|
|
808
|
+
services (when svc-match?
|
|
809
|
+
(get-in network-config [:services (:service clabels)]))
|
|
756
810
|
links (concat (:links containers) (:links services))
|
|
757
811
|
commands (concat (:commands containers) (:commands services))]
|
|
758
812
|
(if (and (not (seq links)) (not (seq commands)))
|
|
@@ -761,7 +815,7 @@ General Options:
|
|
|
761
815
|
(info "Event:" status cname id)
|
|
762
816
|
(P/all (for [link links
|
|
763
817
|
:let [link (link-instance-enrich
|
|
764
|
-
link container-
|
|
818
|
+
link container-data self-pid)]]
|
|
765
819
|
(modify-link link status)))
|
|
766
820
|
(when (= "start" status)
|
|
767
821
|
(P/all (for [{:keys [command]} commands]
|
|
@@ -838,15 +892,15 @@ General Options:
|
|
|
838
892
|
kmod-ovs? (kmod-loaded? "openvswitch")
|
|
839
893
|
kmod-mirred? (kmod-loaded? "act_mirred")
|
|
840
894
|
docker-eth0? (and self-cid (intf-exists? "eth0"))
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
:kmod-ovs? kmod-ovs?
|
|
895
|
+
docker-eth0-addresses (when docker-eth0? (intf-ipv4-addresses "eth0"))
|
|
896
|
+
_ (swap! ctx merge {:kmod-ovs? kmod-ovs?
|
|
844
897
|
:kmod-mirred? kmod-mirred?
|
|
845
|
-
:docker-eth0? docker-eth0?
|
|
898
|
+
:docker-eth0? docker-eth0?
|
|
899
|
+
:docker-eth0-address (first docker-eth0-addresses)})
|
|
846
900
|
network-config (P/-> (load-configs compose-file network-file)
|
|
847
901
|
(interpolate-walk env)
|
|
848
902
|
(check-schema schema verbose)
|
|
849
|
-
(enrich-network-config))
|
|
903
|
+
(enrich-network-config opts))
|
|
850
904
|
_ (when show-config
|
|
851
905
|
(println (js/JSON.stringify (->js network-config)))
|
|
852
906
|
(js/process.exit 0))
|
package/src/conlink/util.cljs
CHANGED
package/test/test1.yaml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: "test1: compose file with embedded network config"
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
DC: "${{ process.env.DOCKER_COMPOSE || 'docker compose' }}"
|
|
5
|
+
COMPOSE_FILE: examples/test1-compose.yaml
|
|
6
|
+
|
|
7
|
+
tests:
|
|
8
|
+
test1:
|
|
9
|
+
name: "compose file with embedded network config"
|
|
10
|
+
steps:
|
|
11
|
+
- exec: :host
|
|
12
|
+
run: |
|
|
13
|
+
${DC} down --remove-orphans --volumes -t1
|
|
14
|
+
${DC} up -d --force-recreate
|
|
15
|
+
- exec: :host
|
|
16
|
+
run: |
|
|
17
|
+
echo "waiting for conlink startup"
|
|
18
|
+
${DC} logs network | grep "All links connected"
|
|
19
|
+
repeat: { retries: 30, interval: '1s' }
|
|
20
|
+
|
|
21
|
+
- {exec: h1, run: ping -c1 -w2 10.0.0.100}
|
|
22
|
+
- {exec: h2, run: ping -c1 -w2 192.168.1.100}
|
|
23
|
+
- {exec: h3, run: ping -c1 -w2 172.16.0.100}
|
|
24
|
+
|
|
25
|
+
- exec: :host
|
|
26
|
+
run: ${DC} down --remove-orphans --volumes -t1
|
package/test/test10.yaml
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: "test10: port forwarding"
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
DC: "${{ process.env.DOCKER_COMPOSE || 'docker compose' }}"
|
|
5
|
+
COMPOSE_FILE: examples/test10-compose.yaml
|
|
6
|
+
|
|
7
|
+
tests:
|
|
8
|
+
test10:
|
|
9
|
+
name: "port forwarding"
|
|
10
|
+
steps:
|
|
11
|
+
- exec: :host
|
|
12
|
+
run: |
|
|
13
|
+
${DC} down --remove-orphans --volumes -t1
|
|
14
|
+
${DC} up -d --force-recreate
|
|
15
|
+
- exec: :host
|
|
16
|
+
run: |
|
|
17
|
+
echo "waiting for conlink startup"
|
|
18
|
+
${DC} logs network | grep "All links connected"
|
|
19
|
+
repeat: { retries: 30, interval: '1s' }
|
|
20
|
+
- exec: node1
|
|
21
|
+
run: ip addr | grep "10\.1\.0\.1"
|
|
22
|
+
repeat: { retries: 10, interval: '2s' }
|
|
23
|
+
|
|
24
|
+
# Check ping between replicas
|
|
25
|
+
- {exec: node2, run: ping -c1 -w2 10.2.0.2}
|
|
26
|
+
# Check ping across router
|
|
27
|
+
- {exec: node1, run: ping -c1 -w2 10.2.0.1}
|
|
28
|
+
- {exec: node1, run: ping -c1 -w2 10.2.0.2}
|
|
29
|
+
- {exec: node2, run: ping -c1 -w2 10.1.0.1}
|
|
30
|
+
# Check ping across router
|
|
31
|
+
- exec: :host
|
|
32
|
+
run: 'curl -sS "http://0.0.0.0:3080" | grep "log"'
|
|
33
|
+
repeat: { retries: 10, interval: '2s' }
|
|
34
|
+
- exec: :host
|
|
35
|
+
run: 'curl -sS "http://0.0.0.0:8080" | grep "log"'
|
|
36
|
+
repeat: { retries: 10, interval: '2s' }
|
|
37
|
+
- exec: :host
|
|
38
|
+
run: 'curl -sS "http://0.0.0.0:80" | grep "share"'
|
|
39
|
+
repeat: { retries: 10, interval: '2s' }
|
|
40
|
+
- exec: :host
|
|
41
|
+
run: 'curl -sS "http://0.0.0.0:81" | grep "share"'
|
|
42
|
+
repeat: { retries: 10, interval: '2s' }
|
|
43
|
+
|
|
44
|
+
- exec: :host
|
|
45
|
+
run: ${DC} down --remove-orphans --volumes -t1
|
|
46
|
+
|
package/test/test2.yaml
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: "test2: separate config and scaling"
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
DC: "${{ process.env.DOCKER_COMPOSE || 'docker compose' }}"
|
|
5
|
+
COMPOSE_FILE: examples/test2-compose.yaml
|
|
6
|
+
|
|
7
|
+
tests:
|
|
8
|
+
test2:
|
|
9
|
+
name: "separate config and scaling"
|
|
10
|
+
steps:
|
|
11
|
+
- exec: :host
|
|
12
|
+
run: |
|
|
13
|
+
${DC} down --remove-orphans --volumes -t1
|
|
14
|
+
${DC} up -d --force-recreate
|
|
15
|
+
- exec: :host
|
|
16
|
+
run: |
|
|
17
|
+
echo "waiting for conlink startup"
|
|
18
|
+
${DC} logs network | grep "All links connected"
|
|
19
|
+
repeat: { retries: 30, interval: '1s' }
|
|
20
|
+
- {exec: node, index: 1, run: ping -c1 -w2 10.0.1.2}
|
|
21
|
+
- {exec: node, index: 2, run: ping -c1 -w2 10.0.1.1}
|
|
22
|
+
- {exec: node, index: 1, run: ping -c1 -w2 8.8.8.8}
|
|
23
|
+
- {exec: node, index: 2, run: ping -c1 -w2 8.8.8.8}
|
|
24
|
+
|
|
25
|
+
- exec: :host
|
|
26
|
+
run: |
|
|
27
|
+
echo "Scale the nodes from 2 to 5"
|
|
28
|
+
${DC} up -d --scale node=5
|
|
29
|
+
- exec: node
|
|
30
|
+
index: 5
|
|
31
|
+
run: ip addr | grep "10\.0\.1\.5"
|
|
32
|
+
repeat: { retries: 10, interval: '2s' }
|
|
33
|
+
- {exec: node, index: 2, run: ping -c1 -w2 10.0.1.5}
|
|
34
|
+
- {exec: node, index: 5, run: ping -c1 -w2 8.8.8.8}
|
|
35
|
+
|
|
36
|
+
- exec: :host
|
|
37
|
+
run: ${DC} down --remove-orphans --volumes -t1
|
package/test/test4.yaml
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: "test4: multiple compose and mdc"
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
DC: "${{ process.env.DOCKER_COMPOSE || 'docker compose' }}"
|
|
5
|
+
MODES_DIR: examples/test4-multiple/modes
|
|
6
|
+
|
|
7
|
+
tests:
|
|
8
|
+
node1:
|
|
9
|
+
name: "mdc node1"
|
|
10
|
+
steps:
|
|
11
|
+
- exec: :host
|
|
12
|
+
run: |
|
|
13
|
+
./mdc node1
|
|
14
|
+
${DC} down --remove-orphans --volumes -t1
|
|
15
|
+
${DC} up -d --force-recreate
|
|
16
|
+
- exec: :host
|
|
17
|
+
run: |
|
|
18
|
+
echo "waiting for conlink startup"
|
|
19
|
+
${DC} logs network | grep "All links connected"
|
|
20
|
+
repeat: { retries: 30, interval: '1s' }
|
|
21
|
+
- exec: r0
|
|
22
|
+
run: ip addr | grep "10\.1\.0\.100"
|
|
23
|
+
repeat: { retries: 10, interval: '2s' }
|
|
24
|
+
|
|
25
|
+
# Ping the r0 router host from node1
|
|
26
|
+
- {exec: node1, index: 1, run: ping -c1 -w2 10.0.0.100}
|
|
27
|
+
|
|
28
|
+
- exec: :host
|
|
29
|
+
run: ${DC} down --remove-orphans --volumes -t1
|
|
30
|
+
|
|
31
|
+
node1-nodes2:
|
|
32
|
+
name: "mdc node1,nodes2"
|
|
33
|
+
steps:
|
|
34
|
+
- exec: :host
|
|
35
|
+
run: |
|
|
36
|
+
./mdc node1,nodes2
|
|
37
|
+
${DC} down --remove-orphans --volumes -t1
|
|
38
|
+
${DC} up -d --force-recreate
|
|
39
|
+
- exec: :host
|
|
40
|
+
run: |
|
|
41
|
+
echo "waiting for conlink startup"
|
|
42
|
+
${DC} logs network | grep "All links connected"
|
|
43
|
+
repeat: { retries: 30, interval: '1s' }
|
|
44
|
+
- exec: node2
|
|
45
|
+
index: 2
|
|
46
|
+
run: ip addr | grep "10\.2\.0\.2"
|
|
47
|
+
repeat: { retries: 10, interval: '2s' }
|
|
48
|
+
|
|
49
|
+
# From both node2 replicas, ping node1 across the r0 router
|
|
50
|
+
- {exec: node2, index: 1, run: ping -c1 -w2 10.1.0.1}
|
|
51
|
+
- {exec: node2, index: 2, run: ping -c1 -w2 10.1.0.1}
|
|
52
|
+
# From node1, ping both node2 replicas across the r0 router
|
|
53
|
+
- {exec: node1, index: 1, run: ping -c1 -w2 10.2.0.1}
|
|
54
|
+
- {exec: node1, index: 1, run: ping -c1 -w2 10.2.0.2}
|
|
55
|
+
|
|
56
|
+
- exec: :host
|
|
57
|
+
run: ${DC} down --remove-orphans --volumes -t1
|
|
58
|
+
|
|
59
|
+
all:
|
|
60
|
+
name: "mdc all"
|
|
61
|
+
steps:
|
|
62
|
+
- exec: :host
|
|
63
|
+
run: |
|
|
64
|
+
./mdc all
|
|
65
|
+
${DC} down --remove-orphans --volumes -t1
|
|
66
|
+
${DC} up -d --force-recreate
|
|
67
|
+
- exec: :host
|
|
68
|
+
run: |
|
|
69
|
+
echo "waiting for conlink startup"
|
|
70
|
+
${DC} logs network | grep "All links connected"
|
|
71
|
+
repeat: { retries: 30, interval: '1s' }
|
|
72
|
+
- exec: r0
|
|
73
|
+
run: /scripts/wait.sh -t 10.0.0.100:80
|
|
74
|
+
|
|
75
|
+
# From node2, download from the web server in r0
|
|
76
|
+
- {exec: node2, index: 1, run: wget -O- 10.0.0.100}
|
|
77
|
+
- {exec: node2, index: 2, run: wget -O- 10.0.0.100}
|
|
78
|
+
|
|
79
|
+
- exec: :host
|
|
80
|
+
run: ${DC} down --remove-orphans --volumes -t1
|
package/test/test7.yaml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: "test7: MAC, MTU, and NetEm settings"
|
|
2
|
+
|
|
3
|
+
env:
|
|
4
|
+
DC: "${{ process.env.DOCKER_COMPOSE || 'docker compose' }}"
|
|
5
|
+
COMPOSE_FILE: examples/test7-compose.yaml
|
|
6
|
+
|
|
7
|
+
tests:
|
|
8
|
+
test7:
|
|
9
|
+
name: "MAC, MTU, and NetEm settings"
|
|
10
|
+
steps:
|
|
11
|
+
- exec: :host
|
|
12
|
+
run: |
|
|
13
|
+
${DC} down --remove-orphans --volumes -t1
|
|
14
|
+
${DC} up -d --force-recreate
|
|
15
|
+
- exec: :host
|
|
16
|
+
run: |
|
|
17
|
+
echo "waiting for conlink startup"
|
|
18
|
+
${DC} logs network | grep "All links connected"
|
|
19
|
+
repeat: { retries: 30, interval: '1s' }
|
|
20
|
+
- exec: node
|
|
21
|
+
run: ip addr | grep "10\.0\.1\.1"
|
|
22
|
+
repeat: { retries: 10, interval: '2s' }
|
|
23
|
+
|
|
24
|
+
# Ensure MAC and MTU are set correctly
|
|
25
|
+
- {exec: node, index: 1, run: ip link show eth0 | grep "ether 00:0a:0b:0c:0d:01"}
|
|
26
|
+
- {exec: node, index: 2, run: ip link show eth0 | grep "ether 00:0a:0b:0c:0d:02"}
|
|
27
|
+
- {exec: node, index: 1, run: ip link show eth0 | grep "mtu 4111"}
|
|
28
|
+
- {exec: node, index: 2, run: ip link show eth0 | grep "mtu 4111"}
|
|
29
|
+
# Check for round-trip ping delay of 80ms
|
|
30
|
+
- {exec: node, index: 1, run: 'ping -c5 10.0.1.2 | tail -n1 | grep "min/avg/max = 8[012345]\."'}
|
|
31
|
+
- {exec: node, index: 2, run: 'ping -c5 10.0.1.1 | tail -n1 | grep "min/avg/max = 8[012345]\."'}
|
|
32
|
+
|
|
33
|
+
- exec: :host
|
|
34
|
+
run: ${DC} down --remove-orphans --volumes -t1
|