conlink 2.0.1 → 2.0.2
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/README.md +11 -6
- 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 +48 -0
- package/scripts/wait.sh +73 -0
- 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
package/old/net2dot.py
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env -S python3 -u
|
|
2
|
-
|
|
3
|
-
# Copyright (c) 2021, Viasat, Inc
|
|
4
|
-
# Licensed under MPL 2.0
|
|
5
|
-
|
|
6
|
-
import re, sys, yaml
|
|
7
|
-
|
|
8
|
-
NODE_PROPS = 'shape=box style=filled penwidth=1'
|
|
9
|
-
CONTAINER_PROPS = 'fontsize = 12 style = filled fillcolor = "#e1d5e7" color = "#9673a6"'
|
|
10
|
-
NETWORK_PROPS = '%s penwidth = 2' % CONTAINER_PROPS
|
|
11
|
-
INTF_PROPS = 'width=0.1 height=0.1 fontsize=10 fillcolor="#ffbb9e" color="#d7db00"'
|
|
12
|
-
SWITCH_PROPS = 'fontsize=12 style="rounded,filled" fillcolor="#dae8fc" color="#6c8ebf"'
|
|
13
|
-
HOST_PROPS = 'fontsize=12 fillcolor="#f5f5f5" color="#666666"'
|
|
14
|
-
|
|
15
|
-
def id(n):
|
|
16
|
-
return re.sub(r"-", "_", n)
|
|
17
|
-
|
|
18
|
-
def intfText(cluster, intf):
|
|
19
|
-
name = intf.get('intf', intf.get('origName', intf.get('name')))
|
|
20
|
-
if name.startswith('DUMMY_'):
|
|
21
|
-
return '%s__%s [shape=point style=invis]' % (
|
|
22
|
-
id(cluster), id(name))
|
|
23
|
-
else:
|
|
24
|
-
ip = intf.get('ip', intf.get('opts', {}).get('ip', ''))
|
|
25
|
-
if ip: ip = "\\n%s" % ip
|
|
26
|
-
return '%s__%s [label="%s%s" %s]' % (
|
|
27
|
-
id(cluster), id(name), name, ip, INTF_PROPS)
|
|
28
|
-
|
|
29
|
-
if __name__ == '__main__':
|
|
30
|
-
|
|
31
|
-
networkFile = sys.argv[1]
|
|
32
|
-
networkName = sys.argv[2]
|
|
33
|
-
|
|
34
|
-
netCfg = yaml.full_load(open(networkFile))
|
|
35
|
-
if 'services' in netCfg:
|
|
36
|
-
netService = re.sub(r'_1$', '', networkName)
|
|
37
|
-
netCfg = netCfg['services'][netService]['x-network']
|
|
38
|
-
mnCfg = netCfg['mininet-cfg']
|
|
39
|
-
|
|
40
|
-
links = []
|
|
41
|
-
containers = {}
|
|
42
|
-
containers[networkName] = {'nodes': []}
|
|
43
|
-
namespaces = {}
|
|
44
|
-
|
|
45
|
-
for link in netCfg.get('links', []):
|
|
46
|
-
l, r = link['left'], link['right']
|
|
47
|
-
clname, crname = l['container'], r['container']
|
|
48
|
-
ilname, irname = l['intf'], r['intf']
|
|
49
|
-
links.append([(clname, ilname), (crname, irname)])
|
|
50
|
-
for cname, intf in [(clname, l), (crname, r)]:
|
|
51
|
-
if cname not in containers:
|
|
52
|
-
containers[cname] = {'nodes': []}
|
|
53
|
-
containers[cname]['nodes'].append(intf)
|
|
54
|
-
|
|
55
|
-
for lk in mnCfg.get('links', []):
|
|
56
|
-
l, r = lk['left'], lk['right']
|
|
57
|
-
links.append([(networkName, l), (networkName, r)])
|
|
58
|
-
|
|
59
|
-
for s in mnCfg.get('switches', []):
|
|
60
|
-
namespaces[s['name']] = {'interfaces': [], 'type': 'switch', **s}
|
|
61
|
-
for h in mnCfg.get('hosts', []):
|
|
62
|
-
namespaces[h['name']] = {'interfaces': [], 'type': 'host', **h}
|
|
63
|
-
|
|
64
|
-
for i in mnCfg.get('interfaces', []):
|
|
65
|
-
nm, nd = i.get('origName', i['name']), i['node']
|
|
66
|
-
if nd in namespaces:
|
|
67
|
-
namespaces[nd]['interfaces'].append(i)
|
|
68
|
-
else:
|
|
69
|
-
links.append([(networkName, nm), (networkName, nd)])
|
|
70
|
-
|
|
71
|
-
# Make sure all namespaces have at least one interface so that
|
|
72
|
-
# they can be connected by edges (lhead, ltail)
|
|
73
|
-
for nsname, nsdata in namespaces.items():
|
|
74
|
-
if not nsdata['interfaces']:
|
|
75
|
-
nsdata['interfaces'].append({'name': 'DUMMY_%s' % nsname})
|
|
76
|
-
|
|
77
|
-
###
|
|
78
|
-
|
|
79
|
-
print('digraph D {')
|
|
80
|
-
print(' splines = true;')
|
|
81
|
-
print(' compound = true;')
|
|
82
|
-
print(' node [%s];' % NODE_PROPS)
|
|
83
|
-
|
|
84
|
-
for cname, cdata in containers.items():
|
|
85
|
-
print(' subgraph cluster_%s {' % id(cname))
|
|
86
|
-
print(' label = "%s";' % cname)
|
|
87
|
-
if cname == networkName:
|
|
88
|
-
print(' %s;' % NETWORK_PROPS)
|
|
89
|
-
else:
|
|
90
|
-
print(' %s;' % CONTAINER_PROPS)
|
|
91
|
-
for node in cdata['nodes']:
|
|
92
|
-
print(' %s;' % intfText(node['container'], node))
|
|
93
|
-
# mininet/network interface is processed after container links
|
|
94
|
-
# so that the mininet/network definitions take precedence
|
|
95
|
-
if cname == networkName:
|
|
96
|
-
for nsname, nsdata in namespaces.items():
|
|
97
|
-
print(' subgraph cluster_%s__%s {' % (
|
|
98
|
-
id(cname), id(nsname)))
|
|
99
|
-
print(' label = "%s";' % nsname)
|
|
100
|
-
if nsdata['type'] == 'switch':
|
|
101
|
-
print(' %s;' % SWITCH_PROPS)
|
|
102
|
-
else:
|
|
103
|
-
print(' %s;' % HOST_PROPS)
|
|
104
|
-
for intf in nsdata['interfaces']:
|
|
105
|
-
print(' %s;' % intfText(cname, intf))
|
|
106
|
-
print(' }')
|
|
107
|
-
print(" }")
|
|
108
|
-
|
|
109
|
-
for ((lc, ln), (rc, rn)) in links:
|
|
110
|
-
extra=''
|
|
111
|
-
if lc == networkName and ln in namespaces:
|
|
112
|
-
iname = namespaces[ln]['interfaces'][0]['name']
|
|
113
|
-
extra += ' ltail=cluster_%s__%s' % (id(networkName), id(ln))
|
|
114
|
-
ln = id(iname)
|
|
115
|
-
if rc == networkName and rn in namespaces:
|
|
116
|
-
iname = namespaces[rn]['interfaces'][0]['name']
|
|
117
|
-
extra += ' lhead=cluster_%s__%s' % (id(networkName), id(rn))
|
|
118
|
-
rn = id(iname)
|
|
119
|
-
print(' %s__%s -> %s__%s [dir=none%s];' % (
|
|
120
|
-
id(lc), id(ln), id(rc), id(rn), extra))
|
|
121
|
-
|
|
122
|
-
print("}")
|
package/old/notes-old.txt
DELETED
|
@@ -1,97 +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
|
-
- [ ] *vlan type interfaces
|
|
9
|
-
|
|
10
|
-
- Near term:
|
|
11
|
-
- [ ] dummy interfaces
|
|
12
|
-
- [ ] schema validation
|
|
13
|
-
- [ ] tc/qdisc settings
|
|
14
|
-
- [ ] arbitrary container commands
|
|
15
|
-
|
|
16
|
-
- Further term:
|
|
17
|
-
- [ ] CNI networking support
|
|
18
|
-
- [ ] tunnel interfaces
|
|
19
|
-
- [ ] multiple routes
|
|
20
|
-
- [ ] ovs flow config
|
|
21
|
-
- [ ] Multiple bridge-modes
|
|
22
|
-
- bridge-mode as part of the domain definition so that the
|
|
23
|
-
same conlink instances can support multiple bridge modes
|
|
24
|
-
simultaneously (with a default for links that don't
|
|
25
|
-
specify).
|
|
26
|
-
- [ ] CNI model:
|
|
27
|
-
- conlink runs in container listening for events on a UDS
|
|
28
|
-
(intead of docker events)
|
|
29
|
-
- an outer conlink command is the CNI client that formats
|
|
30
|
-
events to send over the UDS to the inner conlink
|
|
31
|
-
|
|
32
|
-
- Also see schema-ish.yaml
|
|
33
|
-
links:
|
|
34
|
-
- type: TYPE # Default: domain.
|
|
35
|
-
# Others: dummy, tunnel, host, *vlan, etc
|
|
36
|
-
|
|
37
|
-
domain: DOMAIN # ovs switch name
|
|
38
|
-
|
|
39
|
-
container: FOO # full container name
|
|
40
|
-
# OR
|
|
41
|
-
service: FOO # compose service name
|
|
42
|
-
|
|
43
|
-
interface: INTF # internal container interface name
|
|
44
|
-
|
|
45
|
-
# --- optional general ---
|
|
46
|
-
|
|
47
|
-
ip(s): IP # starting address, can include net slash to limit max
|
|
48
|
-
mac: MAC
|
|
49
|
-
mtu: MTU
|
|
50
|
-
route(s): ROUTE # `ip route add ROUTE`, maybe add "dev INTF" automatically
|
|
51
|
-
tc(s): TC # tc/qdisc commands/settings
|
|
52
|
-
flow(s): FLOW # `ovs-ofctl add-flow DOMAIN FLOW`. With var templating.
|
|
53
|
-
command(s): CMD # arbitrary shell cmd. After all links setup for this container
|
|
54
|
-
|
|
55
|
-
# --- optional for 'type:' links ---
|
|
56
|
-
|
|
57
|
-
host-intf: INTF # host interface to *vlan or move in
|
|
58
|
-
mode: MODE # bridge, etc
|
|
59
|
-
vlanid: VLANID # VLAN #
|
|
60
|
-
nat: NAT # nat target
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- type maps to 'ip link' type with default of 'veth'
|
|
64
|
-
-
|
|
65
|
-
- when type is 'veth', then base default is 'conlink'
|
|
66
|
-
- when type is 'veth' and base is 'conlink', then bridge is required.
|
|
67
|
-
|
|
68
|
-
- conlink veth link: {type: veth [DEFAULT], base: conlink [DEFAULT], bridge: BRIDGE, dev: DEV}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Dependencies in python version:
|
|
73
|
-
- argparse
|
|
74
|
-
- shlex (parsing commands)
|
|
75
|
-
- compose_interpolation import TemplateWithDefaults
|
|
76
|
-
- cerberus import Validator
|
|
77
|
-
- options: joi, ajv, json-schema, and z-schema.
|
|
78
|
-
- docker
|
|
79
|
-
- psutil (pid_exists)
|
|
80
|
-
- json
|
|
81
|
-
- yaml
|
|
82
|
-
- mininet
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- [deprecated idea] conlink sub-commands:
|
|
86
|
-
conlink spit
|
|
87
|
-
- output override docker-compose file with conlink service
|
|
88
|
-
- figure out volume mounts to get to other compose file(s)
|
|
89
|
-
conlink dc up ...
|
|
90
|
-
- generate override docker-compose file with conlink service
|
|
91
|
-
- run the compose command with override file
|
|
92
|
-
conlink start
|
|
93
|
-
- start inside compose
|
|
94
|
-
conlink run
|
|
95
|
-
- start outside compose
|
|
96
|
-
|
|
97
|
-
|
package/old/package.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "conlink",
|
|
3
|
-
"dependencies": {
|
|
4
|
-
"@exodus/schemasafe": "^1.3.0",
|
|
5
|
-
"ajv": "^8.12.0",
|
|
6
|
-
"dockerode": "^3.3.4",
|
|
7
|
-
"joi": "^17.10.2",
|
|
8
|
-
"nbb": "^1.2.178",
|
|
9
|
-
"neodoc": "^2.0.2",
|
|
10
|
-
"yaml": "^2.2.1"
|
|
11
|
-
},
|
|
12
|
-
"devDependencies": {
|
|
13
|
-
"shadow-cljs": "^2.25.7",
|
|
14
|
-
"source-map-support": "^0.5.21"
|
|
15
|
-
}
|
|
16
|
-
}
|
package/old/schema.yaml
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
links:
|
|
2
|
-
type: list
|
|
3
|
-
schema:
|
|
4
|
-
type: dict
|
|
5
|
-
schema:
|
|
6
|
-
left:
|
|
7
|
-
type: dict
|
|
8
|
-
required: true
|
|
9
|
-
schema:
|
|
10
|
-
container: {type: string, required: true}
|
|
11
|
-
intf: {type: string, required: true}
|
|
12
|
-
ip: {type: string, required: false,
|
|
13
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
14
|
-
mac: {type: string, required: false,
|
|
15
|
-
regex: '([0-9A-Fa-f][0-9A-Fa-f]:){5}[0-9A-Fa-f][0-9A-Fa-f]'}
|
|
16
|
-
right:
|
|
17
|
-
type: dict
|
|
18
|
-
required: true
|
|
19
|
-
schema:
|
|
20
|
-
container: {type: string, required: true}
|
|
21
|
-
intf: {type: string, required: true}
|
|
22
|
-
ip: {type: string, required: false,
|
|
23
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
24
|
-
mac: {type: string, required: false,
|
|
25
|
-
regex: '([0-9A-Fa-f][0-9A-Fa-f]:){5}[0-9A-Fa-f][0-9A-Fa-f]'}
|
|
26
|
-
|
|
27
|
-
tunnels:
|
|
28
|
-
type: list
|
|
29
|
-
schema:
|
|
30
|
-
type: dict
|
|
31
|
-
schema:
|
|
32
|
-
type: {type: string, required: true}
|
|
33
|
-
intf: {type: string, required: true}
|
|
34
|
-
vni: {type: number, required: true}
|
|
35
|
-
remote: {type: string, required: true,
|
|
36
|
-
regex: '([0-9]+\.){3}[0-9]+'}
|
|
37
|
-
ip: {type: string, required: false,
|
|
38
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
39
|
-
mac: {type: string, required: false,
|
|
40
|
-
regex: '([0-9A-Fa-f][0-9A-Fa-f]:){5}[0-9A-Fa-f][0-9A-Fa-f]'}
|
|
41
|
-
link_args: {type: string, required: false}
|
|
42
|
-
|
|
43
|
-
interfaces:
|
|
44
|
-
type: list
|
|
45
|
-
schema:
|
|
46
|
-
type: dict
|
|
47
|
-
required: true
|
|
48
|
-
schema:
|
|
49
|
-
type: {type: string, required: true,
|
|
50
|
-
allowed: [link, vlan, macvlan, macvtap, ipvlan, ipvtap]}
|
|
51
|
-
container: {type: string, required: true}
|
|
52
|
-
host-intf: {type: string, required: true}
|
|
53
|
-
intf: {type: string, required: true}
|
|
54
|
-
mode: {type: string, required: false,
|
|
55
|
-
dependencies: {type: [macvlan, macvtap, ipvlan, ipvtap]}}
|
|
56
|
-
vlanid: {type: number, required: false,
|
|
57
|
-
dependencies: {type: [vlan]}}
|
|
58
|
-
ip: {type: string, required: false,
|
|
59
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
60
|
-
nat: {type: string, required: false,
|
|
61
|
-
regex: '([0-9]+\.){3}[0-9]+',
|
|
62
|
-
dependencies: ip}
|
|
63
|
-
|
|
64
|
-
network-settings: {type: string}
|
|
65
|
-
|
|
66
|
-
commands:
|
|
67
|
-
type: list
|
|
68
|
-
schema:
|
|
69
|
-
type: dict
|
|
70
|
-
schema:
|
|
71
|
-
container: {type: string, required: true}
|
|
72
|
-
command:
|
|
73
|
-
required: true
|
|
74
|
-
oneof: [ {type: string}, {type: list, schema: {type: string}} ]
|
|
75
|
-
|
|
76
|
-
mininet-cfg:
|
|
77
|
-
type: dict
|
|
78
|
-
schema:
|
|
79
|
-
|
|
80
|
-
switches:
|
|
81
|
-
type: list
|
|
82
|
-
required: false
|
|
83
|
-
schema:
|
|
84
|
-
type: dict
|
|
85
|
-
schema:
|
|
86
|
-
name: {type: string, required: true}
|
|
87
|
-
opts: {type: dict, required: false}
|
|
88
|
-
|
|
89
|
-
hosts:
|
|
90
|
-
type: list
|
|
91
|
-
required: false
|
|
92
|
-
schema:
|
|
93
|
-
type: dict
|
|
94
|
-
schema:
|
|
95
|
-
name: {type: string, required: true}
|
|
96
|
-
opts: {type: dict, required: false}
|
|
97
|
-
|
|
98
|
-
containers:
|
|
99
|
-
type: list
|
|
100
|
-
required: false
|
|
101
|
-
schema:
|
|
102
|
-
type: dict
|
|
103
|
-
schema:
|
|
104
|
-
name: {type: string, required: true}
|
|
105
|
-
opts: {type: dict, required: false}
|
|
106
|
-
|
|
107
|
-
links:
|
|
108
|
-
type: list
|
|
109
|
-
required: false
|
|
110
|
-
schema:
|
|
111
|
-
type: dict
|
|
112
|
-
schema:
|
|
113
|
-
left: {type: string, required: true}
|
|
114
|
-
right: {type: string, required: true}
|
|
115
|
-
opts: {type: dict, required: false}
|
|
116
|
-
|
|
117
|
-
interfaces:
|
|
118
|
-
type: list
|
|
119
|
-
required: false
|
|
120
|
-
schema:
|
|
121
|
-
type: dict
|
|
122
|
-
schema:
|
|
123
|
-
node: {type: string, required: true}
|
|
124
|
-
name: {type: string, required: true}
|
|
125
|
-
origName: {type: string, required: false}
|
|
126
|
-
opts: {type: dict, required: false}
|
|
127
|
-
|
|
128
|
-
commands:
|
|
129
|
-
type: list
|
|
130
|
-
required: false
|
|
131
|
-
schema:
|
|
132
|
-
type: dict
|
|
133
|
-
schema:
|
|
134
|
-
node: {type: string, required: true}
|
|
135
|
-
sync: {type: boolean, required: false}
|
|
136
|
-
command:
|
|
137
|
-
required: true
|
|
138
|
-
oneof: [ {type: string}, {type: list, schema: {type: string}} ]
|
package/old/schema.yaml.bak
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
$defs:
|
|
2
|
-
one_link:
|
|
3
|
-
|
|
4
|
-
type: object
|
|
5
|
-
additionalProperties: false
|
|
6
|
-
required: ["links"]
|
|
7
|
-
properties:
|
|
8
|
-
links:
|
|
9
|
-
type: array
|
|
10
|
-
items:
|
|
11
|
-
type: object
|
|
12
|
-
# oneOf: [{required: ["container"]},
|
|
13
|
-
# {required: ["service"]},
|
|
14
|
-
# #{required: ["bridge"], properties: {type: {const: {oneOf: ["geneve", "vxlan"]}}}}]
|
|
15
|
-
# #{properties: {type: {const: "geneve"}}, required: ["bridge"]},
|
|
16
|
-
# #{properties: {type: {const: "vxlan"}}, required: ["bridge"]}
|
|
17
|
-
# {allOf: [{properties: {type: {const: "geneve"}}},
|
|
18
|
-
# {properties: {type: {const: "vxlan"}}}]}
|
|
19
|
-
# ]
|
|
20
|
-
|
|
21
|
-
# if: {properties: {type: {const: "veth"}}}
|
|
22
|
-
# then:
|
|
23
|
-
# allOf:
|
|
24
|
-
# - {required: ["bridge"]}
|
|
25
|
-
# - {not: {required: ["vlanid", "vni", "remote"]}}
|
|
26
|
-
# else:
|
|
27
|
-
# not: {required: ["bridge"]}
|
|
28
|
-
# if: {properties: {type: {const: "vlan"}}}
|
|
29
|
-
# then: {required: ["vlanid"]}
|
|
30
|
-
# else: {not: {required: ["vlanid"]}}
|
|
31
|
-
|
|
32
|
-
allOf:
|
|
33
|
-
- if: {properties: {type: {const: "veth"}}}
|
|
34
|
-
then: {required: ["bridge"]}
|
|
35
|
-
else: {not: {required: ["BOGUS"]}}
|
|
36
|
-
- if: {properties: {type: {const: "geneve"}}}
|
|
37
|
-
then: {required: ["bridge", "remote", "vni"]}
|
|
38
|
-
#else: {not: {required: ["bridge", "remote", "vni"]}}
|
|
39
|
-
else: {not: {required: ["BOGUS"]}}
|
|
40
|
-
- if: {properties: {type: {const: "vxlan"}}}
|
|
41
|
-
then: {required: ["bridge", "remote", "vni"]}
|
|
42
|
-
#else: {not: {required: ["bridge", "remote", "vni"]}}
|
|
43
|
-
else: {not: {required: ["BOGUS"]}}
|
|
44
|
-
|
|
45
|
-
additionalProperties: false
|
|
46
|
-
properties:
|
|
47
|
-
type:
|
|
48
|
-
type: string
|
|
49
|
-
default: "veth"
|
|
50
|
-
enum: [veth, dummy, vlan, ipvlan, ipvtap, macvlan, macvtap, geneve, vxlan]
|
|
51
|
-
service: {type: string}
|
|
52
|
-
container: {type: string}
|
|
53
|
-
bridge: {type: string}
|
|
54
|
-
dev: {type: string, default: "eth0"}
|
|
55
|
-
ip: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+/[0-9]*$"}
|
|
56
|
-
mac: {type: string, pattern: "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$"}
|
|
57
|
-
mtu: {type: number}
|
|
58
|
-
route: {type: string}
|
|
59
|
-
|
|
60
|
-
vlanid: {type: number}
|
|
61
|
-
nat: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+/[0-9]*$"}
|
|
62
|
-
|
|
63
|
-
vni: {type: number}
|
|
64
|
-
remote: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+$"}
|
|
65
|
-
|
|
66
|
-
commands:
|
|
67
|
-
type: array
|
|
68
|
-
items:
|
|
69
|
-
type: object
|
|
70
|
-
required: ["command"]
|
|
71
|
-
oneOf: [{required: ["container"]},
|
|
72
|
-
{required: ["service"]}]
|
|
73
|
-
properties:
|
|
74
|
-
service: {type: string}
|
|
75
|
-
container: {type: string}
|
|
76
|
-
command: {type: string}
|
package/old/set-cover-old.cljs
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env nbb
|
|
2
|
-
|
|
3
|
-
(ns set-cover
|
|
4
|
-
(:require [clojure.set :refer [union]]
|
|
5
|
-
[clojure.string :as S]
|
|
6
|
-
[promesa.core :as P]
|
|
7
|
-
["path" :as path]
|
|
8
|
-
["fs/promises" :as fs]))
|
|
9
|
-
|
|
10
|
-
(defn set-covers-with-alts
|
|
11
|
-
"Return all the set covers of a graph containing alternation nodes"
|
|
12
|
-
([graph start] (set-covers-with-alts graph [] #{} [start]))
|
|
13
|
-
([graph result visited pending]
|
|
14
|
-
(loop [result result visited visited pending pending]
|
|
15
|
-
(let [[node & pending] pending]
|
|
16
|
-
(if (coll? node)
|
|
17
|
-
(mapcat
|
|
18
|
-
(fn [node]
|
|
19
|
-
(let [[result visited] (if (contains? visited node)
|
|
20
|
-
[result visited]
|
|
21
|
-
[(conj result node) (conj visited node)])
|
|
22
|
-
pending (into (vec pending) [node])]
|
|
23
|
-
(set-covers-with-alts graph result visited pending)))
|
|
24
|
-
node)
|
|
25
|
-
(let [[result visited] (if (contains? visited node)
|
|
26
|
-
[result visited]
|
|
27
|
-
[(conj result node) (conj visited node)])
|
|
28
|
-
children (filter #(not (contains? visited %)) (graph node))
|
|
29
|
-
pending (into (vec pending) (vec children))]
|
|
30
|
-
(if (empty? pending)
|
|
31
|
-
[result]
|
|
32
|
-
(recur result visited pending))))))))
|
|
33
|
-
|
|
34
|
-
(defn min-set-cover-with-alts
|
|
35
|
-
"Call set-covers-with-alts and then return shortest path (if tie
|
|
36
|
-
then picks first)."
|
|
37
|
-
[graph start]
|
|
38
|
-
(let [[start graph] (if (coll? start)
|
|
39
|
-
[:START (merge graph {:START (set start)})]
|
|
40
|
-
[start graph])
|
|
41
|
-
covers (set-covers-with-alts graph start)
|
|
42
|
-
counts (group-by count covers)
|
|
43
|
-
smallest (apply min (keys counts))]
|
|
44
|
-
(-> (get counts smallest) first next)))
|
|
45
|
-
|
|
46
|
-
(defn deps-split [s] (if (empty? s) [] (S/split s #"[, \n]+")))
|
|
47
|
-
|
|
48
|
-
(defn load-deps
|
|
49
|
-
[path start-deps]
|
|
50
|
-
(P/let [add-deps #(reduce (fn [g [a b]] (update g a (fnil conj []) b)) %1 %2)
|
|
51
|
-
pending (map #(vector :START %)
|
|
52
|
-
(deps-split (S/join "," start-deps)))]
|
|
53
|
-
(P/loop [graph (add-deps {} pending)
|
|
54
|
-
pending pending
|
|
55
|
-
visited #{}]
|
|
56
|
-
(prn :graph graph)
|
|
57
|
-
(P/let [[[node dep] & pending] pending]
|
|
58
|
-
(if (not dep) ;; done
|
|
59
|
-
graph
|
|
60
|
-
(if (contains? visited dep) ;; already processed
|
|
61
|
-
(P/recur graph pending visited)
|
|
62
|
-
(P/let [file (path/join path dep "deps")
|
|
63
|
-
content (P/catch (fs/readFile file "utf8") #(identity ""))
|
|
64
|
-
deps (map #(vector dep %) (deps-split content))]
|
|
65
|
-
(P/recur (add-deps graph deps)
|
|
66
|
-
(apply conj pending deps)
|
|
67
|
-
(conj visited dep)))))))))
|
|
68
|
-
|
|
69
|
-
(P/let [graph (load-deps "./modes1" *command-line-args*)
|
|
70
|
-
modes (min-set-cover-with-alts graph :START)]
|
|
71
|
-
(prn :graph graph)
|
|
72
|
-
(prn :modes modes))
|
|
73
|
-
|
|
74
|
-
#_(def start-deps (deps-split (S/join "," *command-line-args*)))
|
|
75
|
-
|
|
76
|
-
#_(defn load-deps
|
|
77
|
-
[graph path node children]
|
|
78
|
-
(P/let [children (filter #(not (contains? graph %)) children)
|
|
79
|
-
_ (prn :load-deps :path path :node node :children children)
|
|
80
|
-
graph (reduce (fn [g dep]
|
|
81
|
-
(update g node (fnil conj []) dep))
|
|
82
|
-
graph children)
|
|
83
|
-
contents (P/all (for [child children]
|
|
84
|
-
(P/let [file (path/join path child "deps")
|
|
85
|
-
content (P/catch (fs/readFile file "utf8")
|
|
86
|
-
#(identity ""))]
|
|
87
|
-
|
|
88
|
-
(println " " :file file :node child :content (S/trimr content))
|
|
89
|
-
[child (S/trimr content)])))
|
|
90
|
-
_ (println " " :contents contents)
|
|
91
|
-
node-children (->> (for [[node child-content] contents
|
|
92
|
-
:when (not (empty? child-content))]
|
|
93
|
-
[node (deps-split (S/join "," child-content))])
|
|
94
|
-
(apply concat))]
|
|
95
|
-
;;(println " " :node-children node-children)
|
|
96
|
-
(P/loop [graph graph
|
|
97
|
-
node-children node-children]
|
|
98
|
-
(if (empty? node-children)
|
|
99
|
-
graph
|
|
100
|
-
(P/let [[node children] node-children
|
|
101
|
-
new-graph (load-deps graph path node children)]
|
|
102
|
-
(P/recur new-graph (next node-children)))))))
|
|
103
|
-
|
|
104
|
-
#_(P/let [d (load-deps {} "./modes1" :START start-deps)]
|
|
105
|
-
(prn :result d))
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
;;(prn :start-deps start-deps)
|
|
109
|
-
;;(P/loop [node :START
|
|
110
|
-
;; files start-deps
|
|
111
|
-
;; graph (reduce (fn [g dep] (update g :START (fnil conj []) dep))
|
|
112
|
-
;; {} files)
|
|
113
|
-
;; contents (P/all (for [node deps]
|
|
114
|
-
;; (P/let [file node
|
|
115
|
-
;; content (P/catch (fs/readFile file "utf8")
|
|
116
|
-
;; #(identity ""))]
|
|
117
|
-
;; [node content])))]
|
|
118
|
-
;; (P/let [graph
|
|
119
|
-
;; contents (P/all (for [file files]
|
|
120
|
-
;; (P/let [content (P/catch (fs/readFile file "utf8")
|
|
121
|
-
;; #(identity ""))]
|
|
122
|
-
;; [file content])))
|
|
123
|
-
;; graph (reduce (fn [g [dep content]]
|
|
124
|
-
;; (update g (fnil conj []) dep
|
|
125
|
-
;; ))
|
|
126
|
-
;; graph cotents)
|
|
127
|
-
;; ]
|
|
128
|
-
;; (if (empty? contents)
|
|
129
|
-
;; (prn :graph graph)
|
|
130
|
-
;; (P/recur )
|
|
131
|
-
;; )))
|
|
132
|
-
;;
|
|
133
|
-
;; (P/let [contents (P/all (for [file files]
|
|
134
|
-
;; (P/let [content (P/catch (fs/readFile file "utf8")
|
|
135
|
-
;; #(identity ""))]
|
|
136
|
-
;; [file content])))
|
|
137
|
-
;; graph (reduce (fn [g [dep content]]
|
|
138
|
-
;; (update g (fnil conj []) dep
|
|
139
|
-
;; )
|
|
140
|
-
;; graph cotents)
|
|
141
|
-
;; _ (prn :here3)
|
|
142
|
-
;; exists (P/catch (P/do (fs/access file) true) #(identity false))
|
|
143
|
-
;; _ (prn :exists exists)
|
|
144
|
-
;; content (if exists
|
|
145
|
-
;; (fs/readFile (first pending) "utf8")
|
|
146
|
-
;; nil)
|
|
147
|
-
;; pending (if content
|
|
148
|
-
;; (apply conj pending (S/split #"[, \n]" content))
|
|
149
|
-
;; pending)
|
|
150
|
-
;; graph (into graph
|
|
151
|
-
;; (for []))]
|
|
152
|
-
;; (prn :file file :content content :pending pending)
|
|
153
|
-
;; (if pending
|
|
154
|
-
;; (P/recur pending)
|
|
155
|
-
;; graph)))
|
|
156
|
-
;;
|
|
157
|
-
;;(fs/exists "/etc/passwd")
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
(comment
|
|
161
|
-
|
|
162
|
-
(def graph0
|
|
163
|
-
{:A [:B :C]
|
|
164
|
-
:B [:C :D]
|
|
165
|
-
:C [:E]
|
|
166
|
-
:E [:F]})
|
|
167
|
-
|
|
168
|
-
(prn :results (min-set-cover-with-alts graph0 :A))
|
|
169
|
-
|
|
170
|
-
(def graph1
|
|
171
|
-
{:A [:B [:C :D]] ; A requires B AND (C OR D)
|
|
172
|
-
:B [:E :F] ; B requires E AND F
|
|
173
|
-
:C [:G] ; C requires G
|
|
174
|
-
:D [:G :H] ; D requires G AND H
|
|
175
|
-
:E [] ; E has no deps
|
|
176
|
-
:F [] ; F has no deps
|
|
177
|
-
:G [] ; G has no deps
|
|
178
|
-
:H []}) ; H has no deps
|
|
179
|
-
|
|
180
|
-
(prn :result1 (min-set-cover-with-alts graph1 :A))
|
|
181
|
-
|
|
182
|
-
(def graph2
|
|
183
|
-
{:A [:B :C]
|
|
184
|
-
:B [[:C :D]]
|
|
185
|
-
:C [:E]
|
|
186
|
-
:D [:E]})
|
|
187
|
-
|
|
188
|
-
(prn :result2 (min-set-cover-with-alts graph2 :A))
|
|
189
|
-
|
|
190
|
-
(def graph3
|
|
191
|
-
{:accel [:base [:mach3 :ab]]
|
|
192
|
-
:mach3 [:base]
|
|
193
|
-
:ab [:base]})
|
|
194
|
-
|
|
195
|
-
(prn :result3.1 (min-set-cover-with-alts graph3 [:accel :ab]))
|
|
196
|
-
(prn :result3.2 (min-set-cover-with-alts graph3 [:accel :mach3]))
|
|
197
|
-
|
|
198
|
-
(def graph4
|
|
199
|
-
{:A [:B :C]
|
|
200
|
-
:B [[:D :C]]})
|
|
201
|
-
|
|
202
|
-
(prn :result4-all (set-covers-with-alts graph4 :A))
|
|
203
|
-
(prn :result4-min (min-set-cover-with-alts graph4 :A))
|
|
204
|
-
|
|
205
|
-
)
|