conlink 2.2.0 → 2.5.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/net2dot.cljs CHANGED
@@ -29,7 +29,7 @@
29
29
  (S/replace #"[*]" "_STAR_")
30
30
  (S/replace #"[$]" "_DOLLAR_")
31
31
  (S/replace #"[{]" "_LCURLY_")
32
- (S/replace #"[}]" "_LCURLY_")
32
+ (S/replace #"[}]" "_RCURLY_")
33
33
  (S/replace #"[ ]" "_SPACE_")))
34
34
 
35
35
  (defn node-props [label props]
@@ -61,7 +61,7 @@
61
61
  #(->> (subgraph conlink (str "cluster_bridge_" %2)
62
62
  %2 BRIDGE-PROPS)
63
63
  (assoc %1 %2))
64
- {} (keep :bridge (:links network-config)))
64
+ {} (map :bridge (keep :bridge (:links network-config))))
65
65
  services (reduce
66
66
  #(->> (subgraph host (str "cluster_service_" (dot-id %2))
67
67
  (str "service '" (name %2) "'") SVC-PROPS)
@@ -85,7 +85,7 @@
85
85
  "-" (name dev)))
86
86
  out-id (str "out-" outer-dev)
87
87
  out-parent (condp = (keyword base)
88
- :conlink (get bridges bridge)
88
+ :conlink (get bridges (:bridge bridge))
89
89
  :host host)
90
90
  {:keys [type vlanid]} link
91
91
  [elabel iprops] (if (= "host" base)
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "conlink",
3
- "version": "2.2.0",
3
+ "version": "2.5.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.2",
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,21 @@ 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
- type: array
50
- items: {type: string, pattern: "^[0-9]{1,5}:[0-9]{1,5}/(tcp|udp)$"}
51
+ oneOf: [{ "$ref": "#/$defs/fwd" },
52
+ {type: array, items: { "$ref": "#/$defs/fwd" }}]
53
+ netem:
54
+ oneOf: [{type: string},
55
+ {type: array, items: {type: string}}]
56
+ ethtool:
57
+ oneOf: [{type: string},
58
+ {type: array, items: {type: string}}]
51
59
 
52
60
  bridges:
53
61
  type: array
@@ -66,7 +74,9 @@ properties:
66
74
  bridge: {type: string}
67
75
  remote: { "$ref": "#/$defs/ip" }
68
76
  vni: {type: number}
69
- netem: {type: string}
77
+ netem:
78
+ oneOf: [{type: string},
79
+ {type: array, items: {type: string}}]
70
80
 
71
81
  commands:
72
82
  type: array
package/scripts/copy.sh CHANGED
@@ -46,7 +46,8 @@ dst_dir="${1}"; shift || die 2 "Usage: ${0} [-T|--template] SRC_DIR DST_DIR"
46
46
  done
47
47
 
48
48
  if [ "${*}" ]; then
49
- exec "${@}"
49
+ echo "Running: ${*}"
50
+ exec "${@}"
50
51
  else
51
- true
52
+ true
52
53
  fi
package/scripts/wait.sh CHANGED
@@ -69,5 +69,5 @@ done
69
69
 
70
70
  if [ "${*}" ]; then
71
71
  echo "Running: ${*}"
72
- exec ${*}
72
+ exec "${@}"
73
73
  fi
@@ -32,6 +32,8 @@ General Options:
32
32
  [default: auto] [env: CONLINK_BRIDGE_MODE]
33
33
  --default-mtu MTU Default link MTU (for non *vlan types)
34
34
  [default: 65535]
35
+ --keep-veth-offload Do not add '--offload tx off' as the first
36
+ ethtool setting for container veth interfaces
35
37
  --network-file NETWORK-FILE... Network config file
36
38
  --compose-file COMPOSE-FILE... Docker compose file with network config
37
39
  --compose-project NAME Docker compose project name for resolving
@@ -57,7 +59,8 @@ General Options:
57
59
  " --system-id=random --no-mlockall --delete-bridges"))
58
60
 
