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.
Files changed (74) hide show
  1. package/README.md +11 -6
  2. package/examples/test4-multiple/modes/all/deps +1 -0
  3. package/examples/test4-multiple/{base-compose.yaml → modes/base/compose.yaml} +3 -3
  4. package/examples/test4-multiple/{node1-compose.yaml → modes/node1/compose.yaml} +0 -3
  5. package/examples/test4-multiple/{nodes2-compose.yaml → modes/nodes2/compose.yaml} +0 -5
  6. package/examples/test4-multiple/modes/web/compose.yaml +5 -0
  7. package/examples/test4-multiple/modes/web/deps +1 -0
  8. package/mdc +108 -0
  9. package/package.json +2 -1
  10. package/scripts/copy.sh +48 -0
  11. package/scripts/wait.sh +73 -0
  12. package/.env +0 -3
  13. package/TODO +0 -34
  14. package/examples/data.dot +0 -457
  15. package/examples/net2dot-data.dot +0 -123
  16. package/examples/net2dot.dot +0 -457
  17. package/examples/test1-data.dot +0 -82
  18. package/examples/test1.dot +0 -286
  19. package/examples/test4-multiple/all-compose.yaml +0 -5
  20. package/examples/test4-multiple/web-network.yaml +0 -2
  21. package/host-build.yaml +0 -1
  22. package/inspect.json +0 -210
  23. package/modes0/a/deps +0 -1
  24. package/modes0/b/deps +0 -1
  25. package/modes0/c/deps +0 -1
  26. package/modes0/e/deps +0 -1
  27. package/modes1/a/deps +0 -1
  28. package/modes1/b/deps +0 -1
  29. package/modes1/c/deps +0 -1
  30. package/modes1/d/deps +0 -1
  31. package/modes2/a/deps +0 -1
  32. package/modes2/b/deps +0 -1
  33. package/modes2/c/deps +0 -1
  34. package/modes2/d/de +0 -1
  35. package/modes2/d/deps +0 -1
  36. package/modes3/accel/deps +0 -1
  37. package/modes4/a/deps +0 -1
  38. package/modes4/b/deps +0 -1
  39. package/net2dot.mjs +0 -21
  40. package/notes.txt +0 -82
  41. package/old/Dockerfile.bak +0 -26
  42. package/old/add-link.sh +0 -82
  43. package/old/conlink +0 -12
  44. package/old/conlink.cljs +0 -131
  45. package/old/dot_gitignore +0 -1
  46. package/old/examples/test2-compose.yaml +0 -32
  47. package/old/examples/test2-network.yaml +0 -42
  48. package/old/graphviz.cljs +0 -14
  49. package/old/move-link.sh +0 -108
  50. package/old/net2dot.cljs +0 -114
  51. package/old/net2dot.py +0 -122
  52. package/old/notes-old.txt +0 -97
  53. package/old/package.json +0 -16
  54. package/old/schema.yaml +0 -138
  55. package/old/schema.yaml.bak +0 -76
  56. package/old/set-cover-old.cljs +0 -205
  57. package/old/set-cover-old2.cljs +0 -150
  58. package/old/test2b-compose.yaml +0 -18
  59. package/old/veth-link.sh +0 -96
  60. package/read-stream.cljs +0 -12
  61. package/resolve-deps.cljs +0 -183
  62. package/schema-ish.yaml +0 -29
  63. package/tests/invalid-schema-1.yaml +0 -6
  64. package/tests/invalid-schema-2.yaml +0 -6
  65. package/tests/invalid-schema-3.yaml +0 -17
  66. package/tests/invalid-schema-4.yaml +0 -14
  67. package/tests/invalid-schema-5.yaml +0 -12
  68. package/tests/invalid-schema-6.yaml +0 -12
  69. package/tmp/conlink/.env +0 -1
  70. package/topo1.cljs +0 -35
  71. package/topo2.cljs +0 -36
  72. package/topo3.cljs +0 -44
  73. /package/{modes3/ab → examples/test4-multiple/modes/node1}/deps +0 -0
  74. /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}} ]
@@ -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}
@@ -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
- )