59
61
  (def VLAN-TYPES #{:vlan :macvlan :macvtap :ipvlan :ipvtap})
60
- (def LINK-ADD-OPTS [:ip :mac :route :mtu :nat :netem :mode :vlanid :remote :vni])
62
+ (def LINK-ADD-OPTS [:ip :mac :route :mtu :nat :netem :ethtool
63
+ :mode :vlanid :remote :vni])
61
64
  (def INTF-MAX-LEN 15)
62
65
  (def DOCKER-INTF "DOCKER-ETH0")
63
66
 
@@ -77,6 +80,11 @@ General Options:
77
80
  (defn indent-pprint-str [o pre]
78
81
  (indent (trim (with-out-str (pprint o))) pre))
79
82
 
83
+ (defn random-mac
84
+ "Return a random MAC address starting with '0xc2'"
85
+ []
86
+ (addrs/int->mac (reduce #(+ (rand-int 256) (* %1 256))
87
+ 0xc2 [1 2 3 4 5])))
80
88
 
81
89
  (defn load-configs
82
90
  "Load network configs from a list of compose file paths and a list
@@ -104,31 +112,49 @@ General Options:
104
112
  - Add default values to a link:
105
113
  - type: veth
106
114
  - dev: eth0
115
+ - mac: random MAC starting with first octet of 'c2'
107
116
  - mtu: --default-mtu (for non *vlan type)
108
117
  - base: :conlink for veth type, :host for *vlan types, :local otherwise"
109
- [{:as link :keys [type base bridge ip forward]} bridges]
110
- (let [{:keys [default-mtu docker-eth0?]} @ctx
118
+ [{:as link :keys [type bridge ip route forward netem ethtool]} bridges opts]
119
+ (let [{:keys [docker-eth0? docker-eth0-address]} @ctx
120
+ {:keys [default-mtu keep-veth-offload]} opts
111
121
  type (keyword (or type "veth"))
112
122
  dev (get link :dev "eth0")
123
+ mac (get link :mac (random-mac))
113
124
  base-default (cond (= :veth type) :conlink
114
125
  (VLAN-TYPES type) :host
115
126
  :else :local)
116
127
  base (get link :base base-default)
117
128
  bridge (get bridges bridge)
129
+ route (if (string? route) [route] route)
130
+ forward (if (string? forward) [forward] forward)
131
+ netem (if (string? netem) [netem] netem)
132
+ ethtool-pre (if (and (= :veth type) (not keep-veth-offload))
133
+ ["--offload tx off"]
134
+ [])
135
+ ethtool (into ethtool-pre (if (string? ethtool) [ethtool] ethtool))
118
136
  link (merge
119
137
  link
120
138
  {:type type
121
139
  :dev dev
122
- :base base}
140
+ :base base
141
+ :mac mac
142
+ :ethtool ethtool}
123
143
  (when bridge
124
144
  {:bridge bridge})
125
145
  (when (not (VLAN-TYPES type))
126
146
  {:mtu (get link :mtu default-mtu)})
147
+ (when route
148
+ {:route route})
127
149
  (when forward
128
150
  {:forward
129
151
  (map #(let [[port_a port_b proto] (S/split % #"[:/]")]
130
152
  [(js/parseInt port_a) (js/parseInt port_b) proto])
131
- forward)}))]
153
+ forward)})
154
+ (when (and forward docker-eth0-address)
155
+ {:route (conj route (str docker-eth0-address "/32"))})
156
+ (when netem
157
+ {:netem netem}))]
132
158
  (when forward
133
159
  (let [link-id (str (or (:service link) (:container link)) ":" dev)
134
160
  pre (str "link '" link-id "' has forward setting")]
@@ -148,8 +174,9 @@ General Options:
148
174
  is loaded otherwise fall back to :linux. Exit with an error if mode is :ovs
149
175
  or :patch and the 'openvswitch' or 'act_mirred' kernel modules are not
150
176
  loaded respectively."
151
- [{:as bridge-opts :keys [bridge mode]}]
152
- (let [{:keys [warn default-bridge-mode kmod-ovs? kmod-mirred?]} @ctx
177
+ [{:as bridge-opts :keys [bridge mode]} opts]
178
+ (let [{:keys [warn kmod-ovs? kmod-mirred?]} @ctx
179
+ {:keys [default-bridge-mode]} opts
153
180
  mode (keyword (or mode default-bridge-mode))
154
181
  _ (when (and (= :ovs mode) (not kmod-ovs?))
155
182
  (fatal 1 (str "bridge " bridge " mode is 'ovs', "
@@ -157,11 +184,11 @@ General Options:
157
184
  _ (when (and (= :patch mode) (not kmod-mirred?))
158
185
  (warn (str "bridge " bridge " mode is 'patch', "
159
186
  "but no 'act_mirred' kernel module loaded, "
160
- " assuming it will load when needed.")))
187
+ "assuming it will load when needed.")))
161
188
  _ (when (and (= :auto mode) (not kmod-ovs?))
162
189
  (warn (str "bridge " bridge " mode is 'auto', "
163
- " but no 'openvswitch' kernel module loaded, "
164
- " so falling back to 'linux'")))
190
+ "but no 'openvswitch' kernel module loaded, "
191
+ "so falling back to 'linux'")))
165
192
  mode (if (= :auto mode)
166
193
  (if kmod-ovs? :ovs :linux)
167
194
  mode)]
@@ -172,8 +199,9 @@ General Options:
172
199
  add :bridges, :containers, and :services maps with restructured bridge, link,
173
200
  and command configuration to provide a more efficient structure for looking
174
201
  up configuration later."
175
- [{:as cfg :keys [links commands bridges]}]
176
- (let [bridge-map (reduce (fn [acc b] (assoc acc (:bridge b) b))
202
+ [{:as cfg :keys [links bridges tunnels commands]} opts]
203
+ (let [bridge-map (reduce (fn [bs b]
204
+ (assoc bs (:bridge b) b))
177
205
  {} bridges)
178
206
  ;; Add bridges specified in links only
179
207
  all-bridges (reduce (fn [bs b]
@@ -181,21 +209,33 @@ General Options:
181
209
  bridge-map
182
210
  (keep :bridge links))
183
211
  ;; Enrich each bridge
184
- bridges (reduce (fn [bs [k v]] (assoc bs k (enrich-bridge v)))
185
- {} all-bridges)
186
- links (mapv #(enrich-link % bridges) links)
187
- cfg (merge cfg {:links links
188
- :bridges bridges
189
- :containers {}
190
- :services {}})
212
+ enriched-bridges (reduce (fn [bs [k v]]
213
+ (assoc bs k (enrich-bridge v opts)))
214
+ {} all-bridges)
215
+ ;; Restructure links into a map to merge
216
+ link-map (reduce (fn [ls link]
217
+ ;; Merge key is server/container + dev
218
+ (let [lid (str (or (:service link)
219
+ (:container link))
220
+ ":" (get link :dev "eth0"))]
221
+ (update ls lid deep-merge link)))
222
+ {} links)
223
+ enriched-links (map #(enrich-link % enriched-bridges opts)
224
+ (vals link-map))
225
+
226
+ cfg {:bridges enriched-bridges
227
+ :tunnels tunnels
228
+ :containers {}
229
+ :services {}}
191
230
  rfn (fn [kind cfg {:as x :keys [container service]}]
192
231
  (cond-> cfg
193
232
  container (update-in [:containers container kind] conjv x)
194
233
  service (update-in [:services service kind] conjv x)))
195
- cfg (reduce (partial rfn :links) cfg links)
234
+ cfg (reduce (partial rfn :links) cfg enriched-links)
196
235
  cfg (reduce (partial rfn :commands) cfg commands)]
197
236
  cfg))
198
237
 
238
+
199
239
  (defn ajv-error-to-str [error]
200
240
  (let [path (:instancePath error)
201
241
  params (dissoc (:params error) :type :pattern :missingProperty)]
@@ -204,8 +244,7 @@ General Options:
204
244
  (if (not (empty? params)) (str " " params) ""))))
205
245
 
206
246
  (defn check-schema [data schema verbose]
207
- (let [{:keys [info warn]} @ctx
208
- ajv (Ajv. #js {:allErrors true})
247
+ (let [ajv (Ajv. #js {:allErrors true})
209
248
  validator (.compile ajv (->js schema))
210
249
  valid (validator (->js data))]
211
250
  (if valid
@@ -272,7 +311,6 @@ General Options:
272
311
  container properties from an event and the current pid of the
273
312
  network container. Updates iterable properties of the link
274
313
  (via link-add-offset) and adds the following keys:
275
- - :container - the container properties (passed in)
276
314
  - :outer-pid - PID of the network namespace (passed in)
277
315
  - :pid - PID of this container
278
316
  - :dev-id - container name + container interface name
@@ -288,8 +326,7 @@ General Options:
288
326
  link (if (and outer-pid (not (:outer-dev link)))
289
327
  (assoc link :outer-dev (link-outer-dev link id index))
290
328
  link)
291
- link (merge link {:container container
292
- :dev-id dev-id
329
+ link (merge link {:dev-id dev-id
293
330
  :pid pid
294
331
  :outer-pid outer-pid})]
295
332
  link))
@@ -350,6 +387,19 @@ General Options:
350
387
  res (run cmd {:quiet true})]
351
388
  (= 0 (:code res))))
352
389
 
390
+ (defn intf-ipv4-addresses
391
+ "Return a sequence of IPv4 addresses for the interface."
392
+ [intf]
393
+ (P/let [cmd (str "ip -json addr show dev " intf)
394
+ res (run cmd {:quiet true})
395
+ addrs (when (= 0 (:code res))
396
+ (js->clj (js/JSON.parse (:stdout res))
397
+ :keywordize-keys true))]
398
+ (->> addrs
399
+ (mapcat :addr_info)
400
+ (filter #(= "inet" (:family %)))
401
+ (map :local))))
402
+
353
403
  (defn rename-docker-eth0
354
404
  "Rename docker's provided eth0 to DOCKER-INTF to prevent 'RTNETLINK
355
405
  answers: File exists' errors during creation of links that use
@@ -411,7 +461,8 @@ General Options:
411
461
  (if (not cmd)
412
462
  (info (str "Ignoring bridge/switch " bridge " for mode " mode))
413
463
  (P/let [_ (info "Creating bridge/switch" bridge)
414
- res (run* [cmd (str "ip link set " bridge " up")])]
464
+ res (run* [cmd (str "ip link set " bridge " up")]
465
+ {:id "bridge-create"})]
415
466
  (if (not= 0 (:code res))
416
467
  (error (str "Unable to create bridge/switch " bridge))
417
468
  (swap! ctx assoc-in [:network-state :bridges bridge :status] :created))
@@ -510,9 +561,10 @@ General Options:
510
561
  (when outer-pid (str " --pid1 " outer-pid))
511
562
  (when outer-dev (str " --intf1 " outer-dev))
512
563
  (S/join ""
513
- (for [o LINK-ADD-OPTS]
514
- (when-let [v (get link o)]
515
- (str " --" (name o) " '" v "'")))))
564
+ (for [o LINK-ADD-OPTS
565
+ :let [v (get link o [])]
566
+ vo (if (sequential? v) v [v])]
567
+ (str " --" (name o) " '" vo "'"))))
516
568
  res (run cmd {:id dev-id})]
517
569
  (when (not= 0 (:code res))
518
570
  (error (str "Unable to add " (name type) " " dev-id)))
@@ -540,7 +592,7 @@ General Options:
540
592
  forwards defined by :forward property of 'link'."
541
593
  [link action]
542
594
  (P/let [{:keys [error]} @ctx
543
- {:keys [outer-dev dev-id bridge ip forward]} link]
595
+ {:keys [dev-id bridge ip forward]} link]
544
596
  (P/all (for [fwd forward]
545
597
  (P/let [[port_a port_b proto] fwd
546
598
  ip (S/replace ip #"/.*" "")
@@ -562,8 +614,9 @@ General Options:
562
614
  running in a container)"
563
615
  []
564
616
  (P/let [[cgroup mountinfo]
565
- , (P/all [(read-file "/proc/self/cgroup" "utf8")
566
- (read-file "/proc/self/mountinfo" "utf8")])
617
+ , (P/catch (P/all [(read-file "/proc/self/cgroup" "utf8")
618
+ (read-file "/proc/self/mountinfo" "utf8")])
619
+ #(vector "" ""))
567
620
  ;; docker
568
621
  d-cgroups (map second (re-seq #"/docker/([^/\n]*)" cgroup))
569
622
  ;; podman (root)
@@ -604,6 +657,18 @@ General Options:
604
657
  (S/replace #"\." "-")))
605
658
  v])))
606
659
 
660
+ (defn query-container-data
661
+ [container-obj]
662
+ (P/let
663
+ [container (inspect-container container-obj)
664
+ clabels (get-compose-labels container)
665
+ svc-num (:container-number clabels)]
666
+ {:name (->> container :Name (re-seq #"(.*/)?(.*)") first last)
667
+ :index (if svc-num (js/parseInt svc-num) 1)
668
+ :service (:service clabels)
669
+ :pid (-> container :State :Pid)
670
+ :labels clabels}))
671
+
607
672
  ;;;
608
673
 
609
674
  (defn docker-client
@@ -659,7 +724,7 @@ General Options:
659
724
  (condp = action
660
725
  "start"
661
726
  (if link-status
662
- (error (str "Link " dev-id " already exists"))
727
+ (error (str "Link " dev-id " already in state: " link-status))
663
728
  (P/do
664
729
  (swap! ctx assoc-in status-path :creating)
665
730
  (link-add link)
@@ -730,29 +795,26 @@ General Options:
730
795
  if all containers/services are connected."
731
796
  [client {:keys [status id]}]
732
797
  (P/let
733
- [{:keys [log info network-config compose-opts self-pid]} @ctx
798
+ [{:keys [log info network-config network-state compose-opts self-pid]} @ctx
734
799
  container-obj (get-container client id)
735
- container (inspect-container container-obj)
736
- cname (->> container :Name (re-seq #"(.*/)?(.*)") first last)
737
- pid (-> container :State :Pid)
738
-
739
- clabels (get-compose-labels container)
740
- svc-name (:service clabels)
741
- svc-num (:container-number clabels)
742
- cindex (if svc-num (js/parseInt svc-num) 1)
743
- container-info {:id id
744
- :name cname
745
- :index cindex
746
- :service svc-name
747
- :pid pid
748
- :labels clabels}
800
+ container-data (if (= "die" status)
801
+ (P/let [ci (get-in network-state [:containers id])]
802
+ (swap! ctx update-in [:network-state :containers]
803
+ dissoc id)
804
+ ci)
805
+ (P/let [ci (query-container-data container-obj)]
806
+ (swap! ctx update-in [:network-state :containers]
807
+ assoc id ci)
808
+ ci))
809
+ {cname :name clabels :labels} container-data
749
810
 
750
811
  svc-match? (and (let [p (:project compose-opts)]
751
812
  (or (not p) (= p (:project clabels))))
752
813
  (let [d (:project-working_dir compose-opts)]
753
814
  (or (not d) (= d (:project-working_dir clabels)))))
754
815
  containers (get-in network-config [:containers cname])
755
- services (when svc-match? (get-in network-config [:services svc-name]))
816
+ services (when svc-match?
817
+ (get-in network-config [:services (:service clabels)]))
756
818
  links (concat (:links containers) (:links services))
757
819
  commands (concat (:commands containers) (:commands services))]
758
820
  (if (and (not (seq links)) (not (seq commands)))
@@ -761,7 +823,7 @@ General Options:
761
823
  (info "Event:" status cname id)
762
824
  (P/all (for [link links
763
825
  :let [link (link-instance-enrich
764
- link container-info self-pid)]]
826
+ link container-data self-pid)]]
765
827
  (modify-link link status)))
766
828
  (when (= "start" status)
767
829
  (P/all (for [{:keys [command]} commands]
@@ -838,15 +900,15 @@ General Options:
838
900
  kmod-ovs? (kmod-loaded? "openvswitch")
839
901
  kmod-mirred? (kmod-loaded? "act_mirred")
840
902
  docker-eth0? (and self-cid (intf-exists? "eth0"))
841
- _ (swap! ctx merge {:default-bridge-mode (:default-bridge-mode opts)
842
- :default-mtu (:default-mtu opts)
843
- :kmod-ovs? kmod-ovs?
903
+ docker-eth0-addresses (when docker-eth0? (intf-ipv4-addresses "eth0"))
904
+ _ (swap! ctx merge {:kmod-ovs? kmod-ovs?
844
905
  :kmod-mirred? kmod-mirred?
845
- :docker-eth0? docker-eth0?})
906
+ :docker-eth0? docker-eth0?
907
+ :docker-eth0-address (first docker-eth0-addresses)})
846
908
  network-config (P/-> (load-configs compose-file network-file)
847
909
  (interpolate-walk env)
848
910
  (check-schema schema verbose)
849
- (enrich-network-config))
911
+ (enrich-network-config opts))
850
912
  _ (when show-config
851
913
  (println (js/JSON.stringify (->js network-config)))
852
914
  (js/process.exit 0))
@@ -44,7 +44,7 @@
44
44
  (js/process.exit code))
45
45
 
46
46
  (defn deep-merge [a b]
47
- (merge-with #(cond (map? %1) (recur %1 %2)
47
+ (merge-with #(cond (map? %1) (deep-merge %1 %2)
48
48
  (vector? %1) (vec (concat %1 %2))
49
49
  (sequential? %1) (concat %1 %2)
50
50
  :else %2)
@@ -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
@@ -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
+
@@ -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
@@ -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