Merge ~cgrabowski/maas:rpc_client_server into maas:rack_region_exploration
- Git
- lp:~cgrabowski/maas
- rpc_client_server
- Merge into rack_region_exploration
Status: | Merged |
---|---|
Approved by: | Christian Grabowski |
Approved revision: | e4105e0c6bf7c8b11fa71629d67385c20b5a2cad |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~cgrabowski/maas:rpc_client_server |
Merge into: | maas:rack_region_exploration |
Diff against target: |
3110 lines (+2887/-3) 21 files modified
src/rackd_spike/Makefile (+21/-1) src/rackd_spike/cmd/rackd.go (+21/-0) src/rackd_spike/go.mod (+4/-0) src/rackd_spike/go.sum (+15/-2) src/rackd_spike/internal/machine_helpers/env.go (+67/-0) src/rackd_spike/internal/machine_helpers/info.go (+24/-0) src/rackd_spike/internal/machine_helpers/interfaces.go (+498/-0) src/rackd_spike/internal/machine_helpers/interfaces_capnp.go (+65/-0) src/rackd_spike/internal/machine_helpers/interfaces_test.go (+81/-0) src/rackd_spike/internal/machine_helpers/ps.go (+81/-0) src/rackd_spike/internal/machine_helpers/refresh.go (+29/-0) src/rackd_spike/internal/machine_helpers/snap.go (+30/-0) src/rackd_spike/internal/transport/rpc.go (+127/-0) src/rackd_spike/pkg/authenticate/authenticator.go (+93/-0) src/rackd_spike/pkg/region/handshake.go (+91/-0) src/rackd_spike/pkg/register/registerer.go (+125/-0) src/rackd_spike/pkg/rpc/handshake.capnp.go (+933/-0) src/rackd_spike/pkg/rpc/network.capnp.go (+489/-0) src/rpc/go.capnp (+27/-0) src/rpc/handshake.capnp (+36/-0) src/rpc/network.capnp (+30/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexsander de Souza | Approve | ||
MAAS Lander | Approve | ||
Review via email: mp+405247@code.launchpad.net |
Commit message
add rpc handshake
add machine helper functions
Description of the change
Alexsander de Souza (alexsander-souza) : | # |
Christian Grabowski (cgrabowski) : | # |
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: SUCCESS
COMMIT: 55db9bddb0a716d
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: FAILED
LOG: http://
COMMIT: 6b7bb3239a1fa16
Alexsander de Souza (alexsander-souza) : | # |
Christian Grabowski (cgrabowski) : | # |
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: SUCCESS
COMMIT: efa4abdd774328b
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: SUCCESS
COMMIT: bd874202dee2eee
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: FAILED
LOG: http://
COMMIT: a350ebb73dc98f9
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: SUCCESS
COMMIT: e4105e0c6bf7c8b
Alexsander de Souza (alexsander-souza) wrote : | # |
LGTM
MAAS Lander (maas-lander) wrote : | # |
LANDING
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: FAILED BUILD
LOG: http://
Preview Diff
1 | diff --git a/src/rackd_spike/Makefile b/src/rackd_spike/Makefile |
2 | index 81278c8..df50bdd 100644 |
3 | --- a/src/rackd_spike/Makefile |
4 | +++ b/src/rackd_spike/Makefile |
5 | @@ -1,3 +1,6 @@ |
6 | +PWD:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) |
7 | +ROOT_DIR:=$(shell dirname $(PWD)) |
8 | +RPC_DIR:=$(PWD)/pkg/rpc |
9 | VERSION:=develop-$(shell git rev-list -1 HEAD) |
10 | |
11 | PATH:=$(shell go env GOPATH)/bin:${PATH} |
12 | @@ -5,24 +8,41 @@ export PATH |
13 | |
14 | LDFLAGS="-X main.Version=$(VERSION) -s -w" |
15 | |
16 | +.PHONY: all |
17 | all: version test build |
18 | |
19 | version: |
20 | @go version |
21 | |
22 | +.PHONY: build |
23 | build: rackd |
24 | |
25 | +.PHONY: build-dir |
26 | build-dir: |
27 | mkdir -p ./build |
28 | |
29 | -rackd: build-dir |
30 | +.PHONY: rackd |
31 | +rackd: build-dir gen-capnp |
32 | go build -ldflags $(LDFLAGS) -o ./build/rackd ./cmd/rackd.go |
33 | |
34 | +.PHONY: test |
35 | test: |
36 | go test ./... |
37 | |
38 | +.PHONY: lint |
39 | lint: |
40 | go vet ./... |
41 | |
42 | +.PHONY: format |
43 | format: |
44 | gofmt -s -d ./cmd ./internal ./pkg |
45 | + |
46 | +.PHONY: capnp-dir |
47 | +capnp-dir: |
48 | + mkdir -p ./pkg/rpc |
49 | + |
50 | +%.capnp: capnp-dir |
51 | + capnp compile -ogo:$(PWD)/pkg/rpc $(ROOT_DIR)/rpc/$@ --src-prefix $(ROOT_DIR)/rpc |
52 | + |
53 | +.PHONY: gen-capnp |
54 | +gen-capnp: handshake.capnp network.capnp |
55 | diff --git a/src/rackd_spike/cmd/rackd.go b/src/rackd_spike/cmd/rackd.go |
56 | index fd7dac5..8ca5188 100644 |
57 | --- a/src/rackd_spike/cmd/rackd.go |
58 | +++ b/src/rackd_spike/cmd/rackd.go |
59 | @@ -14,6 +14,10 @@ import ( |
60 | "rackd/cmd/subcommands" |
61 | "rackd/internal/config" |
62 | "rackd/internal/metrics" |
63 | + "rackd/internal/transport" |
64 | + "rackd/pkg/authenticate" |
65 | + "rackd/pkg/region" |
66 | + "rackd/pkg/register" |
67 | ) |
68 | |
69 | type opts struct { |
70 | @@ -76,6 +80,23 @@ var ( |
71 | } |
72 | defer metricsSrvr.Close() |
73 | |
74 | + initRegion := os.Getenv("REGION_URL") |
75 | + rpcMgr := transport.NewRPCManager(initRegion, true) // TODO use the register command to provide info to connect instead and make TLS skip verify configurable |
76 | + err = rpcMgr.Init(ctx) |
77 | + if err != nil { |
78 | + return err |
79 | + } |
80 | + rpcMgr.AddClient(ctx, authenticate.NewCapnpAuthenticator()) |
81 | + rpcMgr.AddClient(ctx, register.NewCapnpRegisterer()) |
82 | + err = rpcMgr.Init(ctx) |
83 | + if err != nil { |
84 | + return err |
85 | + } |
86 | + err = region.Handshake(ctx, initRegion, Version, rpcMgr) |
87 | + if err != nil { |
88 | + return err |
89 | + } |
90 | + |
91 | log.Info().Msgf("rackd %v started successfully", Version) |
92 | |
93 | sigChan := make(chan os.Signal, 4) |
94 | diff --git a/src/rackd_spike/go.mod b/src/rackd_spike/go.mod |
95 | index 3339fb7..73edbc6 100644 |
96 | --- a/src/rackd_spike/go.mod |
97 | +++ b/src/rackd_spike/go.mod |
98 | @@ -3,11 +3,15 @@ module rackd |
99 | go 1.16 |
100 | |
101 | require ( |
102 | + capnproto.org/go/capnp/v3 v3.0.0-alpha.1 |
103 | github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d |
104 | github.com/coreos/go-systemd/v22 v22.3.2 |
105 | github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b |
106 | + github.com/lxc/lxd v0.0.0-20210705204343-3596a3bcba59 |
107 | + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect |
108 | github.com/prometheus/client_golang v0.9.3 |
109 | github.com/rs/zerolog v1.23.0 |
110 | github.com/spf13/cobra v1.1.3 |
111 | + gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect |
112 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b |
113 | ) |
114 | diff --git a/src/rackd_spike/go.sum b/src/rackd_spike/go.sum |
115 | index 4c08b8b..b61ac4f 100644 |
116 | --- a/src/rackd_spike/go.sum |
117 | +++ b/src/rackd_spike/go.sum |
118 | @@ -1,3 +1,5 @@ |
119 | +capnproto.org/go/capnp/v3 v3.0.0-alpha.1 h1:lA/zWC1XgaFez/UdqcWi5Bz1grsqPQDY5Ki4lgYrQ1o= |
120 | +capnproto.org/go/capnp/v3 v3.0.0-alpha.1/go.mod h1:izbWjXlvObqHwvhxwDBFLpY9lXSXIxDKRtnuktKHVsU= |
121 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |
122 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |
123 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= |
124 | @@ -110,11 +112,13 @@ github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b h1:iNjcivnc6lhbvJA3LD6 |
125 | github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= |
126 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= |
127 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= |
128 | -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= |
129 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= |
130 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
131 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= |
132 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
133 | +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= |
134 | +github.com/lxc/lxd v0.0.0-20210705204343-3596a3bcba59 h1:FvuAx1MSuzz2gC5fqGG1tL99SNm1JacG3kDWqL3vILo= |
135 | +github.com/lxc/lxd v0.0.0-20210705204343-3596a3bcba59/go.mod h1:2BaZflfwsv8a3uy3/Vw+de4Avn4DSrAiqaHJjCIXMV4= |
136 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= |
137 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= |
138 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= |
139 | @@ -132,9 +136,13 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh |
140 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
141 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
142 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= |
143 | +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= |
144 | +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= |
145 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= |
146 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= |
147 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= |
148 | +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= |
149 | +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= |
150 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
151 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
152 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
153 | @@ -181,7 +189,10 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ |
154 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= |
155 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |
156 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= |
157 | +github.com/tinylib/msgp v1.1.5 h1:2gXmtWueD2HefZHQe1QOy9HVzmFrLOVvsXwXBQ0ayy0= |
158 | +github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= |
159 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= |
160 | +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= |
161 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= |
162 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= |
163 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= |
164 | @@ -280,6 +291,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn |
165 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
166 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
167 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
168 | +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= |
169 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= |
170 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
171 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
172 | @@ -307,8 +319,9 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq |
173 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= |
174 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= |
175 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
176 | -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= |
177 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
178 | +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= |
179 | +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
180 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= |
181 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= |
182 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= |
183 | diff --git a/src/rackd_spike/internal/machine_helpers/env.go b/src/rackd_spike/internal/machine_helpers/env.go |
184 | new file mode 100644 |
185 | index 0000000..351d53c |
186 | --- /dev/null |
187 | +++ b/src/rackd_spike/internal/machine_helpers/env.go |
188 | @@ -0,0 +1,67 @@ |
189 | +package machinehelpers |
190 | + |
191 | +import ( |
192 | + "fmt" |
193 | + "io" |
194 | + "os" |
195 | + "path/filepath" |
196 | + "strings" |
197 | + "sync" |
198 | +) |
199 | + |
200 | +var ( |
201 | + maasId string |
202 | +) |
203 | + |
204 | +var ( |
205 | + maasIdLock = &sync.RWMutex{} |
206 | +) |
207 | + |
208 | +func GetMAASDataPath(path string) string { |
209 | + basePath, ok := os.LookupEnv(path) |
210 | + if !ok { |
211 | + basePath = "/var/lib/maas" |
212 | + } |
213 | + return filepath.Join(basePath, path) |
214 | +} |
215 | + |
216 | +func GetMAASID() (string, error) { |
217 | + maasIdLock.RLock() |
218 | + defer maasIdLock.RUnlock() |
219 | + |
220 | + if len(maasId) == 0 { |
221 | + path := GetMAASDataPath("maas_id") |
222 | + f, err := os.Open(path) |
223 | + if err != nil { |
224 | + if os.IsNotExist(err) { |
225 | + return "", nil |
226 | + } |
227 | + return "", err |
228 | + } |
229 | + contents, err := io.ReadAll(f) |
230 | + if err != nil { |
231 | + return "", err |
232 | + } |
233 | + maasIdLock.Lock() |
234 | + defer maasIdLock.Unlock() |
235 | + maasId = strings.TrimSpace(string(contents)) |
236 | + } |
237 | + return maasId, nil |
238 | +} |
239 | + |
240 | +func SetMAASId(id string) error { |
241 | + path := GetMAASDataPath("maas_id") |
242 | + maasIdLock.Lock() |
243 | + defer maasIdLock.Unlock() |
244 | + maasId = id |
245 | + f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0644) |
246 | + if err != nil { |
247 | + return err |
248 | + } |
249 | + defer f.Close() |
250 | + _, err = fmt.Fprint(f, id) |
251 | + if err != nil { |
252 | + return err |
253 | + } |
254 | + return nil |
255 | +} |
256 | diff --git a/src/rackd_spike/internal/machine_helpers/info.go b/src/rackd_spike/internal/machine_helpers/info.go |
257 | new file mode 100644 |
258 | index 0000000..1517fc6 |
259 | --- /dev/null |
260 | +++ b/src/rackd_spike/internal/machine_helpers/info.go |
261 | @@ -0,0 +1,24 @@ |
262 | +package machinehelpers |
263 | + |
264 | +import ( |
265 | + lxdresources "github.com/lxc/lxd/shared/api" |
266 | +) |
267 | + |
268 | +type EnvInfo struct { |
269 | + Kernel string `json:"kernel"` |
270 | + KernelArchitecture string `json:"kernel_architecture"` |
271 | + KernelVersion string `json:"kernel_version"` |
272 | + OSName string `json:"os_name"` |
273 | + OSVersion string `json:"os_version"` |
274 | + Server string `json:"server"` |
275 | + ServerName string `json:"server_name"` |
276 | + ServerVersion string `json:"server_version"` |
277 | +} |
278 | + |
279 | +type MachineInfo struct { |
280 | + APIExtensions []string `json:"api_extension"` |
281 | + APIVersion string `json:"api_version"` |
282 | + Environment EnvInfo `json:"environment"` |
283 | + Resources lxdresources.Resources `json:"resources"` |
284 | + Networks map[string]lxdresources.NetworkState `json:"networks"` |
285 | +} |
286 | diff --git a/src/rackd_spike/internal/machine_helpers/interfaces.go b/src/rackd_spike/internal/machine_helpers/interfaces.go |
287 | new file mode 100644 |
288 | index 0000000..cbf58e6 |
289 | --- /dev/null |
290 | +++ b/src/rackd_spike/internal/machine_helpers/interfaces.go |
291 | @@ -0,0 +1,498 @@ |
292 | +package machinehelpers |
293 | + |
294 | +import ( |
295 | + "bufio" |
296 | + "context" |
297 | + "encoding/json" |
298 | + "fmt" |
299 | + "io" |
300 | + "net" |
301 | + "os" |
302 | + "os/exec" |
303 | + "path/filepath" |
304 | + "regexp" |
305 | + "sort" |
306 | + "strconv" |
307 | + "strings" |
308 | + |
309 | + lxdresources "github.com/lxc/lxd/shared/api" |
310 | +) |
311 | + |
312 | +var ( |
313 | + excludedInterfaceTypes = map[string]struct{}{ |
314 | + "loopback": {}, |
315 | + "ipip": {}, |
316 | + "tunnel": {}, |
317 | + } |
318 | + |
319 | + leaseRx = regexp.MustCompile(`(?m)(^\s*lease\s+{([^}]+)})`) |
320 | +) |
321 | + |
322 | +func isExcludedType(ctx context.Context, t string) (bool, error) { |
323 | + if _, ok := excludedInterfaceTypes[t]; ok { |
324 | + return true, nil |
325 | + } |
326 | + runningContainer, err := RunningInContainer(ctx) |
327 | + if err != nil { |
328 | + return false, err |
329 | + } |
330 | + if runningContainer && t == "ethernet" { |
331 | + return true, nil |
332 | + } |
333 | + if strings.HasPrefix("unknown-", t) { |
334 | + return true, nil |
335 | + } |
336 | + return false, nil |
337 | +} |
338 | + |
339 | +func GetIPAddr(ctx context.Context) (map[string]lxdresources.NetworkState, error) { |
340 | + cmdPath, err := GetResourcesBinPath() |
341 | + if err != nil { |
342 | + return nil, err |
343 | + } |
344 | + var args []string |
345 | + if IsRunningInSnap() { |
346 | + args = append(args, cmdPath) |
347 | + cmdPath = "/usr/bin/sudo" |
348 | + } |
349 | + cmd := exec.CommandContext(ctx, cmdPath, args...) |
350 | + out, err := cmd.Output() |
351 | + if err != nil { |
352 | + return nil, err |
353 | + } |
354 | + var info MachineInfo |
355 | + err = json.Unmarshal(out, &info) |
356 | + if err != nil { |
357 | + return nil, err |
358 | + } |
359 | + return info.Networks, nil |
360 | +} |
361 | + |
362 | +func splitDhclientCmdlineFile(data []byte, atEOF bool) (advance int, token []byte, err error) { |
363 | + for i := 0; i < len(data); i++ { |
364 | + if data[i] == '\x00' { |
365 | + return i + 1, data[:i], nil |
366 | + } |
367 | + if !atEOF { |
368 | + return 0, nil, nil |
369 | + } |
370 | + } |
371 | + return 0, data, bufio.ErrFinalToken |
372 | +} |
373 | + |
374 | +func GetLatestFixedAddress(leasePath string) (string, error) { |
375 | + f, err := os.Open(leasePath) |
376 | + if err != nil { |
377 | + return "", err |
378 | + } |
379 | + defer f.Close() |
380 | + return getLatestFixedAddress(f) |
381 | +} |
382 | + |
383 | +func getLatestFixedAddress(leaseFile io.Reader) (string, error) { |
384 | + leaseBytes, err := io.ReadAll(leaseFile) |
385 | + if err != nil { |
386 | + return "", err |
387 | + } |
388 | + submatches := leaseRx.FindAllSubmatch(leaseBytes, -1) |
389 | + if len(submatches) > 0 { |
390 | + matches := submatches[len(submatches)-1] |
391 | + if len(matches) > 0 { |
392 | + lastLease := matches[len(matches)-1] |
393 | + for _, line := range strings.Split(string(lastLease), "\n") { |
394 | + line = strings.TrimSpace(line) |
395 | + if len(line) > 0 { |
396 | + lineList := strings.SplitN(line, " ", 2) |
397 | + if len(lineList) < 2 { |
398 | + continue |
399 | + } |
400 | + statement, value := lineList[0], lineList[1] |
401 | + if statement == "fixed-address" || statement == "fixed-address6" { |
402 | + return strings.TrimSpace(strings.SplitN(value, ";", 2)[0]), nil |
403 | + } |
404 | + } |
405 | + } |
406 | + } |
407 | + } |
408 | + return "", nil |
409 | +} |
410 | + |
411 | +func GetDhclientInfo(ctx context.Context, procPath string) (map[string]string, error) { |
412 | + if len(procPath) == 0 { |
413 | + procPath = "/proc" |
414 | + } |
415 | + pids, err := GetRunningPIDsWithCMD(ctx, "dhclient", "", false) |
416 | + if err != nil { |
417 | + return nil, err |
418 | + } |
419 | + info := make(map[string]string) |
420 | + for _, pid := range pids { |
421 | + cmdlinePath := filepath.Join(procPath, strconv.Itoa(pid), "cmdline") |
422 | + err = func() error { |
423 | + f, err := os.Open(cmdlinePath) |
424 | + if err != nil { |
425 | + return err |
426 | + } |
427 | + defer f.Close() |
428 | + scanner := bufio.NewScanner(f) |
429 | + scanner.Split(splitDhclientCmdlineFile) |
430 | + var ( |
431 | + cmd []string |
432 | + leasePath string |
433 | + ) |
434 | + lfIdx := -1 |
435 | + for scanner.Scan() { |
436 | + cmd = append(cmd, scanner.Text()) |
437 | + if cmd[len(cmd)-1] == "-lf" { |
438 | + lfIdx = len(cmd) - 1 |
439 | + } |
440 | + if lfIdx > -1 && len(cmd)-2 == lfIdx { |
441 | + leasePath = cmd[len(cmd)-1] |
442 | + } |
443 | + } |
444 | + ifaceName := cmd[len(cmd)-1] |
445 | + ipAddr, err := GetLatestFixedAddress(leasePath) |
446 | + if err != nil { |
447 | + return err |
448 | + } |
449 | + if len(ipAddr) > 0 && ipAddr != " " { |
450 | + info[ifaceName] = ipAddr |
451 | + } |
452 | + return nil |
453 | + }() |
454 | + if err != nil { |
455 | + return nil, err |
456 | + } |
457 | + } |
458 | + return info, nil |
459 | +} |
460 | + |
461 | +type IPLink struct { |
462 | + Netmask int |
463 | + Mode string |
464 | + Address string |
465 | + Gateway string |
466 | +} |
467 | + |
468 | +type Vlan struct { |
469 | + LowerDev string |
470 | + Vid uint64 |
471 | +} |
472 | + |
473 | +type Interface struct { |
474 | + Type string |
475 | + Mac string |
476 | + Links []IPLink |
477 | + Enabled bool |
478 | + Vlan *Vlan |
479 | + Source string |
480 | + Parents []string |
481 | + Monitored bool |
482 | +} |
483 | + |
484 | +type sortableSubnets []*net.IPNet |
485 | + |
486 | +func (s sortableSubnets) Len() int { |
487 | + return len(s) |
488 | +} |
489 | + |
490 | +func (s sortableSubnets) Less(i, j int) bool { |
491 | + iPrefixlen, _ := s[i].Mask.Size() |
492 | + jPrefixlen, _ := s[j].Mask.Size() |
493 | + return iPrefixlen < jPrefixlen |
494 | +} |
495 | + |
496 | +func (s sortableSubnets) Swap(i, j int) { |
497 | + tmp := s[j] |
498 | + s[j] = s[i] |
499 | + s[i] = tmp |
500 | +} |
501 | + |
502 | +func fixLinkAddresses(links []IPLink) ([]IPLink, error) { |
503 | + var ( |
504 | + subnetsV4 []*net.IPNet |
505 | + linksV4 []struct { |
506 | + Link IPLink |
507 | + Idx int |
508 | + } |
509 | + subnetsV6 []*net.IPNet |
510 | + linksV6 []struct { |
511 | + Link IPLink |
512 | + Idx int |
513 | + } |
514 | + ) |
515 | + for i, link := range links { |
516 | + var ( |
517 | + ipAddr net.IP |
518 | + ipNet *net.IPNet |
519 | + err error |
520 | + ) |
521 | + if link.Netmask != 0 { |
522 | + ipAddr, ipNet, err = net.ParseCIDR(fmt.Sprintf("%s/%d", link.Address, link.Netmask)) |
523 | + if err != nil { |
524 | + return nil, err |
525 | + } |
526 | + } else { |
527 | + ipAddr, ipNet, err = net.ParseCIDR(link.Address) |
528 | + if err != nil { |
529 | + return nil, err |
530 | + } |
531 | + } |
532 | + prefixLen, _ := ipNet.Mask.Size() |
533 | + if ipAddr.To4() != nil { |
534 | + if prefixLen == 32 { |
535 | + linksV4 = append(linksV4, struct { |
536 | + Link IPLink |
537 | + Idx int |
538 | + }{ |
539 | + Link: link, |
540 | + Idx: i, |
541 | + }) |
542 | + } else { |
543 | + subnetsV4 = append(subnetsV4, ipNet) |
544 | + } |
545 | + } else { |
546 | + if prefixLen == 128 { |
547 | + linksV6 = append(linksV6, struct { |
548 | + Link IPLink |
549 | + Idx int |
550 | + }{ |
551 | + Link: link, |
552 | + Idx: i, |
553 | + }) |
554 | + } else { |
555 | + subnetsV6 = append(subnetsV6, ipNet) |
556 | + } |
557 | + } |
558 | + } |
559 | + newLinks := [][]struct { |
560 | + Link IPLink |
561 | + Idx int |
562 | + }{linksV4, linksV6} |
563 | + newSubnets := [][]*net.IPNet{subnetsV4, subnetsV6} |
564 | + for i, currLinks := range newLinks { |
565 | + currSubnets := sortableSubnets(newSubnets[i]) |
566 | + var ok bool |
567 | + currSubnets, ok = sort.Reverse(currSubnets).(sortableSubnets) |
568 | + if !ok { |
569 | + return nil, fmt.Errorf("sort.Reverse() returned a type other than sortableSubnets, %T", currSubnets) |
570 | + } |
571 | + for _, link := range currLinks { |
572 | + var ( |
573 | + ip net.IP |
574 | + err error |
575 | + ) |
576 | + if link.Link.Netmask != 0 { |
577 | + ip, _, err = net.ParseCIDR( |
578 | + fmt.Sprintf("%s:%d", link.Link.Address, link.Link.Netmask), |
579 | + ) |
580 | + } else { |
581 | + ip, _, err = net.ParseCIDR(link.Link.Address) |
582 | + } |
583 | + if err != nil { |
584 | + return nil, err |
585 | + } |
586 | + for _, subnet := range currSubnets { |
587 | + if subnet.Contains(ip) { |
588 | + prefixlen, _ := subnet.Mask.Size() |
589 | + if link.Link.Netmask != 0 { |
590 | + link.Link.Netmask = prefixlen |
591 | + } else { |
592 | + link.Link.Address = fmt.Sprintf("%s/%d", ip, prefixlen) |
593 | + } |
594 | + } |
595 | + } |
596 | + links[link.Idx] = link.Link |
597 | + } |
598 | + } |
599 | + return links, nil |
600 | +} |
601 | + |
602 | +type IPRoute struct { |
603 | + Gateway string `json:"gateway"` |
604 | + GatewayIP net.IP `json:"-"` |
605 | + Dev string `json:"dev"` |
606 | + Protocol string `json:"protocol"` |
607 | + Metric int `json:"metric"` |
608 | + Flags []int `json:"flags"` |
609 | +} |
610 | + |
611 | +func GetIPRoute(ctx context.Context) (map[string]IPRoute, error) { |
612 | + cmd := exec.CommandContext(ctx, "ip", "-json", "route", "list", "scope", "global") |
613 | + routes := make(map[string]IPRoute) |
614 | + var routeList []struct { |
615 | + Name string `json:"dst"` |
616 | + IPRoute |
617 | + } |
618 | + out, err := cmd.Output() |
619 | + if err != nil { |
620 | + return nil, err |
621 | + } |
622 | + err = json.Unmarshal(out, &routeList) |
623 | + if err != nil { |
624 | + return nil, err |
625 | + } |
626 | + for _, route := range routeList { |
627 | + route.IPRoute.GatewayIP = net.ParseIP(route.Gateway) |
628 | + routes[route.Name] = route.IPRoute |
629 | + } |
630 | + return routes, nil |
631 | +} |
632 | + |
633 | +func fixGateways(links []IPLink, ipRouteInfo map[string]IPRoute) ([]IPLink, error) { |
634 | + for i, link := range links { |
635 | + _, subnet, err := net.ParseCIDR(link.Address) |
636 | + if err != nil { |
637 | + return nil, err |
638 | + } |
639 | + if routeInfo, ok := ipRouteInfo[subnet.String()]; ok { |
640 | + link.Gateway = routeInfo.Gateway |
641 | + } else if defaultInfo, ok := ipRouteInfo["default"]; ok && subnet.Contains(defaultInfo.GatewayIP) { |
642 | + link.Gateway = defaultInfo.Gateway |
643 | + } |
644 | + links[i] = link |
645 | + } |
646 | + return links, nil |
647 | +} |
648 | + |
649 | +func GetInterfaceChildren(interfaces map[string]Interface) map[string][]string { |
650 | + children := make(map[string][]string) |
651 | + for name, iface := range interfaces { |
652 | + for _, parent := range iface.Parents { |
653 | + if node, ok := children[parent]; ok { |
654 | + node = append(node, name) |
655 | + } else { |
656 | + children[parent] = []string{name} |
657 | + } |
658 | + } |
659 | + } |
660 | + return children |
661 | +} |
662 | + |
663 | +type InterfaceChild struct { |
664 | + Name string |
665 | + Iface Interface |
666 | +} |
667 | + |
668 | +func InterfaceChildren(ifname string, interfaces map[string]Interface, children map[string][]string) (res []InterfaceChild) { |
669 | + if node, ok := children[ifname]; ok { |
670 | + for _, child := range node { |
671 | + res = append(res, InterfaceChild{Name: child, Iface: interfaces[child]}) |
672 | + } |
673 | + } |
674 | + return res |
675 | +} |
676 | + |
677 | +func GetDefaultMonitoredInterfaces(interfaces map[string]Interface) (res map[string]struct{}) { |
678 | + res = make(map[string]struct{}) |
679 | + childrenMap := GetInterfaceChildren(interfaces) |
680 | + for name, iface := range interfaces { |
681 | + if !iface.Enabled { |
682 | + continue |
683 | + } |
684 | + switch iface.Type { |
685 | + case "physical": |
686 | + shouldMonitor := true |
687 | + for _, child := range InterfaceChildren(name, interfaces, childrenMap) { |
688 | + if child.Iface.Type == "bond" { |
689 | + shouldMonitor = false |
690 | + break |
691 | + } |
692 | + } |
693 | + if shouldMonitor { |
694 | + res[name] = struct{}{} |
695 | + } |
696 | + case "bond": |
697 | + res[name] = struct{}{} |
698 | + case "bridge": |
699 | + if len(iface.Parents) == 0 { |
700 | + res[name] = struct{}{} |
701 | + } |
702 | + } |
703 | + } |
704 | + return res |
705 | +} |
706 | + |
707 | +func GetAllInterfacesDefinition(ctx context.Context, annotateWithMonitored bool) (map[string]Interface, error) { |
708 | + dhclientInfo, err := GetDhclientInfo(ctx, "") |
709 | + if err != nil { |
710 | + return nil, err |
711 | + } |
712 | + netIfaces, err := GetIPAddr(ctx) |
713 | + if err != nil { |
714 | + return nil, err |
715 | + } |
716 | + iprouteInfo, err := GetIPRoute(ctx) |
717 | + if err != nil { |
718 | + return nil, err |
719 | + } |
720 | + res := make(map[string]Interface) |
721 | + for name, iface := range netIfaces { |
722 | + excludeType, err := isExcludedType(ctx, iface.Type) |
723 | + if err != nil { |
724 | + return nil, err |
725 | + } |
726 | + if excludeType { |
727 | + continue |
728 | + } |
729 | + i := Interface{ |
730 | + Mac: iface.Hwaddr, |
731 | + Enabled: iface.State == "up", |
732 | + } |
733 | + if !(iface.Type == "vlan" || iface.Type == "bridge" || iface.Type == "bond") { |
734 | + i.Type = "physical" |
735 | + } else { |
736 | + i.Type = iface.Type |
737 | + if iface.Bond != nil && len(iface.Bond.LowerDevices) > 0 { |
738 | + i.Parents = append(i.Parents, iface.Bond.LowerDevices...) |
739 | + } |
740 | + if iface.Bridge != nil && len(iface.Bridge.UpperDevices) > 0 { |
741 | + i.Parents = append(i.Parents, iface.Bridge.UpperDevices...) |
742 | + } |
743 | + } |
744 | + if iface.VLAN != nil { |
745 | + i.Vlan = &Vlan{ |
746 | + LowerDev: iface.VLAN.LowerDevice, |
747 | + Vid: iface.VLAN.VID, |
748 | + } |
749 | + i.Parents = append(i.Parents, iface.VLAN.LowerDevice) |
750 | + } |
751 | + dhcpAddr := dhclientInfo[name] |
752 | + for _, addr := range iface.Addresses { |
753 | + mode := "static" |
754 | + if net.ParseIP(addr.Address).String() == dhcpAddr { |
755 | + mode = "dhcp" |
756 | + } |
757 | + |
758 | + link := IPLink{Mode: mode, Address: addr.Address} |
759 | + if len(addr.Netmask) > 0 { |
760 | + link.Netmask, err = strconv.Atoi(addr.Netmask) |
761 | + if err != nil { |
762 | + return nil, err |
763 | + } |
764 | + } |
765 | + i.Links = append(i.Links, link) |
766 | + } |
767 | + i.Links, err = fixLinkAddresses(i.Links) |
768 | + if err != nil { |
769 | + return nil, err |
770 | + } |
771 | + i.Links, err = fixGateways(i.Links, iprouteInfo) |
772 | + if err != nil { |
773 | + return nil, err |
774 | + } |
775 | + res[name] = i |
776 | + } |
777 | + if annotateWithMonitored { |
778 | + monitoredIfaces := GetDefaultMonitoredInterfaces(res) |
779 | + for name, iface := range res { |
780 | + if _, ok := monitoredIfaces[name]; ok { |
781 | + iface.Monitored = true |
782 | + } else { |
783 | + iface.Monitored = false |
784 | + } |
785 | + res[name] = iface |
786 | + } |
787 | + } |
788 | + return res, nil |
789 | +} |
790 | diff --git a/src/rackd_spike/internal/machine_helpers/interfaces_capnp.go b/src/rackd_spike/internal/machine_helpers/interfaces_capnp.go |
791 | new file mode 100644 |
792 | index 0000000..777f0b4 |
793 | --- /dev/null |
794 | +++ b/src/rackd_spike/internal/machine_helpers/interfaces_capnp.go |
795 | @@ -0,0 +1,65 @@ |
796 | +package machinehelpers |
797 | + |
798 | +import ( |
799 | + "rackd/pkg/rpc" |
800 | +) |
801 | + |
802 | +type CapnpInterfaces map[string]Interface |
803 | + |
804 | +func (c CapnpInterfaces) SetProto(ifacePayload rpc.Interfaces) error { |
805 | + ifaces, err := ifacePayload.NewIfaces(int32(len(c))) |
806 | + if err != nil { |
807 | + return err |
808 | + } |
809 | + var idx int |
810 | + for name, iface := range c { |
811 | + protoIface := ifaces.At(idx) |
812 | + err = protoIface.SetName(name) |
813 | + if err != nil { |
814 | + return err |
815 | + } |
816 | + details, err := protoIface.NewIface() |
817 | + if err != nil { |
818 | + return err |
819 | + } |
820 | + details.SetMacAddress(iface.Mac) |
821 | + details.SetType(iface.Type) |
822 | + protoLinks, err := details.NewLinks(int32(len(iface.Links))) |
823 | + if err != nil { |
824 | + return err |
825 | + } |
826 | + for i, link := range iface.Links { |
827 | + protoLink := protoLinks.At(i) |
828 | + err = protoLink.SetMode(link.Mode) |
829 | + if err != nil { |
830 | + return err |
831 | + } |
832 | + err = protoLink.SetAddress(link.Address) |
833 | + if err != nil { |
834 | + return err |
835 | + } |
836 | + err = protoLink.SetGateway(link.Gateway) |
837 | + if err != nil { |
838 | + return err |
839 | + } |
840 | + protoLink.SetNetmask(int32(link.Netmask)) |
841 | + } |
842 | + if iface.Vlan != nil { |
843 | + details.SetVid(iface.Vlan.Vid) |
844 | + } |
845 | + if len(iface.Parents) > 0 { |
846 | + protoParents, err := details.NewParents(int32(len(iface.Parents))) |
847 | + if err != nil { |
848 | + return err |
849 | + } |
850 | + for i, parent := range iface.Parents { |
851 | + err = protoParents.Set(i, parent) |
852 | + if err != nil { |
853 | + return err |
854 | + } |
855 | + } |
856 | + } |
857 | + idx++ |
858 | + } |
859 | + return nil |
860 | +} |
861 | diff --git a/src/rackd_spike/internal/machine_helpers/interfaces_test.go b/src/rackd_spike/internal/machine_helpers/interfaces_test.go |
862 | new file mode 100644 |
863 | index 0000000..a7d2b3c |
864 | --- /dev/null |
865 | +++ b/src/rackd_spike/internal/machine_helpers/interfaces_test.go |
866 | @@ -0,0 +1,81 @@ |
867 | +package machinehelpers |
868 | + |
869 | +import ( |
870 | + "errors" |
871 | + "io" |
872 | + "testing" |
873 | +) |
874 | + |
875 | +type mockLeaseFile struct { |
876 | + Data []byte |
877 | +} |
878 | + |
879 | +func (m mockLeaseFile) Read(b []byte) (n int, err error) { |
880 | + n = copy(b, m.Data) |
881 | + if n > 0 { |
882 | + m.Data = m.Data[n:] |
883 | + } |
884 | + if len(m.Data) == 0 { |
885 | + return n, io.EOF |
886 | + } |
887 | + return n, nil |
888 | +} |
889 | + |
890 | +func TestGetLatestFixedAddress(t *testing.T) { |
891 | + table := []struct { |
892 | + Name string |
893 | + In mockLeaseFile |
894 | + Out string |
895 | + Err error |
896 | + }{ |
897 | + { |
898 | + Name: "basic-v4-lease-file", |
899 | + In: mockLeaseFile{ |
900 | + Data: []byte(` |
901 | + lease { |
902 | + fixed-address 10.0.0.2; |
903 | + } |
904 | + `), |
905 | + }, |
906 | + Out: "10.0.0.2", |
907 | + }, { |
908 | + Name: "basic-v6-lease-file", |
909 | + In: mockLeaseFile{ |
910 | + Data: []byte(` |
911 | + lease { |
912 | + fixed-address6 fe80::ca56:eed8:1344:1aa2; |
913 | + } |
914 | + `), |
915 | + }, |
916 | + Out: "fe80::ca56:eed8:1344:1aa2", |
917 | + }, { |
918 | + Name: "no-data-lease-file", |
919 | + In: mockLeaseFile{}, |
920 | + }, { |
921 | + Name: "multi-lease-lease-file", |
922 | + In: mockLeaseFile{ |
923 | + Data: []byte(` |
924 | + lease { |
925 | + fixed-address 10.0.0.9; |
926 | + } |
927 | + |
928 | + lease { |
929 | + fixed-address 10.0.0.2; |
930 | + } |
931 | + `), |
932 | + }, |
933 | + Out: "10.0.0.2", |
934 | + }, |
935 | + } |
936 | + for _, tcase := range table { |
937 | + t.Run(tcase.Name, func(tt *testing.T) { |
938 | + out, err := getLatestFixedAddress(tcase.In) |
939 | + if !errors.Is(err, tcase.Err) { |
940 | + tt.Fatalf("expected %v to equal %v", err, tcase.Err) |
941 | + } |
942 | + if out != tcase.Out { |
943 | + tt.Fatalf("expected '%s' to equal '%s'", out, tcase.Out) |
944 | + } |
945 | + }) |
946 | + } |
947 | +} |
948 | diff --git a/src/rackd_spike/internal/machine_helpers/ps.go b/src/rackd_spike/internal/machine_helpers/ps.go |
949 | new file mode 100644 |
950 | index 0000000..016564b |
951 | --- /dev/null |
952 | +++ b/src/rackd_spike/internal/machine_helpers/ps.go |
953 | @@ -0,0 +1,81 @@ |
954 | +package machinehelpers |
955 | + |
956 | +import ( |
957 | + "bufio" |
958 | + "context" |
959 | + "os" |
960 | + "os/exec" |
961 | + "path/filepath" |
962 | + "strconv" |
963 | + "strings" |
964 | +) |
965 | + |
966 | +const ( |
967 | + vertCheckExec = "systemd-detect-virt" |
968 | +) |
969 | + |
970 | +var ( |
971 | + vertCheckArgs = []string{"-c"} |
972 | +) |
973 | + |
974 | +func RunningInContainer(ctx context.Context) (bool, error) { |
975 | + cmd := exec.CommandContext(ctx, vertCheckExec, vertCheckArgs...) |
976 | + if err := cmd.Run(); err != nil { |
977 | + if cmd.ProcessState.ExitCode() == 1 { |
978 | + return false, nil |
979 | + } |
980 | + return false, err |
981 | + } |
982 | + return true, nil |
983 | +} |
984 | + |
985 | +func PIDInContainer(pid int, procPath string) (bool, error) { |
986 | + if len(procPath) == 0 { |
987 | + procPath = "/proc" |
988 | + } |
989 | + cgroupPath := filepath.Join(procPath, strconv.Itoa(pid), "cgroup") |
990 | + f, err := os.Open(cgroupPath) |
991 | + if err != nil { |
992 | + return false, err |
993 | + } |
994 | + defer f.Close() |
995 | + scanner := bufio.NewScanner(f) |
996 | + for scanner.Scan() { |
997 | + line := scanner.Text() |
998 | + cgroup := strings.SplitN(line, ":", 2) |
999 | + // cgroup[2] will be the cgroup heirarchy |
1000 | + if strings.HasPrefix(cgroup[2], "/lxc") || strings.Contains(cgroup[2], "docker") { |
1001 | + return true, nil |
1002 | + } |
1003 | + } |
1004 | + return false, nil |
1005 | +} |
1006 | + |
1007 | +func GetRunningPIDsWithCMD(ctx context.Context, command, procPath string, excludeContainerProcesses bool) ([]int, error) { |
1008 | + if len(procPath) == 0 { |
1009 | + procPath = "/proc" |
1010 | + } |
1011 | + dirs, err := os.ReadDir(procPath) |
1012 | + if err != nil { |
1013 | + return nil, err |
1014 | + } |
1015 | + var runningPIDs []int |
1016 | + runningInContainer, err := RunningInContainer(ctx) |
1017 | + if err != nil { |
1018 | + return nil, err |
1019 | + } |
1020 | + for _, dir := range dirs { |
1021 | + pid, parseErr := strconv.Atoi(dir.Name()) |
1022 | + if parseErr == nil { |
1023 | + pidInContainer, err := PIDInContainer(pid, procPath) |
1024 | + if err != nil { |
1025 | + return nil, err |
1026 | + } |
1027 | + if excludeContainerProcesses && !runningInContainer && pidInContainer { |
1028 | + continue |
1029 | + } |
1030 | + runningPIDs = append(runningPIDs, pid) |
1031 | + } |
1032 | + } |
1033 | + return runningPIDs, nil |
1034 | +} |
1035 | diff --git a/src/rackd_spike/internal/machine_helpers/refresh.go b/src/rackd_spike/internal/machine_helpers/refresh.go |
1036 | new file mode 100644 |
1037 | index 0000000..685460b |
1038 | --- /dev/null |
1039 | +++ b/src/rackd_spike/internal/machine_helpers/refresh.go |
1040 | @@ -0,0 +1,29 @@ |
1041 | +package machinehelpers |
1042 | + |
1043 | +import ( |
1044 | + "path/filepath" |
1045 | + "runtime" |
1046 | +) |
1047 | + |
1048 | +func isDevEnv() bool { |
1049 | + // TODO grab this value from config |
1050 | + return true |
1051 | +} |
1052 | + |
1053 | +func GetResourcesBinPath() (string, error) { |
1054 | + var path string |
1055 | + if isDevEnv() { |
1056 | + path = "src/machine-resources/bin" |
1057 | + } else { |
1058 | + prefix, ok := SnapPaths{}.FromEnv()["snap"] |
1059 | + path = "/usr/share/maas/machine-resources" |
1060 | + if ok { |
1061 | + path = prefix + path |
1062 | + } |
1063 | + } |
1064 | + absPath, err := filepath.Abs(path) |
1065 | + if err != nil { |
1066 | + return "", err |
1067 | + } |
1068 | + return filepath.Join(absPath, runtime.GOARCH), nil |
1069 | +} |
1070 | diff --git a/src/rackd_spike/internal/machine_helpers/snap.go b/src/rackd_spike/internal/machine_helpers/snap.go |
1071 | new file mode 100644 |
1072 | index 0000000..0956377 |
1073 | --- /dev/null |
1074 | +++ b/src/rackd_spike/internal/machine_helpers/snap.go |
1075 | @@ -0,0 +1,30 @@ |
1076 | +package machinehelpers |
1077 | + |
1078 | +import ( |
1079 | + "os" |
1080 | +) |
1081 | + |
1082 | +var ( |
1083 | + pathVars = map[string]string{ |
1084 | + "snap": "SNAP", |
1085 | + "common": "SNAP_COMMON", |
1086 | + "data": "SNAP_DATA", |
1087 | + } |
1088 | +) |
1089 | + |
1090 | +func IsRunningInSnap() bool { |
1091 | + _, ok := os.LookupEnv("SNAP") |
1092 | + return ok |
1093 | +} |
1094 | + |
1095 | +type SnapPaths map[string]string |
1096 | + |
1097 | +func (s SnapPaths) FromEnv() SnapPaths { |
1098 | + for k, v := range pathVars { |
1099 | + path, ok := os.LookupEnv(v) |
1100 | + if ok { |
1101 | + s[k] = path |
1102 | + } |
1103 | + } |
1104 | + return s |
1105 | +} |
1106 | diff --git a/src/rackd_spike/internal/transport/rpc.go b/src/rackd_spike/internal/transport/rpc.go |
1107 | new file mode 100644 |
1108 | index 0000000..c0764d0 |
1109 | --- /dev/null |
1110 | +++ b/src/rackd_spike/internal/transport/rpc.go |
1111 | @@ -0,0 +1,127 @@ |
1112 | +package transport |
1113 | + |
1114 | +import ( |
1115 | + "context" |
1116 | + "crypto/tls" |
1117 | + "errors" |
1118 | + "net" |
1119 | + "net/url" |
1120 | + |
1121 | + capnprpc "capnproto.org/go/capnp/v3/rpc" |
1122 | + "github.com/rs/zerolog" |
1123 | + |
1124 | + "rackd/internal/metrics" |
1125 | +) |
1126 | + |
1127 | +var ( |
1128 | + ErrRPCClientNotFound = errors.New("error client not found") |
1129 | +) |
1130 | + |
1131 | +type RPCHandler interface { |
1132 | + Name() string |
1133 | + RegisterMetrics(*metrics.Registry) error |
1134 | + SetupServer(context.Context, *ConnWrapper) |
1135 | +} |
1136 | + |
1137 | +type RPCClient interface { |
1138 | + Name() string |
1139 | + RegisterMetrics(*metrics.Registry) error |
1140 | + SetupClient(context.Context, *ConnWrapper) |
1141 | +} |
1142 | + |
1143 | +type CapnpRPCClient interface { |
1144 | + RPCClient |
1145 | + Release() |
1146 | +} |
1147 | + |
1148 | +type ConnWrapper struct { |
1149 | + Conn net.Conn |
1150 | + capnpConn *capnprpc.Conn |
1151 | +} |
1152 | + |
1153 | +func NewConnWrapper(conn net.Conn) *ConnWrapper { |
1154 | + return &ConnWrapper{ |
1155 | + Conn: conn, |
1156 | + capnpConn: capnprpc.NewConn(capnprpc.NewStreamTransport(conn), nil), |
1157 | + } |
1158 | +} |
1159 | + |
1160 | +func (c *ConnWrapper) Capnp() *capnprpc.Conn { |
1161 | + return c.capnpConn |
1162 | +} |
1163 | + |
1164 | +type RPCManager struct { |
1165 | + conns map[string]*ConnWrapper |
1166 | + handlers map[string]RPCHandler |
1167 | + clients map[string]RPCClient |
1168 | + initURL string |
1169 | + skipHostVerify bool |
1170 | +} |
1171 | + |
1172 | +func NewRPCManager(rpcServerURL string, skipHostVerify bool) *RPCManager { |
1173 | + return &RPCManager{ |
1174 | + conns: make(map[string]*ConnWrapper), |
1175 | + handlers: make(map[string]RPCHandler), |
1176 | + clients: make(map[string]RPCClient), |
1177 | + initURL: rpcServerURL, |
1178 | + skipHostVerify: skipHostVerify, |
1179 | + } |
1180 | +} |
1181 | + |
1182 | +// Init initiates the initial region connection |
1183 | +func (r *RPCManager) Init(ctx context.Context) error { |
1184 | + parsedURL, err := url.Parse(r.initURL) |
1185 | + if err != nil { |
1186 | + return err |
1187 | + } |
1188 | + var conn net.Conn |
1189 | + if parsedURL.Scheme == "https" { |
1190 | + conn, err = tls.Dial( |
1191 | + "tcp", |
1192 | + net.JoinHostPort(parsedURL.Hostname(), parsedURL.Port()), |
1193 | + &tls.Config{InsecureSkipVerify: r.skipHostVerify}, |
1194 | + ) |
1195 | + } else { |
1196 | + conn, err = net.Dial("tcp", net.JoinHostPort(parsedURL.Hostname(), parsedURL.Port())) |
1197 | + } |
1198 | + if err != nil { |
1199 | + return err |
1200 | + } |
1201 | + r.AddConn(ctx, conn) |
1202 | + log := zerolog.Ctx(ctx) |
1203 | + log.Debug().Msg("connected to region server") |
1204 | + return nil |
1205 | +} |
1206 | + |
1207 | +func (r *RPCManager) AddHandler(ctx context.Context, handler RPCHandler) { |
1208 | + r.handlers[handler.Name()] = handler |
1209 | + for _, conn := range r.conns { |
1210 | + handler.SetupServer(ctx, conn) |
1211 | + } |
1212 | +} |
1213 | + |
1214 | +func (r *RPCManager) AddClient(ctx context.Context, client RPCClient) { |
1215 | + r.clients[client.Name()] = client |
1216 | + for _, conn := range r.conns { |
1217 | + client.SetupClient(ctx, conn) |
1218 | + } |
1219 | +} |
1220 | + |
1221 | +func (r *RPCManager) AddConn(ctx context.Context, conn net.Conn) { |
1222 | + newConn := NewConnWrapper(conn) |
1223 | + r.conns[conn.RemoteAddr().String()] = newConn |
1224 | + for _, handler := range r.handlers { |
1225 | + handler.SetupServer(ctx, newConn) |
1226 | + } |
1227 | + for _, client := range r.clients { |
1228 | + client.SetupClient(ctx, newConn) |
1229 | + } |
1230 | +} |
1231 | + |
1232 | +func (r *RPCManager) GetClient(clientName string) (RPCClient, error) { |
1233 | + c, ok := r.clients[clientName] |
1234 | + if !ok { |
1235 | + return nil, ErrRPCClientNotFound |
1236 | + } |
1237 | + return c, nil |
1238 | +} |
1239 | diff --git a/src/rackd_spike/pkg/authenticate/authenticator.go b/src/rackd_spike/pkg/authenticate/authenticator.go |
1240 | new file mode 100644 |
1241 | index 0000000..6a60a86 |
1242 | --- /dev/null |
1243 | +++ b/src/rackd_spike/pkg/authenticate/authenticator.go |
1244 | @@ -0,0 +1,93 @@ |
1245 | +package authenticate |
1246 | + |
1247 | +import ( |
1248 | + "bytes" |
1249 | + "context" |
1250 | + "fmt" |
1251 | + |
1252 | + "rackd/internal/metrics" |
1253 | + "rackd/internal/transport" |
1254 | + "rackd/pkg/rpc" |
1255 | +) |
1256 | + |
1257 | +type AuthCreds struct { |
1258 | + Salt []byte |
1259 | + Digest []byte |
1260 | +} |
1261 | + |
1262 | +func (c *AuthCreds) localDigest(secret, message []byte) []byte { |
1263 | + // TODO |
1264 | + return nil |
1265 | +} |
1266 | + |
1267 | +func (c *AuthCreds) Verify(secret, message []byte) bool { |
1268 | + return bytes.Compare(c.Digest, c.localDigest(secret, message)) == 0 |
1269 | +} |
1270 | + |
1271 | +type Authenticator interface { |
1272 | + transport.RPCClient |
1273 | + Authenticate(context.Context, string, []byte, []byte) (*AuthCreds, error) |
1274 | +} |
1275 | + |
1276 | +type CapnpAuthenticator struct { |
1277 | + clients map[string]*rpc.Authenticator |
1278 | +} |
1279 | + |
1280 | +func NewCapnpAuthenticator() Authenticator { |
1281 | + // Perhaps we should initialize this with the shared secret already loaded either |
1282 | + // from the config manager or load from the FS on instantiation? |
1283 | + return &CapnpAuthenticator{ |
1284 | + clients: make(map[string]*rpc.Authenticator), |
1285 | + } |
1286 | +} |
1287 | + |
1288 | +func (c *CapnpAuthenticator) Name() string { |
1289 | + return "authenticator" |
1290 | +} |
1291 | + |
1292 | +func (c *CapnpAuthenticator) RegisterMetrics(registry *metrics.Registry) error { |
1293 | + // TODO |
1294 | + return nil |
1295 | +} |
1296 | + |
1297 | +func (c *CapnpAuthenticator) SetupClient(ctx context.Context, conn *transport.ConnWrapper) { |
1298 | + c.clients[conn.Conn.RemoteAddr().String()] = &rpc.Authenticator{Client: conn.Capnp().Bootstrap(ctx)} |
1299 | +} |
1300 | + |
1301 | +func (c *CapnpAuthenticator) Authenticate(ctx context.Context, region string, secret, message []byte) (*AuthCreds, error) { |
1302 | + regionClient, ok := c.clients[region] |
1303 | + if !ok { |
1304 | + return nil, fmt.Errorf("%w: %s", transport.ErrRPCClientNotFound, region) |
1305 | + } |
1306 | + result, release := regionClient.Authenticate(ctx, func(params rpc.Authenticator_authenticate_Params) error { |
1307 | + return params.SetMsg(message) |
1308 | + }) |
1309 | + defer release() |
1310 | + resp, err := result.Struct() |
1311 | + if err != nil { |
1312 | + return nil, err |
1313 | + } |
1314 | + creds, err := resp.Resp() |
1315 | + if err != nil { |
1316 | + return nil, err |
1317 | + } |
1318 | + salt, err := creds.Salt() |
1319 | + if err != nil { |
1320 | + return nil, err |
1321 | + } |
1322 | + digest, err := creds.Digest() |
1323 | + if err != nil { |
1324 | + return nil, err |
1325 | + } |
1326 | + return &AuthCreds{ |
1327 | + Salt: salt, |
1328 | + Digest: digest, |
1329 | + }, nil |
1330 | +} |
1331 | + |
1332 | +func (c *CapnpAuthenticator) Release() { |
1333 | + for k, client := range c.clients { |
1334 | + client.Release() |
1335 | + delete(c.clients, k) |
1336 | + } |
1337 | +} |
1338 | diff --git a/src/rackd_spike/pkg/region/handshake.go b/src/rackd_spike/pkg/region/handshake.go |
1339 | new file mode 100644 |
1340 | index 0000000..4d1a090 |
1341 | --- /dev/null |
1342 | +++ b/src/rackd_spike/pkg/region/handshake.go |
1343 | @@ -0,0 +1,91 @@ |
1344 | +package region |
1345 | + |
1346 | +import ( |
1347 | + "context" |
1348 | + "crypto/rand" |
1349 | + "errors" |
1350 | + "fmt" |
1351 | + "os" |
1352 | + |
1353 | + machinehelpers "rackd/internal/machine_helpers" |
1354 | + "rackd/internal/transport" |
1355 | + auth "rackd/pkg/authenticate" |
1356 | + reg "rackd/pkg/register" |
1357 | +) |
1358 | + |
1359 | +var ( |
1360 | + ErrNoAuthenticatorProvided = errors.New("error no authenticator was provided") |
1361 | + ErrNoRegistererProvided = errors.New("error no registerer was provided") |
1362 | + ErrRegionNotAuthed = errors.New("error unable to authenticate with region") |
1363 | +) |
1364 | + |
1365 | +func authenticate(ctx context.Context, region string, rpcMgr *transport.RPCManager) error { |
1366 | + authenticatorIface, err := rpcMgr.GetClient("authenticator") |
1367 | + if err != nil { |
1368 | + return err |
1369 | + } |
1370 | + authenticator, ok := authenticatorIface.(auth.Authenticator) |
1371 | + if !ok { |
1372 | + return ErrNoAuthenticatorProvided |
1373 | + } |
1374 | + secret := []byte{} // TODO get this from filesystem |
1375 | + message := make([]byte, 16) |
1376 | + _, err = rand.Read(message) |
1377 | + if err != nil { |
1378 | + return err |
1379 | + } |
1380 | + creds, err := authenticator.Authenticate(ctx, region, secret, message) |
1381 | + if err != nil { |
1382 | + return err |
1383 | + } |
1384 | + if !creds.Verify(secret, message) { |
1385 | + return fmt.Errorf("%w: credential verification failed", ErrRegionNotAuthed) |
1386 | + } |
1387 | + return nil |
1388 | +} |
1389 | + |
1390 | +func register(ctx context.Context, region, localVersion string, rpcMgr *transport.RPCManager) error { |
1391 | + registererIface, err := rpcMgr.GetClient("registerer") |
1392 | + if err != nil { |
1393 | + return err |
1394 | + } |
1395 | + registerer, ok := registererIface.(reg.Registerer) |
1396 | + if !ok { |
1397 | + return ErrNoRegistererProvided |
1398 | + } |
1399 | + // TODO get cluster UUID from config |
1400 | + clusterUUID := "123456" |
1401 | + systemId, err := machinehelpers.GetMAASID() |
1402 | + if err != nil { |
1403 | + return err |
1404 | + } |
1405 | + interfaces, err := machinehelpers.GetAllInterfacesDefinition(ctx, false) |
1406 | + if err != nil { |
1407 | + return err |
1408 | + } |
1409 | + hostname, err := os.Hostname() |
1410 | + if err != nil { |
1411 | + return err |
1412 | + } |
1413 | + err = registerer.Register( |
1414 | + ctx, |
1415 | + region, |
1416 | + clusterUUID, |
1417 | + systemId, |
1418 | + hostname, |
1419 | + localVersion, |
1420 | + interfaces, |
1421 | + ) |
1422 | + if err != nil { |
1423 | + return err |
1424 | + } |
1425 | + return nil |
1426 | +} |
1427 | + |
1428 | +func Handshake(ctx context.Context, region, localVersion string, rpcMgr *transport.RPCManager) error { |
1429 | + err := authenticate(ctx, region, rpcMgr) |
1430 | + if err != nil { |
1431 | + return err |
1432 | + } |
1433 | + return register(ctx, region, localVersion, rpcMgr) |
1434 | +} |
1435 | diff --git a/src/rackd_spike/pkg/register/registerer.go b/src/rackd_spike/pkg/register/registerer.go |
1436 | new file mode 100644 |
1437 | index 0000000..b6562e7 |
1438 | --- /dev/null |
1439 | +++ b/src/rackd_spike/pkg/register/registerer.go |
1440 | @@ -0,0 +1,125 @@ |
1441 | +package register |
1442 | + |
1443 | +import ( |
1444 | + "context" |
1445 | + |
1446 | + "github.com/rs/zerolog" |
1447 | + |
1448 | + machinehelpers "rackd/internal/machine_helpers" |
1449 | + "rackd/internal/metrics" |
1450 | + "rackd/internal/transport" |
1451 | + "rackd/pkg/rpc" |
1452 | +) |
1453 | + |
1454 | +type Registerer interface { |
1455 | + transport.RPCClient |
1456 | + Register( |
1457 | + ctx context.Context, |
1458 | + region, clusterUUID, systemId, hostname, version string, |
1459 | + interfaces map[string]machinehelpers.Interface, |
1460 | + ) error |
1461 | +} |
1462 | + |
1463 | +type CapnpRegisterer struct { |
1464 | + clients map[string]*rpc.Registerer |
1465 | +} |
1466 | + |
1467 | +func NewCapnpRegisterer() Registerer { |
1468 | + return &CapnpRegisterer{} |
1469 | +} |
1470 | + |
1471 | +func (c *CapnpRegisterer) Name() string { |
1472 | + return "Registerer" |
1473 | +} |
1474 | + |
1475 | +func (c *CapnpRegisterer) RegisterMetrics(registry *metrics.Registry) error { |
1476 | + // TODO |
1477 | + return nil |
1478 | +} |
1479 | + |
1480 | +func (c *CapnpRegisterer) SetupClient(ctx context.Context, client *transport.ConnWrapper) { |
1481 | + c.clients[client.Conn.RemoteAddr().String()] = &rpc.Registerer{Client: client.Capnp().Bootstrap(ctx)} |
1482 | +} |
1483 | + |
1484 | +func (c *CapnpRegisterer) Register( |
1485 | + ctx context.Context, |
1486 | + region, clusterUUID, systemId, hostname, version string, |
1487 | + interfaces map[string]machinehelpers.Interface, |
1488 | +) error { |
1489 | + client, ok := c.clients[region] |
1490 | + if !ok { |
1491 | + return transport.ErrRPCClientNotFound |
1492 | + } |
1493 | + result, release := client.Register(ctx, func(params rpc.Registerer_register_Params) error { |
1494 | + req, err := params.NewReq() |
1495 | + if err != nil { |
1496 | + return err |
1497 | + } |
1498 | + err = req.SetSystemId(systemId) |
1499 | + if err != nil { |
1500 | + return err |
1501 | + } |
1502 | + err = req.SetHostname(hostname) |
1503 | + if err != nil { |
1504 | + return err |
1505 | + } |
1506 | + ifaces, err := req.NewInterfaces() |
1507 | + if err != nil { |
1508 | + return err |
1509 | + } |
1510 | + capnpIfaces := machinehelpers.CapnpInterfaces(interfaces) |
1511 | + err = capnpIfaces.SetProto(ifaces) |
1512 | + if err != nil { |
1513 | + return err |
1514 | + } |
1515 | + err = req.SetUrl(region) |
1516 | + if err != nil { |
1517 | + return err |
1518 | + } |
1519 | + err = req.SetNodegroup(clusterUUID) |
1520 | + if err != nil { |
1521 | + return err |
1522 | + } |
1523 | + req.SetBeaconSupport(true) |
1524 | + err = req.SetVersion(version) |
1525 | + if err != nil { |
1526 | + return err |
1527 | + } |
1528 | + return nil |
1529 | + }) |
1530 | + defer release() |
1531 | + resp, err := result.Struct() |
1532 | + if err != nil { |
1533 | + return err |
1534 | + } |
1535 | + res, err := resp.Resp() |
1536 | + if err != nil { |
1537 | + return err |
1538 | + } |
1539 | + localId, err := res.SystemId() |
1540 | + if err != nil { |
1541 | + return err |
1542 | + } |
1543 | + // TODO set global metrics labels |
1544 | + err = machinehelpers.SetMAASId(localId) |
1545 | + if err != nil { |
1546 | + return err |
1547 | + } |
1548 | + respVersion, err := res.Version() |
1549 | + if err != nil { |
1550 | + return err |
1551 | + } |
1552 | + if len(respVersion) == 0 { |
1553 | + respVersion = "unknown MAAS version" |
1554 | + } |
1555 | + log := zerolog.Ctx(ctx) |
1556 | + log.Log().Msgf("Rack controller '%s' registered (via %s) with %s.", localId, region, respVersion) |
1557 | + return nil |
1558 | +} |
1559 | + |
1560 | +func (c *CapnpRegisterer) Release() { |
1561 | + for k, client := range c.clients { |
1562 | + client.Release() |
1563 | + delete(c.clients, k) |
1564 | + } |
1565 | +} |
1566 | diff --git a/src/rackd_spike/pkg/rpc/handshake.capnp.go b/src/rackd_spike/pkg/rpc/handshake.capnp.go |
1567 | new file mode 100644 |
1568 | index 0000000..94955c9 |
1569 | --- /dev/null |
1570 | +++ b/src/rackd_spike/pkg/rpc/handshake.capnp.go |
1571 | @@ -0,0 +1,933 @@ |
1572 | +// Code generated by capnpc-go. DO NOT EDIT. |
1573 | + |
1574 | +package rpc |
1575 | + |
1576 | +import ( |
1577 | + capnp "capnproto.org/go/capnp/v3" |
1578 | + text "capnproto.org/go/capnp/v3/encoding/text" |
1579 | + schemas "capnproto.org/go/capnp/v3/schemas" |
1580 | + server "capnproto.org/go/capnp/v3/server" |
1581 | + context "context" |
1582 | +) |
1583 | + |
1584 | +type AuthResponse struct{ capnp.Struct } |
1585 | + |
1586 | +// AuthResponse_TypeID is the unique identifier for the type AuthResponse. |
1587 | +const AuthResponse_TypeID = 0x98b03f82d720e4e1 |
1588 | + |
1589 | +func NewAuthResponse(s *capnp.Segment) (AuthResponse, error) { |
1590 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) |
1591 | + return AuthResponse{st}, err |
1592 | +} |
1593 | + |
1594 | +func NewRootAuthResponse(s *capnp.Segment) (AuthResponse, error) { |
1595 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) |
1596 | + return AuthResponse{st}, err |
1597 | +} |
1598 | + |
1599 | +func ReadRootAuthResponse(msg *capnp.Message) (AuthResponse, error) { |
1600 | + root, err := msg.Root() |
1601 | + return AuthResponse{root.Struct()}, err |
1602 | +} |
1603 | + |
1604 | +func (s AuthResponse) String() string { |
1605 | + str, _ := text.Marshal(0x98b03f82d720e4e1, s.Struct) |
1606 | + return str |
1607 | +} |
1608 | + |
1609 | +func (s AuthResponse) Salt() ([]byte, error) { |
1610 | + p, err := s.Struct.Ptr(0) |
1611 | + return []byte(p.Data()), err |
1612 | +} |
1613 | + |
1614 | +func (s AuthResponse) HasSalt() bool { |
1615 | + return s.Struct.HasPtr(0) |
1616 | +} |
1617 | + |
1618 | +func (s AuthResponse) SetSalt(v []byte) error { |
1619 | + return s.Struct.SetData(0, v) |
1620 | +} |
1621 | + |
1622 | +func (s AuthResponse) Digest() ([]byte, error) { |
1623 | + p, err := s.Struct.Ptr(1) |
1624 | + return []byte(p.Data()), err |
1625 | +} |
1626 | + |
1627 | +func (s AuthResponse) HasDigest() bool { |
1628 | + return s.Struct.HasPtr(1) |
1629 | +} |
1630 | + |
1631 | +func (s AuthResponse) SetDigest(v []byte) error { |
1632 | + return s.Struct.SetData(1, v) |
1633 | +} |
1634 | + |
1635 | +// AuthResponse_List is a list of AuthResponse. |
1636 | +type AuthResponse_List struct{ capnp.List } |
1637 | + |
1638 | +// NewAuthResponse creates a new list of AuthResponse. |
1639 | +func NewAuthResponse_List(s *capnp.Segment, sz int32) (AuthResponse_List, error) { |
1640 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz) |
1641 | + return AuthResponse_List{l}, err |
1642 | +} |
1643 | + |
1644 | +func (s AuthResponse_List) At(i int) AuthResponse { return AuthResponse{s.List.Struct(i)} } |
1645 | + |
1646 | +func (s AuthResponse_List) Set(i int, v AuthResponse) error { return s.List.SetStruct(i, v.Struct) } |
1647 | + |
1648 | +func (s AuthResponse_List) String() string { |
1649 | + str, _ := text.MarshalList(0x98b03f82d720e4e1, s.List) |
1650 | + return str |
1651 | +} |
1652 | + |
1653 | +// AuthResponse_Future is a wrapper for a AuthResponse promised by a client call. |
1654 | +type AuthResponse_Future struct{ *capnp.Future } |
1655 | + |
1656 | +func (p AuthResponse_Future) Struct() (AuthResponse, error) { |
1657 | + s, err := p.Future.Struct() |
1658 | + return AuthResponse{s}, err |
1659 | +} |
1660 | + |
1661 | +type Authenticator struct{ Client *capnp.Client } |
1662 | + |
1663 | +// Authenticator_TypeID is the unique identifier for the type Authenticator. |
1664 | +const Authenticator_TypeID = 0x800ae3a77a7bc18e |
1665 | + |
1666 | +func (c Authenticator) Authenticate(ctx context.Context, params func(Authenticator_authenticate_Params) error) (Authenticator_authenticate_Results_Future, capnp.ReleaseFunc) { |
1667 | + s := capnp.Send{ |
1668 | + Method: capnp.Method{ |
1669 | + InterfaceID: 0x800ae3a77a7bc18e, |
1670 | + MethodID: 0, |
1671 | + InterfaceName: "handshake.capnp:Authenticator", |
1672 | + MethodName: "authenticate", |
1673 | + }, |
1674 | + } |
1675 | + if params != nil { |
1676 | + s.ArgsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 1} |
1677 | + s.PlaceArgs = func(s capnp.Struct) error { return params(Authenticator_authenticate_Params{Struct: s}) } |
1678 | + } |
1679 | + ans, release := c.Client.SendCall(ctx, s) |
1680 | + return Authenticator_authenticate_Results_Future{Future: ans.Future()}, release |
1681 | +} |
1682 | + |
1683 | +func (c Authenticator) AddRef() Authenticator { |
1684 | + return Authenticator{ |
1685 | + Client: c.Client.AddRef(), |
1686 | + } |
1687 | +} |
1688 | + |
1689 | +func (c Authenticator) Release() { |
1690 | + c.Client.Release() |
1691 | +} |
1692 | + |
1693 | +// A Authenticator_Server is a Authenticator with a local implementation. |
1694 | +type Authenticator_Server interface { |
1695 | + Authenticate(context.Context, Authenticator_authenticate) error |
1696 | +} |
1697 | + |
1698 | +// Authenticator_NewServer creates a new Server from an implementation of Authenticator_Server. |
1699 | +func Authenticator_NewServer(s Authenticator_Server, policy *server.Policy) *server.Server { |
1700 | + c, _ := s.(server.Shutdowner) |
1701 | + return server.New(Authenticator_Methods(nil, s), s, c, policy) |
1702 | +} |
1703 | + |
1704 | +// Authenticator_ServerToClient creates a new Client from an implementation of Authenticator_Server. |
1705 | +// The caller is responsible for calling Release on the returned Client. |
1706 | +func Authenticator_ServerToClient(s Authenticator_Server, policy *server.Policy) Authenticator { |
1707 | + return Authenticator{Client: capnp.NewClient(Authenticator_NewServer(s, policy))} |
1708 | +} |
1709 | + |
1710 | +// Authenticator_Methods appends Methods to a slice that invoke the methods on s. |
1711 | +// This can be used to create a more complicated Server. |
1712 | +func Authenticator_Methods(methods []server.Method, s Authenticator_Server) []server.Method { |
1713 | + if cap(methods) == 0 { |
1714 | + methods = make([]server.Method, 0, 1) |
1715 | + } |
1716 | + |
1717 | + methods = append(methods, server.Method{ |
1718 | + Method: capnp.Method{ |
1719 | + InterfaceID: 0x800ae3a77a7bc18e, |
1720 | + MethodID: 0, |
1721 | + InterfaceName: "handshake.capnp:Authenticator", |
1722 | + MethodName: "authenticate", |
1723 | + }, |
1724 | + Impl: func(ctx context.Context, call *server.Call) error { |
1725 | + return s.Authenticate(ctx, Authenticator_authenticate{call}) |
1726 | + }, |
1727 | + }) |
1728 | + |
1729 | + return methods |
1730 | +} |
1731 | + |
1732 | +// Authenticator_authenticate holds the state for a server call to Authenticator.authenticate. |
1733 | +// See server.Call for documentation. |
1734 | +type Authenticator_authenticate struct { |
1735 | + *server.Call |
1736 | +} |
1737 | + |
1738 | +// Args returns the call's arguments. |
1739 | +func (c Authenticator_authenticate) Args() Authenticator_authenticate_Params { |
1740 | + return Authenticator_authenticate_Params{Struct: c.Call.Args()} |
1741 | +} |
1742 | + |
1743 | +// AllocResults allocates the results struct. |
1744 | +func (c Authenticator_authenticate) AllocResults() (Authenticator_authenticate_Results, error) { |
1745 | + r, err := c.Call.AllocResults(capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
1746 | + return Authenticator_authenticate_Results{Struct: r}, err |
1747 | +} |
1748 | + |
1749 | +type Authenticator_authenticate_Params struct{ capnp.Struct } |
1750 | + |
1751 | +// Authenticator_authenticate_Params_TypeID is the unique identifier for the type Authenticator_authenticate_Params. |
1752 | +const Authenticator_authenticate_Params_TypeID = 0xdbaca3bedaffa653 |
1753 | + |
1754 | +func NewAuthenticator_authenticate_Params(s *capnp.Segment) (Authenticator_authenticate_Params, error) { |
1755 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
1756 | + return Authenticator_authenticate_Params{st}, err |
1757 | +} |
1758 | + |
1759 | +func NewRootAuthenticator_authenticate_Params(s *capnp.Segment) (Authenticator_authenticate_Params, error) { |
1760 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
1761 | + return Authenticator_authenticate_Params{st}, err |
1762 | +} |
1763 | + |
1764 | +func ReadRootAuthenticator_authenticate_Params(msg *capnp.Message) (Authenticator_authenticate_Params, error) { |
1765 | + root, err := msg.Root() |
1766 | + return Authenticator_authenticate_Params{root.Struct()}, err |
1767 | +} |
1768 | + |
1769 | +func (s Authenticator_authenticate_Params) String() string { |
1770 | + str, _ := text.Marshal(0xdbaca3bedaffa653, s.Struct) |
1771 | + return str |
1772 | +} |
1773 | + |
1774 | +func (s Authenticator_authenticate_Params) Msg() ([]byte, error) { |
1775 | + p, err := s.Struct.Ptr(0) |
1776 | + return []byte(p.Data()), err |
1777 | +} |
1778 | + |
1779 | +func (s Authenticator_authenticate_Params) HasMsg() bool { |
1780 | + return s.Struct.HasPtr(0) |
1781 | +} |
1782 | + |
1783 | +func (s Authenticator_authenticate_Params) SetMsg(v []byte) error { |
1784 | + return s.Struct.SetData(0, v) |
1785 | +} |
1786 | + |
1787 | +// Authenticator_authenticate_Params_List is a list of Authenticator_authenticate_Params. |
1788 | +type Authenticator_authenticate_Params_List struct{ capnp.List } |
1789 | + |
1790 | +// NewAuthenticator_authenticate_Params creates a new list of Authenticator_authenticate_Params. |
1791 | +func NewAuthenticator_authenticate_Params_List(s *capnp.Segment, sz int32) (Authenticator_authenticate_Params_List, error) { |
1792 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) |
1793 | + return Authenticator_authenticate_Params_List{l}, err |
1794 | +} |
1795 | + |
1796 | +func (s Authenticator_authenticate_Params_List) At(i int) Authenticator_authenticate_Params { |
1797 | + return Authenticator_authenticate_Params{s.List.Struct(i)} |
1798 | +} |
1799 | + |
1800 | +func (s Authenticator_authenticate_Params_List) Set(i int, v Authenticator_authenticate_Params) error { |
1801 | + return s.List.SetStruct(i, v.Struct) |
1802 | +} |
1803 | + |
1804 | +func (s Authenticator_authenticate_Params_List) String() string { |
1805 | + str, _ := text.MarshalList(0xdbaca3bedaffa653, s.List) |
1806 | + return str |
1807 | +} |
1808 | + |
1809 | +// Authenticator_authenticate_Params_Future is a wrapper for a Authenticator_authenticate_Params promised by a client call. |
1810 | +type Authenticator_authenticate_Params_Future struct{ *capnp.Future } |
1811 | + |
1812 | +func (p Authenticator_authenticate_Params_Future) Struct() (Authenticator_authenticate_Params, error) { |
1813 | + s, err := p.Future.Struct() |
1814 | + return Authenticator_authenticate_Params{s}, err |
1815 | +} |
1816 | + |
1817 | +type Authenticator_authenticate_Results struct{ capnp.Struct } |
1818 | + |
1819 | +// Authenticator_authenticate_Results_TypeID is the unique identifier for the type Authenticator_authenticate_Results. |
1820 | +const Authenticator_authenticate_Results_TypeID = 0x96c07ce683897942 |
1821 | + |
1822 | +func NewAuthenticator_authenticate_Results(s *capnp.Segment) (Authenticator_authenticate_Results, error) { |
1823 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
1824 | + return Authenticator_authenticate_Results{st}, err |
1825 | +} |
1826 | + |
1827 | +func NewRootAuthenticator_authenticate_Results(s *capnp.Segment) (Authenticator_authenticate_Results, error) { |
1828 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
1829 | + return Authenticator_authenticate_Results{st}, err |
1830 | +} |
1831 | + |
1832 | +func ReadRootAuthenticator_authenticate_Results(msg *capnp.Message) (Authenticator_authenticate_Results, error) { |
1833 | + root, err := msg.Root() |
1834 | + return Authenticator_authenticate_Results{root.Struct()}, err |
1835 | +} |
1836 | + |
1837 | +func (s Authenticator_authenticate_Results) String() string { |
1838 | + str, _ := text.Marshal(0x96c07ce683897942, s.Struct) |
1839 | + return str |
1840 | +} |
1841 | + |
1842 | +func (s Authenticator_authenticate_Results) Resp() (AuthResponse, error) { |
1843 | + p, err := s.Struct.Ptr(0) |
1844 | + return AuthResponse{Struct: p.Struct()}, err |
1845 | +} |
1846 | + |
1847 | +func (s Authenticator_authenticate_Results) HasResp() bool { |
1848 | + return s.Struct.HasPtr(0) |
1849 | +} |
1850 | + |
1851 | +func (s Authenticator_authenticate_Results) SetResp(v AuthResponse) error { |
1852 | + return s.Struct.SetPtr(0, v.Struct.ToPtr()) |
1853 | +} |
1854 | + |
1855 | +// NewResp sets the resp field to a newly |
1856 | +// allocated AuthResponse struct, preferring placement in s's segment. |
1857 | +func (s Authenticator_authenticate_Results) NewResp() (AuthResponse, error) { |
1858 | + ss, err := NewAuthResponse(s.Struct.Segment()) |
1859 | + if err != nil { |
1860 | + return AuthResponse{}, err |
1861 | + } |
1862 | + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) |
1863 | + return ss, err |
1864 | +} |
1865 | + |
1866 | +// Authenticator_authenticate_Results_List is a list of Authenticator_authenticate_Results. |
1867 | +type Authenticator_authenticate_Results_List struct{ capnp.List } |
1868 | + |
1869 | +// NewAuthenticator_authenticate_Results creates a new list of Authenticator_authenticate_Results. |
1870 | +func NewAuthenticator_authenticate_Results_List(s *capnp.Segment, sz int32) (Authenticator_authenticate_Results_List, error) { |
1871 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) |
1872 | + return Authenticator_authenticate_Results_List{l}, err |
1873 | +} |
1874 | + |
1875 | +func (s Authenticator_authenticate_Results_List) At(i int) Authenticator_authenticate_Results { |
1876 | + return Authenticator_authenticate_Results{s.List.Struct(i)} |
1877 | +} |
1878 | + |
1879 | +func (s Authenticator_authenticate_Results_List) Set(i int, v Authenticator_authenticate_Results) error { |
1880 | + return s.List.SetStruct(i, v.Struct) |
1881 | +} |
1882 | + |
1883 | +func (s Authenticator_authenticate_Results_List) String() string { |
1884 | + str, _ := text.MarshalList(0x96c07ce683897942, s.List) |
1885 | + return str |
1886 | +} |
1887 | + |
1888 | +// Authenticator_authenticate_Results_Future is a wrapper for a Authenticator_authenticate_Results promised by a client call. |
1889 | +type Authenticator_authenticate_Results_Future struct{ *capnp.Future } |
1890 | + |
1891 | +func (p Authenticator_authenticate_Results_Future) Struct() (Authenticator_authenticate_Results, error) { |
1892 | + s, err := p.Future.Struct() |
1893 | + return Authenticator_authenticate_Results{s}, err |
1894 | +} |
1895 | + |
1896 | +func (p Authenticator_authenticate_Results_Future) Resp() AuthResponse_Future { |
1897 | + return AuthResponse_Future{Future: p.Future.Field(0, nil)} |
1898 | +} |
1899 | + |
1900 | +type RegisterRequest struct{ capnp.Struct } |
1901 | + |
1902 | +// RegisterRequest_TypeID is the unique identifier for the type RegisterRequest. |
1903 | +const RegisterRequest_TypeID = 0x8a21a43d866e69f4 |
1904 | + |
1905 | +func NewRegisterRequest(s *capnp.Segment) (RegisterRequest, error) { |
1906 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}) |
1907 | + return RegisterRequest{st}, err |
1908 | +} |
1909 | + |
1910 | +func NewRootRegisterRequest(s *capnp.Segment) (RegisterRequest, error) { |
1911 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}) |
1912 | + return RegisterRequest{st}, err |
1913 | +} |
1914 | + |
1915 | +func ReadRootRegisterRequest(msg *capnp.Message) (RegisterRequest, error) { |
1916 | + root, err := msg.Root() |
1917 | + return RegisterRequest{root.Struct()}, err |
1918 | +} |
1919 | + |
1920 | +func (s RegisterRequest) String() string { |
1921 | + str, _ := text.Marshal(0x8a21a43d866e69f4, s.Struct) |
1922 | + return str |
1923 | +} |
1924 | + |
1925 | +func (s RegisterRequest) SystemId() (string, error) { |
1926 | + p, err := s.Struct.Ptr(0) |
1927 | + return p.Text(), err |
1928 | +} |
1929 | + |
1930 | +func (s RegisterRequest) HasSystemId() bool { |
1931 | + return s.Struct.HasPtr(0) |
1932 | +} |
1933 | + |
1934 | +func (s RegisterRequest) SystemIdBytes() ([]byte, error) { |
1935 | + p, err := s.Struct.Ptr(0) |
1936 | + return p.TextBytes(), err |
1937 | +} |
1938 | + |
1939 | +func (s RegisterRequest) SetSystemId(v string) error { |
1940 | + return s.Struct.SetText(0, v) |
1941 | +} |
1942 | + |
1943 | +func (s RegisterRequest) Hostname() (string, error) { |
1944 | + p, err := s.Struct.Ptr(1) |
1945 | + return p.Text(), err |
1946 | +} |
1947 | + |
1948 | +func (s RegisterRequest) HasHostname() bool { |
1949 | + return s.Struct.HasPtr(1) |
1950 | +} |
1951 | + |
1952 | +func (s RegisterRequest) HostnameBytes() ([]byte, error) { |
1953 | + p, err := s.Struct.Ptr(1) |
1954 | + return p.TextBytes(), err |
1955 | +} |
1956 | + |
1957 | +func (s RegisterRequest) SetHostname(v string) error { |
1958 | + return s.Struct.SetText(1, v) |
1959 | +} |
1960 | + |
1961 | +func (s RegisterRequest) Interfaces() (Interfaces, error) { |
1962 | + p, err := s.Struct.Ptr(2) |
1963 | + return Interfaces{Struct: p.Struct()}, err |
1964 | +} |
1965 | + |
1966 | +func (s RegisterRequest) HasInterfaces() bool { |
1967 | + return s.Struct.HasPtr(2) |
1968 | +} |
1969 | + |
1970 | +func (s RegisterRequest) SetInterfaces(v Interfaces) error { |
1971 | + return s.Struct.SetPtr(2, v.Struct.ToPtr()) |
1972 | +} |
1973 | + |
1974 | +// NewInterfaces sets the interfaces field to a newly |
1975 | +// allocated Interfaces struct, preferring placement in s's segment. |
1976 | +func (s RegisterRequest) NewInterfaces() (Interfaces, error) { |
1977 | + ss, err := NewInterfaces(s.Struct.Segment()) |
1978 | + if err != nil { |
1979 | + return Interfaces{}, err |
1980 | + } |
1981 | + err = s.Struct.SetPtr(2, ss.Struct.ToPtr()) |
1982 | + return ss, err |
1983 | +} |
1984 | + |
1985 | +func (s RegisterRequest) Url() (string, error) { |
1986 | + p, err := s.Struct.Ptr(3) |
1987 | + return p.Text(), err |
1988 | +} |
1989 | + |
1990 | +func (s RegisterRequest) HasUrl() bool { |
1991 | + return s.Struct.HasPtr(3) |
1992 | +} |
1993 | + |
1994 | +func (s RegisterRequest) UrlBytes() ([]byte, error) { |
1995 | + p, err := s.Struct.Ptr(3) |
1996 | + return p.TextBytes(), err |
1997 | +} |
1998 | + |
1999 | +func (s RegisterRequest) SetUrl(v string) error { |
2000 | + return s.Struct.SetText(3, v) |
2001 | +} |
2002 | + |
2003 | +func (s RegisterRequest) Nodegroup() (string, error) { |
2004 | + p, err := s.Struct.Ptr(4) |
2005 | + return p.Text(), err |
2006 | +} |
2007 | + |
2008 | +func (s RegisterRequest) HasNodegroup() bool { |
2009 | + return s.Struct.HasPtr(4) |
2010 | +} |
2011 | + |
2012 | +func (s RegisterRequest) NodegroupBytes() ([]byte, error) { |
2013 | + p, err := s.Struct.Ptr(4) |
2014 | + return p.TextBytes(), err |
2015 | +} |
2016 | + |
2017 | +func (s RegisterRequest) SetNodegroup(v string) error { |
2018 | + return s.Struct.SetText(4, v) |
2019 | +} |
2020 | + |
2021 | +func (s RegisterRequest) BeaconSupport() bool { |
2022 | + return s.Struct.Bit(0) |
2023 | +} |
2024 | + |
2025 | +func (s RegisterRequest) SetBeaconSupport(v bool) { |
2026 | + s.Struct.SetBit(0, v) |
2027 | +} |
2028 | + |
2029 | +func (s RegisterRequest) Version() (string, error) { |
2030 | + p, err := s.Struct.Ptr(5) |
2031 | + return p.Text(), err |
2032 | +} |
2033 | + |
2034 | +func (s RegisterRequest) HasVersion() bool { |
2035 | + return s.Struct.HasPtr(5) |
2036 | +} |
2037 | + |
2038 | +func (s RegisterRequest) VersionBytes() ([]byte, error) { |
2039 | + p, err := s.Struct.Ptr(5) |
2040 | + return p.TextBytes(), err |
2041 | +} |
2042 | + |
2043 | +func (s RegisterRequest) SetVersion(v string) error { |
2044 | + return s.Struct.SetText(5, v) |
2045 | +} |
2046 | + |
2047 | +// RegisterRequest_List is a list of RegisterRequest. |
2048 | +type RegisterRequest_List struct{ capnp.List } |
2049 | + |
2050 | +// NewRegisterRequest creates a new list of RegisterRequest. |
2051 | +func NewRegisterRequest_List(s *capnp.Segment, sz int32) (RegisterRequest_List, error) { |
2052 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}, sz) |
2053 | + return RegisterRequest_List{l}, err |
2054 | +} |
2055 | + |
2056 | +func (s RegisterRequest_List) At(i int) RegisterRequest { return RegisterRequest{s.List.Struct(i)} } |
2057 | + |
2058 | +func (s RegisterRequest_List) Set(i int, v RegisterRequest) error { |
2059 | + return s.List.SetStruct(i, v.Struct) |
2060 | +} |
2061 | + |
2062 | +func (s RegisterRequest_List) String() string { |
2063 | + str, _ := text.MarshalList(0x8a21a43d866e69f4, s.List) |
2064 | + return str |
2065 | +} |
2066 | + |
2067 | +// RegisterRequest_Future is a wrapper for a RegisterRequest promised by a client call. |
2068 | +type RegisterRequest_Future struct{ *capnp.Future } |
2069 | + |
2070 | +func (p RegisterRequest_Future) Struct() (RegisterRequest, error) { |
2071 | + s, err := p.Future.Struct() |
2072 | + return RegisterRequest{s}, err |
2073 | +} |
2074 | + |
2075 | +func (p RegisterRequest_Future) Interfaces() Interfaces_Future { |
2076 | + return Interfaces_Future{Future: p.Future.Field(2, nil)} |
2077 | +} |
2078 | + |
2079 | +type RegisterResponse struct{ capnp.Struct } |
2080 | + |
2081 | +// RegisterResponse_TypeID is the unique identifier for the type RegisterResponse. |
2082 | +const RegisterResponse_TypeID = 0x971fe28893233a11 |
2083 | + |
2084 | +func NewRegisterResponse(s *capnp.Segment) (RegisterResponse, error) { |
2085 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}) |
2086 | + return RegisterResponse{st}, err |
2087 | +} |
2088 | + |
2089 | +func NewRootRegisterResponse(s *capnp.Segment) (RegisterResponse, error) { |
2090 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}) |
2091 | + return RegisterResponse{st}, err |
2092 | +} |
2093 | + |
2094 | +func ReadRootRegisterResponse(msg *capnp.Message) (RegisterResponse, error) { |
2095 | + root, err := msg.Root() |
2096 | + return RegisterResponse{root.Struct()}, err |
2097 | +} |
2098 | + |
2099 | +func (s RegisterResponse) String() string { |
2100 | + str, _ := text.Marshal(0x971fe28893233a11, s.Struct) |
2101 | + return str |
2102 | +} |
2103 | + |
2104 | +func (s RegisterResponse) SystemId() (string, error) { |
2105 | + p, err := s.Struct.Ptr(0) |
2106 | + return p.Text(), err |
2107 | +} |
2108 | + |
2109 | +func (s RegisterResponse) HasSystemId() bool { |
2110 | + return s.Struct.HasPtr(0) |
2111 | +} |
2112 | + |
2113 | +func (s RegisterResponse) SystemIdBytes() ([]byte, error) { |
2114 | + p, err := s.Struct.Ptr(0) |
2115 | + return p.TextBytes(), err |
2116 | +} |
2117 | + |
2118 | +func (s RegisterResponse) SetSystemId(v string) error { |
2119 | + return s.Struct.SetText(0, v) |
2120 | +} |
2121 | + |
2122 | +func (s RegisterResponse) Uuid() (string, error) { |
2123 | + p, err := s.Struct.Ptr(1) |
2124 | + return p.Text(), err |
2125 | +} |
2126 | + |
2127 | +func (s RegisterResponse) HasUuid() bool { |
2128 | + return s.Struct.HasPtr(1) |
2129 | +} |
2130 | + |
2131 | +func (s RegisterResponse) UuidBytes() ([]byte, error) { |
2132 | + p, err := s.Struct.Ptr(1) |
2133 | + return p.TextBytes(), err |
2134 | +} |
2135 | + |
2136 | +func (s RegisterResponse) SetUuid(v string) error { |
2137 | + return s.Struct.SetText(1, v) |
2138 | +} |
2139 | + |
2140 | +func (s RegisterResponse) Version() (string, error) { |
2141 | + p, err := s.Struct.Ptr(2) |
2142 | + return p.Text(), err |
2143 | +} |
2144 | + |
2145 | +func (s RegisterResponse) HasVersion() bool { |
2146 | + return s.Struct.HasPtr(2) |
2147 | +} |
2148 | + |
2149 | +func (s RegisterResponse) VersionBytes() ([]byte, error) { |
2150 | + p, err := s.Struct.Ptr(2) |
2151 | + return p.TextBytes(), err |
2152 | +} |
2153 | + |
2154 | +func (s RegisterResponse) SetVersion(v string) error { |
2155 | + return s.Struct.SetText(2, v) |
2156 | +} |
2157 | + |
2158 | +// RegisterResponse_List is a list of RegisterResponse. |
2159 | +type RegisterResponse_List struct{ capnp.List } |
2160 | + |
2161 | +// NewRegisterResponse creates a new list of RegisterResponse. |
2162 | +func NewRegisterResponse_List(s *capnp.Segment, sz int32) (RegisterResponse_List, error) { |
2163 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}, sz) |
2164 | + return RegisterResponse_List{l}, err |
2165 | +} |
2166 | + |
2167 | +func (s RegisterResponse_List) At(i int) RegisterResponse { return RegisterResponse{s.List.Struct(i)} } |
2168 | + |
2169 | +func (s RegisterResponse_List) Set(i int, v RegisterResponse) error { |
2170 | + return s.List.SetStruct(i, v.Struct) |
2171 | +} |
2172 | + |
2173 | +func (s RegisterResponse_List) String() string { |
2174 | + str, _ := text.MarshalList(0x971fe28893233a11, s.List) |
2175 | + return str |
2176 | +} |
2177 | + |
2178 | +// RegisterResponse_Future is a wrapper for a RegisterResponse promised by a client call. |
2179 | +type RegisterResponse_Future struct{ *capnp.Future } |
2180 | + |
2181 | +func (p RegisterResponse_Future) Struct() (RegisterResponse, error) { |
2182 | + s, err := p.Future.Struct() |
2183 | + return RegisterResponse{s}, err |
2184 | +} |
2185 | + |
2186 | +type Registerer struct{ Client *capnp.Client } |
2187 | + |
2188 | +// Registerer_TypeID is the unique identifier for the type Registerer. |
2189 | +const Registerer_TypeID = 0xe75723043cae2d20 |
2190 | + |
2191 | +func (c Registerer) Register(ctx context.Context, params func(Registerer_register_Params) error) (Registerer_register_Results_Future, capnp.ReleaseFunc) { |
2192 | + s := capnp.Send{ |
2193 | + Method: capnp.Method{ |
2194 | + InterfaceID: 0xe75723043cae2d20, |
2195 | + MethodID: 0, |
2196 | + InterfaceName: "handshake.capnp:Registerer", |
2197 | + MethodName: "register", |
2198 | + }, |
2199 | + } |
2200 | + if params != nil { |
2201 | + s.ArgsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 1} |
2202 | + s.PlaceArgs = func(s capnp.Struct) error { return params(Registerer_register_Params{Struct: s}) } |
2203 | + } |
2204 | + ans, release := c.Client.SendCall(ctx, s) |
2205 | + return Registerer_register_Results_Future{Future: ans.Future()}, release |
2206 | +} |
2207 | + |
2208 | +func (c Registerer) AddRef() Registerer { |
2209 | + return Registerer{ |
2210 | + Client: c.Client.AddRef(), |
2211 | + } |
2212 | +} |
2213 | + |
2214 | +func (c Registerer) Release() { |
2215 | + c.Client.Release() |
2216 | +} |
2217 | + |
2218 | +// A Registerer_Server is a Registerer with a local implementation. |
2219 | +type Registerer_Server interface { |
2220 | + Register(context.Context, Registerer_register) error |
2221 | +} |
2222 | + |
2223 | +// Registerer_NewServer creates a new Server from an implementation of Registerer_Server. |
2224 | +func Registerer_NewServer(s Registerer_Server, policy *server.Policy) *server.Server { |
2225 | + c, _ := s.(server.Shutdowner) |
2226 | + return server.New(Registerer_Methods(nil, s), s, c, policy) |
2227 | +} |
2228 | + |
2229 | +// Registerer_ServerToClient creates a new Client from an implementation of Registerer_Server. |
2230 | +// The caller is responsible for calling Release on the returned Client. |
2231 | +func Registerer_ServerToClient(s Registerer_Server, policy *server.Policy) Registerer { |
2232 | + return Registerer{Client: capnp.NewClient(Registerer_NewServer(s, policy))} |
2233 | +} |
2234 | + |
2235 | +// Registerer_Methods appends Methods to a slice that invoke the methods on s. |
2236 | +// This can be used to create a more complicated Server. |
2237 | +func Registerer_Methods(methods []server.Method, s Registerer_Server) []server.Method { |
2238 | + if cap(methods) == 0 { |
2239 | + methods = make([]server.Method, 0, 1) |
2240 | + } |
2241 | + |
2242 | + methods = append(methods, server.Method{ |
2243 | + Method: capnp.Method{ |
2244 | + InterfaceID: 0xe75723043cae2d20, |
2245 | + MethodID: 0, |
2246 | + InterfaceName: "handshake.capnp:Registerer", |
2247 | + MethodName: "register", |
2248 | + }, |
2249 | + Impl: func(ctx context.Context, call *server.Call) error { |
2250 | + return s.Register(ctx, Registerer_register{call}) |
2251 | + }, |
2252 | + }) |
2253 | + |
2254 | + return methods |
2255 | +} |
2256 | + |
2257 | +// Registerer_register holds the state for a server call to Registerer.register. |
2258 | +// See server.Call for documentation. |
2259 | +type Registerer_register struct { |
2260 | + *server.Call |
2261 | +} |
2262 | + |
2263 | +// Args returns the call's arguments. |
2264 | +func (c Registerer_register) Args() Registerer_register_Params { |
2265 | + return Registerer_register_Params{Struct: c.Call.Args()} |
2266 | +} |
2267 | + |
2268 | +// AllocResults allocates the results struct. |
2269 | +func (c Registerer_register) AllocResults() (Registerer_register_Results, error) { |
2270 | + r, err := c.Call.AllocResults(capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2271 | + return Registerer_register_Results{Struct: r}, err |
2272 | +} |
2273 | + |
2274 | +type Registerer_register_Params struct{ capnp.Struct } |
2275 | + |
2276 | +// Registerer_register_Params_TypeID is the unique identifier for the type Registerer_register_Params. |
2277 | +const Registerer_register_Params_TypeID = 0x80a0e6cbaa396ef4 |
2278 | + |
2279 | +func NewRegisterer_register_Params(s *capnp.Segment) (Registerer_register_Params, error) { |
2280 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2281 | + return Registerer_register_Params{st}, err |
2282 | +} |
2283 | + |
2284 | +func NewRootRegisterer_register_Params(s *capnp.Segment) (Registerer_register_Params, error) { |
2285 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2286 | + return Registerer_register_Params{st}, err |
2287 | +} |
2288 | + |
2289 | +func ReadRootRegisterer_register_Params(msg *capnp.Message) (Registerer_register_Params, error) { |
2290 | + root, err := msg.Root() |
2291 | + return Registerer_register_Params{root.Struct()}, err |
2292 | +} |
2293 | + |
2294 | +func (s Registerer_register_Params) String() string { |
2295 | + str, _ := text.Marshal(0x80a0e6cbaa396ef4, s.Struct) |
2296 | + return str |
2297 | +} |
2298 | + |
2299 | +func (s Registerer_register_Params) Req() (RegisterRequest, error) { |
2300 | + p, err := s.Struct.Ptr(0) |
2301 | + return RegisterRequest{Struct: p.Struct()}, err |
2302 | +} |
2303 | + |
2304 | +func (s Registerer_register_Params) HasReq() bool { |
2305 | + return s.Struct.HasPtr(0) |
2306 | +} |
2307 | + |
2308 | +func (s Registerer_register_Params) SetReq(v RegisterRequest) error { |
2309 | + return s.Struct.SetPtr(0, v.Struct.ToPtr()) |
2310 | +} |
2311 | + |
2312 | +// NewReq sets the req field to a newly |
2313 | +// allocated RegisterRequest struct, preferring placement in s's segment. |
2314 | +func (s Registerer_register_Params) NewReq() (RegisterRequest, error) { |
2315 | + ss, err := NewRegisterRequest(s.Struct.Segment()) |
2316 | + if err != nil { |
2317 | + return RegisterRequest{}, err |
2318 | + } |
2319 | + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) |
2320 | + return ss, err |
2321 | +} |
2322 | + |
2323 | +// Registerer_register_Params_List is a list of Registerer_register_Params. |
2324 | +type Registerer_register_Params_List struct{ capnp.List } |
2325 | + |
2326 | +// NewRegisterer_register_Params creates a new list of Registerer_register_Params. |
2327 | +func NewRegisterer_register_Params_List(s *capnp.Segment, sz int32) (Registerer_register_Params_List, error) { |
2328 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) |
2329 | + return Registerer_register_Params_List{l}, err |
2330 | +} |
2331 | + |
2332 | +func (s Registerer_register_Params_List) At(i int) Registerer_register_Params { |
2333 | + return Registerer_register_Params{s.List.Struct(i)} |
2334 | +} |
2335 | + |
2336 | +func (s Registerer_register_Params_List) Set(i int, v Registerer_register_Params) error { |
2337 | + return s.List.SetStruct(i, v.Struct) |
2338 | +} |
2339 | + |
2340 | +func (s Registerer_register_Params_List) String() string { |
2341 | + str, _ := text.MarshalList(0x80a0e6cbaa396ef4, s.List) |
2342 | + return str |
2343 | +} |
2344 | + |
2345 | +// Registerer_register_Params_Future is a wrapper for a Registerer_register_Params promised by a client call. |
2346 | +type Registerer_register_Params_Future struct{ *capnp.Future } |
2347 | + |
2348 | +func (p Registerer_register_Params_Future) Struct() (Registerer_register_Params, error) { |
2349 | + s, err := p.Future.Struct() |
2350 | + return Registerer_register_Params{s}, err |
2351 | +} |
2352 | + |
2353 | +func (p Registerer_register_Params_Future) Req() RegisterRequest_Future { |
2354 | + return RegisterRequest_Future{Future: p.Future.Field(0, nil)} |
2355 | +} |
2356 | + |
2357 | +type Registerer_register_Results struct{ capnp.Struct } |
2358 | + |
2359 | +// Registerer_register_Results_TypeID is the unique identifier for the type Registerer_register_Results. |
2360 | +const Registerer_register_Results_TypeID = 0xb5c83b347e16691c |
2361 | + |
2362 | +func NewRegisterer_register_Results(s *capnp.Segment) (Registerer_register_Results, error) { |
2363 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2364 | + return Registerer_register_Results{st}, err |
2365 | +} |
2366 | + |
2367 | +func NewRootRegisterer_register_Results(s *capnp.Segment) (Registerer_register_Results, error) { |
2368 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2369 | + return Registerer_register_Results{st}, err |
2370 | +} |
2371 | + |
2372 | +func ReadRootRegisterer_register_Results(msg *capnp.Message) (Registerer_register_Results, error) { |
2373 | + root, err := msg.Root() |
2374 | + return Registerer_register_Results{root.Struct()}, err |
2375 | +} |
2376 | + |
2377 | +func (s Registerer_register_Results) String() string { |
2378 | + str, _ := text.Marshal(0xb5c83b347e16691c, s.Struct) |
2379 | + return str |
2380 | +} |
2381 | + |
2382 | +func (s Registerer_register_Results) Resp() (RegisterResponse, error) { |
2383 | + p, err := s.Struct.Ptr(0) |
2384 | + return RegisterResponse{Struct: p.Struct()}, err |
2385 | +} |
2386 | + |
2387 | +func (s Registerer_register_Results) HasResp() bool { |
2388 | + return s.Struct.HasPtr(0) |
2389 | +} |
2390 | + |
2391 | +func (s Registerer_register_Results) SetResp(v RegisterResponse) error { |
2392 | + return s.Struct.SetPtr(0, v.Struct.ToPtr()) |
2393 | +} |
2394 | + |
2395 | +// NewResp sets the resp field to a newly |
2396 | +// allocated RegisterResponse struct, preferring placement in s's segment. |
2397 | +func (s Registerer_register_Results) NewResp() (RegisterResponse, error) { |
2398 | + ss, err := NewRegisterResponse(s.Struct.Segment()) |
2399 | + if err != nil { |
2400 | + return RegisterResponse{}, err |
2401 | + } |
2402 | + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) |
2403 | + return ss, err |
2404 | +} |
2405 | + |
2406 | +// Registerer_register_Results_List is a list of Registerer_register_Results. |
2407 | +type Registerer_register_Results_List struct{ capnp.List } |
2408 | + |
2409 | +// NewRegisterer_register_Results creates a new list of Registerer_register_Results. |
2410 | +func NewRegisterer_register_Results_List(s *capnp.Segment, sz int32) (Registerer_register_Results_List, error) { |
2411 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) |
2412 | + return Registerer_register_Results_List{l}, err |
2413 | +} |
2414 | + |
2415 | +func (s Registerer_register_Results_List) At(i int) Registerer_register_Results { |
2416 | + return Registerer_register_Results{s.List.Struct(i)} |
2417 | +} |
2418 | + |
2419 | +func (s Registerer_register_Results_List) Set(i int, v Registerer_register_Results) error { |
2420 | + return s.List.SetStruct(i, v.Struct) |
2421 | +} |
2422 | + |
2423 | +func (s Registerer_register_Results_List) String() string { |
2424 | + str, _ := text.MarshalList(0xb5c83b347e16691c, s.List) |
2425 | + return str |
2426 | +} |
2427 | + |
2428 | +// Registerer_register_Results_Future is a wrapper for a Registerer_register_Results promised by a client call. |
2429 | +type Registerer_register_Results_Future struct{ *capnp.Future } |
2430 | + |
2431 | +func (p Registerer_register_Results_Future) Struct() (Registerer_register_Results, error) { |
2432 | + s, err := p.Future.Struct() |
2433 | + return Registerer_register_Results{s}, err |
2434 | +} |
2435 | + |
2436 | +func (p Registerer_register_Results_Future) Resp() RegisterResponse_Future { |
2437 | + return RegisterResponse_Future{Future: p.Future.Field(0, nil)} |
2438 | +} |
2439 | + |
2440 | +const schema_dceab81b996ed67b = "x\xda\x8cTM\x88\x1cE\x18}\xaf\xaa\xbb'\x09\xbb" + |
2441 | + "\xcc\x14=zI\xe2F\xb3\x07W\xd8%\x92\x04qU" + |
2442 | + "6F%\xc9\xa2\xb8\xb51(\xb9uf\xca\xdd1;" + |
2443 | + "=\x93\xae\x1e%\xc6\x9f\x10QTPQ\xc1?<\x08" + |
2444 | + "\x8a\x82\x88z0\xa0\xa0\x12\xc1\xc0\x82\x04\x12\x10\x7f\xe2" + |
2445 | + "^\xa2!J\xc0\x8b\xe4\xe2AZj\xdc\xe9\xe9L\x0c" + |
2446 | + "\xd9[\xd7\xc7\xeb\xf7\xbd\xef\xbd\xaao\xd3Ub\x9b\xb8" + |
2447 | + "\xd1\xbf)\x00\xf4N?\xc8^\xfc\xe6\xd0\xa3\x1f\xfc\xb6" + |
2448 | + "\xe60TEf\x87~\x88\xdf\\\xfb\xf9\xf9%\x80!" + |
2449 | + "\xe5_\xe1\xb0,\x01\xe1j\xb9#\xdc\xea\xbe\xb2\x0b\xf1" + |
2450 | + "\xcd\x1f~w\xee\x9d\xc3Pk\x09\xf8,\x01\x9b\xd7\xcb" + |
2451 | + "\xbd\x04\xc319\x05f\x17\x1a\xf13\xb7\xbdw\xed\xf3" + |
2452 | + "\xd0\x15\xb2O\xe7\x07\x0e\xb9K\x0a\x86{\x1c\xd1f-" + |
2453 | + "_\"\x98m?\xf8\xdcS\xe7\x1e;\xf6\x1a\xd459" + |
2454 | + "\xdf\x9f\xde[\x8e\xef\x1f\xcf\xf1\xa9\xc9\x8d\xaf>\xfb\xeb" + |
2455 | + "\xc8\xebP\x95\"]\x97c\xbd\xbf\x86\xe1\xb8\xef\x14\x8e" + |
2456 | + "\xf9\x9f\x80\xd9\x99\xb3\x1b~<2\xf5\xe9\x1b\x03`\xe1" + |
2457 | + "\x10\xc7\xfd\xf3\xe1\xa9.\xf6\x84\xff\x08\x98\xadk\\\xfd" + |
2458 | + "\xc4\x96[\x16\x8f\x16'\x19\x0b\xf6\xb9\xce[\x03\xd7y" + |
2459 | + "\xf7\xfb\xd9\xe9\xaf\xdf\xfd\xe8\x97\xa2\xb4=\xc1+\x0e`" + |
2460 | + "\xba\x80\x0d\xe3\x1f\xdf\xeam\xbc\xff\xf7K\x8c{:8" + |
2461 | + "\x1d\xbe\xec\x06\x0e_\x08v\x84_\x04%\xd4\xb2\xf9(" + |
2462 | + "\xae\xdb\xf9h\xbf0\x13\xb5\xa8\x1d\xb7'o\xef\xa4\xf3" + |
2463 | + "&N\x1b#\xb5(m%3\xa4\xf6\xa4\x0f\xe4m\xd9" + |
2464 | + "\xb3F\xa9\x87 \xd4\xeaR\x16-\xff\x81r-J\xcd" + |
2465 | + "6\xce\x909\xad\xd7\xa3\x9d5s\x0d\x9b\x9a\xc4$\x13" + |
2466 | + "\xc9\xf2\xe7\xe8L\x94D\xb2i\xb5'=\xc0#\xa0\x86" + |
2467 | + "\xaf\x03\xf4*I]\x15,%\xe6\x00+\xfd\xe0@V" + |
2468 | + "\xd0g\x96\x83\xcc\xb3\xe6@\xc7\xd8\x14N\xf2\xba\x9c\xf1" + |
2469 | + "\xe84\xa0?\x93\xd4\xc7\x04\x15Y\xa5+~\xe5\x8a_" + |
2470 | + "J\xeaEA%D\x95\x02P\xc7\xf7\x02\xfa[I}" + |
2471 | + "RPIY\xa5\x04\xd4\x09'hQR\x7f/\xa8<" + |
2472 | + "\xafJ\x0fP\xa7f\x01}RR/\x09\xd2\xaf\xd2\x07" + |
2473 | + "\xd4\xcf\x09\xa0\x7f\x92\xd4g\x05U\xe0W\x19\x00\xea\xcc" + |
2474 | + "v@/I\xea?\x043{\xd0\xa6\xa6\xb9\xab\x0e\x80" + |
2475 | + "C\x10\x1cr\xc3\xb4l\x1aGMS\xac5\xe2\xd4$" + |
2476 | + "\x0fF5HcY\xc9\xee\x98~\xfc\xef{\xdf\xde\x7f" + |
2477 | + "dy\xfeR'Y\xc8\xa1q\xabn\xe6\x92V\x07l" + |
2478 | + "\xe7\xb5}&\xaa\xb5\xe2\xdd\x1d\x8c\xb4\xdb\xad$%!" + |
2479 | + "H\xf0\xc9\x87Mb\x1b\xad\xb8\xdfz\xd9G\x7f0\xf8" + |
2480 | + "n\xee\x13Q\xffdFg\x8d\xed,\xc8\xf4\xa2\xa4n" + |
2481 | + "\xe8'UN\x8cm\xb3\xd2\xbf\xe6W\x8e\xca\xb6[\xb1" + |
2482 | + "5\xe8\x865\x94\x93\xde\xe5r\xb9SR\xcf\x14\xc2\xba" + |
2483 | + "\xc7u\xda)\xa9\xef+\x84\xa5\x9d\xb3wK\xea\x07\xfe" + |
2484 | + "\xdf\xd9r\xa7\xd3\xa8\xf7\x0e\x97\x9d\xfd\xa2K\xefD\x95" + |
2485 | + "\x9d*\xa7iU\xaei\xcc\xb5\x1f\x95\xd4\x9b\x0a\x9a\xc6" + |
2486 | + "'\x01}\xbd\xa4\xde\"X\xb6\xd1B\xcaa\x08\x0e\x83" + |
2487 | + "S\xf5\xc6\x9c\xb1\xf9qe\xef\xc0\xd9[Z\xb8\xa2\xbd" + |
2488 | + "\xf9\xca\x19\xb0w%\x09\xba\xa7\xd6\xe4e\x9fZ\xd3\xce" + |
2489 | + "]\"Y\x0cJ\x96\xa6\xb0\x0ez\x0b\x97\xbd}\xa5\xd4" + |
2490 | + "\xf4\x7f\xeb\xa07\x16\x80\xee.\xf87\x00\x00\xff\xff\x86" + |
2491 | + "\xdc\x84m" |
2492 | + |
2493 | +func init() { |
2494 | + schemas.Register(schema_dceab81b996ed67b, |
2495 | + 0x800ae3a77a7bc18e, |
2496 | + 0x80a0e6cbaa396ef4, |
2497 | + 0x8a21a43d866e69f4, |
2498 | + 0x96c07ce683897942, |
2499 | + 0x971fe28893233a11, |
2500 | + 0x98b03f82d720e4e1, |
2501 | + 0xb5c83b347e16691c, |
2502 | + 0xdbaca3bedaffa653, |
2503 | + 0xe75723043cae2d20) |
2504 | +} |
2505 | diff --git a/src/rackd_spike/pkg/rpc/network.capnp.go b/src/rackd_spike/pkg/rpc/network.capnp.go |
2506 | new file mode 100644 |
2507 | index 0000000..4101c19 |
2508 | --- /dev/null |
2509 | +++ b/src/rackd_spike/pkg/rpc/network.capnp.go |
2510 | @@ -0,0 +1,489 @@ |
2511 | +// Code generated by capnpc-go. DO NOT EDIT. |
2512 | + |
2513 | +package rpc |
2514 | + |
2515 | +import ( |
2516 | + capnp "capnproto.org/go/capnp/v3" |
2517 | + text "capnproto.org/go/capnp/v3/encoding/text" |
2518 | + schemas "capnproto.org/go/capnp/v3/schemas" |
2519 | +) |
2520 | + |
2521 | +type Link struct{ capnp.Struct } |
2522 | + |
2523 | +// Link_TypeID is the unique identifier for the type Link. |
2524 | +const Link_TypeID = 0xc7251b7c2c125e6e |
2525 | + |
2526 | +func NewLink(s *capnp.Segment) (Link, error) { |
2527 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3}) |
2528 | + return Link{st}, err |
2529 | +} |
2530 | + |
2531 | +func NewRootLink(s *capnp.Segment) (Link, error) { |
2532 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3}) |
2533 | + return Link{st}, err |
2534 | +} |
2535 | + |
2536 | +func ReadRootLink(msg *capnp.Message) (Link, error) { |
2537 | + root, err := msg.Root() |
2538 | + return Link{root.Struct()}, err |
2539 | +} |
2540 | + |
2541 | +func (s Link) String() string { |
2542 | + str, _ := text.Marshal(0xc7251b7c2c125e6e, s.Struct) |
2543 | + return str |
2544 | +} |
2545 | + |
2546 | +func (s Link) Mode() (string, error) { |
2547 | + p, err := s.Struct.Ptr(0) |
2548 | + return p.Text(), err |
2549 | +} |
2550 | + |
2551 | +func (s Link) HasMode() bool { |
2552 | + return s.Struct.HasPtr(0) |
2553 | +} |
2554 | + |
2555 | +func (s Link) ModeBytes() ([]byte, error) { |
2556 | + p, err := s.Struct.Ptr(0) |
2557 | + return p.TextBytes(), err |
2558 | +} |
2559 | + |
2560 | +func (s Link) SetMode(v string) error { |
2561 | + return s.Struct.SetText(0, v) |
2562 | +} |
2563 | + |
2564 | +func (s Link) Address() (string, error) { |
2565 | + p, err := s.Struct.Ptr(1) |
2566 | + return p.Text(), err |
2567 | +} |
2568 | + |
2569 | +func (s Link) HasAddress() bool { |
2570 | + return s.Struct.HasPtr(1) |
2571 | +} |
2572 | + |
2573 | +func (s Link) AddressBytes() ([]byte, error) { |
2574 | + p, err := s.Struct.Ptr(1) |
2575 | + return p.TextBytes(), err |
2576 | +} |
2577 | + |
2578 | +func (s Link) SetAddress(v string) error { |
2579 | + return s.Struct.SetText(1, v) |
2580 | +} |
2581 | + |
2582 | +func (s Link) Gateway() (string, error) { |
2583 | + p, err := s.Struct.Ptr(2) |
2584 | + return p.Text(), err |
2585 | +} |
2586 | + |
2587 | +func (s Link) HasGateway() bool { |
2588 | + return s.Struct.HasPtr(2) |
2589 | +} |
2590 | + |
2591 | +func (s Link) GatewayBytes() ([]byte, error) { |
2592 | + p, err := s.Struct.Ptr(2) |
2593 | + return p.TextBytes(), err |
2594 | +} |
2595 | + |
2596 | +func (s Link) SetGateway(v string) error { |
2597 | + return s.Struct.SetText(2, v) |
2598 | +} |
2599 | + |
2600 | +func (s Link) Netmask() int32 { |
2601 | + return int32(s.Struct.Uint32(0)) |
2602 | +} |
2603 | + |
2604 | +func (s Link) SetNetmask(v int32) { |
2605 | + s.Struct.SetUint32(0, uint32(v)) |
2606 | +} |
2607 | + |
2608 | +// Link_List is a list of Link. |
2609 | +type Link_List struct{ capnp.List } |
2610 | + |
2611 | +// NewLink creates a new list of Link. |
2612 | +func NewLink_List(s *capnp.Segment, sz int32) (Link_List, error) { |
2613 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3}, sz) |
2614 | + return Link_List{l}, err |
2615 | +} |
2616 | + |
2617 | +func (s Link_List) At(i int) Link { return Link{s.List.Struct(i)} } |
2618 | + |
2619 | +func (s Link_List) Set(i int, v Link) error { return s.List.SetStruct(i, v.Struct) } |
2620 | + |
2621 | +func (s Link_List) String() string { |
2622 | + str, _ := text.MarshalList(0xc7251b7c2c125e6e, s.List) |
2623 | + return str |
2624 | +} |
2625 | + |
2626 | +// Link_Future is a wrapper for a Link promised by a client call. |
2627 | +type Link_Future struct{ *capnp.Future } |
2628 | + |
2629 | +func (p Link_Future) Struct() (Link, error) { |
2630 | + s, err := p.Future.Struct() |
2631 | + return Link{s}, err |
2632 | +} |
2633 | + |
2634 | +type InterfaceDetails struct{ capnp.Struct } |
2635 | + |
2636 | +// InterfaceDetails_TypeID is the unique identifier for the type InterfaceDetails. |
2637 | +const InterfaceDetails_TypeID = 0xca5e2a006234f169 |
2638 | + |
2639 | +func NewInterfaceDetails(s *capnp.Segment) (InterfaceDetails, error) { |
2640 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 4}) |
2641 | + return InterfaceDetails{st}, err |
2642 | +} |
2643 | + |
2644 | +func NewRootInterfaceDetails(s *capnp.Segment) (InterfaceDetails, error) { |
2645 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 4}) |
2646 | + return InterfaceDetails{st}, err |
2647 | +} |
2648 | + |
2649 | +func ReadRootInterfaceDetails(msg *capnp.Message) (InterfaceDetails, error) { |
2650 | + root, err := msg.Root() |
2651 | + return InterfaceDetails{root.Struct()}, err |
2652 | +} |
2653 | + |
2654 | +func (s InterfaceDetails) String() string { |
2655 | + str, _ := text.Marshal(0xca5e2a006234f169, s.Struct) |
2656 | + return str |
2657 | +} |
2658 | + |
2659 | +func (s InterfaceDetails) MacAddress() (string, error) { |
2660 | + p, err := s.Struct.Ptr(0) |
2661 | + return p.Text(), err |
2662 | +} |
2663 | + |
2664 | +func (s InterfaceDetails) HasMacAddress() bool { |
2665 | + return s.Struct.HasPtr(0) |
2666 | +} |
2667 | + |
2668 | +func (s InterfaceDetails) MacAddressBytes() ([]byte, error) { |
2669 | + p, err := s.Struct.Ptr(0) |
2670 | + return p.TextBytes(), err |
2671 | +} |
2672 | + |
2673 | +func (s InterfaceDetails) SetMacAddress(v string) error { |
2674 | + return s.Struct.SetText(0, v) |
2675 | +} |
2676 | + |
2677 | +func (s InterfaceDetails) Type() (string, error) { |
2678 | + p, err := s.Struct.Ptr(1) |
2679 | + return p.Text(), err |
2680 | +} |
2681 | + |
2682 | +func (s InterfaceDetails) HasType() bool { |
2683 | + return s.Struct.HasPtr(1) |
2684 | +} |
2685 | + |
2686 | +func (s InterfaceDetails) TypeBytes() ([]byte, error) { |
2687 | + p, err := s.Struct.Ptr(1) |
2688 | + return p.TextBytes(), err |
2689 | +} |
2690 | + |
2691 | +func (s InterfaceDetails) SetType(v string) error { |
2692 | + return s.Struct.SetText(1, v) |
2693 | +} |
2694 | + |
2695 | +func (s InterfaceDetails) Links() (Link_List, error) { |
2696 | + p, err := s.Struct.Ptr(2) |
2697 | + return Link_List{List: p.List()}, err |
2698 | +} |
2699 | + |
2700 | +func (s InterfaceDetails) HasLinks() bool { |
2701 | + return s.Struct.HasPtr(2) |
2702 | +} |
2703 | + |
2704 | +func (s InterfaceDetails) SetLinks(v Link_List) error { |
2705 | + return s.Struct.SetPtr(2, v.List.ToPtr()) |
2706 | +} |
2707 | + |
2708 | +// NewLinks sets the links field to a newly |
2709 | +// allocated Link_List, preferring placement in s's segment. |
2710 | +func (s InterfaceDetails) NewLinks(n int32) (Link_List, error) { |
2711 | + l, err := NewLink_List(s.Struct.Segment(), n) |
2712 | + if err != nil { |
2713 | + return Link_List{}, err |
2714 | + } |
2715 | + err = s.Struct.SetPtr(2, l.List.ToPtr()) |
2716 | + return l, err |
2717 | +} |
2718 | + |
2719 | +func (s InterfaceDetails) Vid() uint64 { |
2720 | + return s.Struct.Uint64(0) |
2721 | +} |
2722 | + |
2723 | +func (s InterfaceDetails) SetVid(v uint64) { |
2724 | + s.Struct.SetUint64(0, v) |
2725 | +} |
2726 | + |
2727 | +func (s InterfaceDetails) Enabled() bool { |
2728 | + return s.Struct.Bit(64) |
2729 | +} |
2730 | + |
2731 | +func (s InterfaceDetails) SetEnabled(v bool) { |
2732 | + s.Struct.SetBit(64, v) |
2733 | +} |
2734 | + |
2735 | +func (s InterfaceDetails) Parents() (capnp.TextList, error) { |
2736 | + p, err := s.Struct.Ptr(3) |
2737 | + return capnp.TextList{List: p.List()}, err |
2738 | +} |
2739 | + |
2740 | +func (s InterfaceDetails) HasParents() bool { |
2741 | + return s.Struct.HasPtr(3) |
2742 | +} |
2743 | + |
2744 | +func (s InterfaceDetails) SetParents(v capnp.TextList) error { |
2745 | + return s.Struct.SetPtr(3, v.List.ToPtr()) |
2746 | +} |
2747 | + |
2748 | +// NewParents sets the parents field to a newly |
2749 | +// allocated capnp.TextList, preferring placement in s's segment. |
2750 | +func (s InterfaceDetails) NewParents(n int32) (capnp.TextList, error) { |
2751 | + l, err := capnp.NewTextList(s.Struct.Segment(), n) |
2752 | + if err != nil { |
2753 | + return capnp.TextList{}, err |
2754 | + } |
2755 | + err = s.Struct.SetPtr(3, l.List.ToPtr()) |
2756 | + return l, err |
2757 | +} |
2758 | + |
2759 | +// InterfaceDetails_List is a list of InterfaceDetails. |
2760 | +type InterfaceDetails_List struct{ capnp.List } |
2761 | + |
2762 | +// NewInterfaceDetails creates a new list of InterfaceDetails. |
2763 | +func NewInterfaceDetails_List(s *capnp.Segment, sz int32) (InterfaceDetails_List, error) { |
2764 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 4}, sz) |
2765 | + return InterfaceDetails_List{l}, err |
2766 | +} |
2767 | + |
2768 | +func (s InterfaceDetails_List) At(i int) InterfaceDetails { return InterfaceDetails{s.List.Struct(i)} } |
2769 | + |
2770 | +func (s InterfaceDetails_List) Set(i int, v InterfaceDetails) error { |
2771 | + return s.List.SetStruct(i, v.Struct) |
2772 | +} |
2773 | + |
2774 | +func (s InterfaceDetails_List) String() string { |
2775 | + str, _ := text.MarshalList(0xca5e2a006234f169, s.List) |
2776 | + return str |
2777 | +} |
2778 | + |
2779 | +// InterfaceDetails_Future is a wrapper for a InterfaceDetails promised by a client call. |
2780 | +type InterfaceDetails_Future struct{ *capnp.Future } |
2781 | + |
2782 | +func (p InterfaceDetails_Future) Struct() (InterfaceDetails, error) { |
2783 | + s, err := p.Future.Struct() |
2784 | + return InterfaceDetails{s}, err |
2785 | +} |
2786 | + |
2787 | +type Interface struct{ capnp.Struct } |
2788 | + |
2789 | +// Interface_TypeID is the unique identifier for the type Interface. |
2790 | +const Interface_TypeID = 0x929a2663d1c662e2 |
2791 | + |
2792 | +func NewInterface(s *capnp.Segment) (Interface, error) { |
2793 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) |
2794 | + return Interface{st}, err |
2795 | +} |
2796 | + |
2797 | +func NewRootInterface(s *capnp.Segment) (Interface, error) { |
2798 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) |
2799 | + return Interface{st}, err |
2800 | +} |
2801 | + |
2802 | +func ReadRootInterface(msg *capnp.Message) (Interface, error) { |
2803 | + root, err := msg.Root() |
2804 | + return Interface{root.Struct()}, err |
2805 | +} |
2806 | + |
2807 | +func (s Interface) String() string { |
2808 | + str, _ := text.Marshal(0x929a2663d1c662e2, s.Struct) |
2809 | + return str |
2810 | +} |
2811 | + |
2812 | +func (s Interface) Name() (string, error) { |
2813 | + p, err := s.Struct.Ptr(0) |
2814 | + return p.Text(), err |
2815 | +} |
2816 | + |
2817 | +func (s Interface) HasName() bool { |
2818 | + return s.Struct.HasPtr(0) |
2819 | +} |
2820 | + |
2821 | +func (s Interface) NameBytes() ([]byte, error) { |
2822 | + p, err := s.Struct.Ptr(0) |
2823 | + return p.TextBytes(), err |
2824 | +} |
2825 | + |
2826 | +func (s Interface) SetName(v string) error { |
2827 | + return s.Struct.SetText(0, v) |
2828 | +} |
2829 | + |
2830 | +func (s Interface) Iface() (InterfaceDetails, error) { |
2831 | + p, err := s.Struct.Ptr(1) |
2832 | + return InterfaceDetails{Struct: p.Struct()}, err |
2833 | +} |
2834 | + |
2835 | +func (s Interface) HasIface() bool { |
2836 | + return s.Struct.HasPtr(1) |
2837 | +} |
2838 | + |
2839 | +func (s Interface) SetIface(v InterfaceDetails) error { |
2840 | + return s.Struct.SetPtr(1, v.Struct.ToPtr()) |
2841 | +} |
2842 | + |
2843 | +// NewIface sets the iface field to a newly |
2844 | +// allocated InterfaceDetails struct, preferring placement in s's segment. |
2845 | +func (s Interface) NewIface() (InterfaceDetails, error) { |
2846 | + ss, err := NewInterfaceDetails(s.Struct.Segment()) |
2847 | + if err != nil { |
2848 | + return InterfaceDetails{}, err |
2849 | + } |
2850 | + err = s.Struct.SetPtr(1, ss.Struct.ToPtr()) |
2851 | + return ss, err |
2852 | +} |
2853 | + |
2854 | +// Interface_List is a list of Interface. |
2855 | +type Interface_List struct{ capnp.List } |
2856 | + |
2857 | +// NewInterface creates a new list of Interface. |
2858 | +func NewInterface_List(s *capnp.Segment, sz int32) (Interface_List, error) { |
2859 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz) |
2860 | + return Interface_List{l}, err |
2861 | +} |
2862 | + |
2863 | +func (s Interface_List) At(i int) Interface { return Interface{s.List.Struct(i)} } |
2864 | + |
2865 | +func (s Interface_List) Set(i int, v Interface) error { return s.List.SetStruct(i, v.Struct) } |
2866 | + |
2867 | +func (s Interface_List) String() string { |
2868 | + str, _ := text.MarshalList(0x929a2663d1c662e2, s.List) |
2869 | + return str |
2870 | +} |
2871 | + |
2872 | +// Interface_Future is a wrapper for a Interface promised by a client call. |
2873 | +type Interface_Future struct{ *capnp.Future } |
2874 | + |
2875 | +func (p Interface_Future) Struct() (Interface, error) { |
2876 | + s, err := p.Future.Struct() |
2877 | + return Interface{s}, err |
2878 | +} |
2879 | + |
2880 | +func (p Interface_Future) Iface() InterfaceDetails_Future { |
2881 | + return InterfaceDetails_Future{Future: p.Future.Field(1, nil)} |
2882 | +} |
2883 | + |
2884 | +type Interfaces struct{ capnp.Struct } |
2885 | + |
2886 | +// Interfaces_TypeID is the unique identifier for the type Interfaces. |
2887 | +const Interfaces_TypeID = 0x826b9c4ff97d4a43 |
2888 | + |
2889 | +func NewInterfaces(s *capnp.Segment) (Interfaces, error) { |
2890 | + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2891 | + return Interfaces{st}, err |
2892 | +} |
2893 | + |
2894 | +func NewRootInterfaces(s *capnp.Segment) (Interfaces, error) { |
2895 | + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) |
2896 | + return Interfaces{st}, err |
2897 | +} |
2898 | + |
2899 | +func ReadRootInterfaces(msg *capnp.Message) (Interfaces, error) { |
2900 | + root, err := msg.Root() |
2901 | + return Interfaces{root.Struct()}, err |
2902 | +} |
2903 | + |
2904 | +func (s Interfaces) String() string { |
2905 | + str, _ := text.Marshal(0x826b9c4ff97d4a43, s.Struct) |
2906 | + return str |
2907 | +} |
2908 | + |
2909 | +func (s Interfaces) Ifaces() (Interface_List, error) { |
2910 | + p, err := s.Struct.Ptr(0) |
2911 | + return Interface_List{List: p.List()}, err |
2912 | +} |
2913 | + |
2914 | +func (s Interfaces) HasIfaces() bool { |
2915 | + return s.Struct.HasPtr(0) |
2916 | +} |
2917 | + |
2918 | +func (s Interfaces) SetIfaces(v Interface_List) error { |
2919 | + return s.Struct.SetPtr(0, v.List.ToPtr()) |
2920 | +} |
2921 | + |
2922 | +// NewIfaces sets the ifaces field to a newly |
2923 | +// allocated Interface_List, preferring placement in s's segment. |
2924 | +func (s Interfaces) NewIfaces(n int32) (Interface_List, error) { |
2925 | + l, err := NewInterface_List(s.Struct.Segment(), n) |
2926 | + if err != nil { |
2927 | + return Interface_List{}, err |
2928 | + } |
2929 | + err = s.Struct.SetPtr(0, l.List.ToPtr()) |
2930 | + return l, err |
2931 | +} |
2932 | + |
2933 | +// Interfaces_List is a list of Interfaces. |
2934 | +type Interfaces_List struct{ capnp.List } |
2935 | + |
2936 | +// NewInterfaces creates a new list of Interfaces. |
2937 | +func NewInterfaces_List(s *capnp.Segment, sz int32) (Interfaces_List, error) { |
2938 | + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) |
2939 | + return Interfaces_List{l}, err |
2940 | +} |
2941 | + |
2942 | +func (s Interfaces_List) At(i int) Interfaces { return Interfaces{s.List.Struct(i)} } |
2943 | + |
2944 | +func (s Interfaces_List) Set(i int, v Interfaces) error { return s.List.SetStruct(i, v.Struct) } |
2945 | + |
2946 | +func (s Interfaces_List) String() string { |
2947 | + str, _ := text.MarshalList(0x826b9c4ff97d4a43, s.List) |
2948 | + return str |
2949 | +} |
2950 | + |
2951 | +// Interfaces_Future is a wrapper for a Interfaces promised by a client call. |
2952 | +type Interfaces_Future struct{ *capnp.Future } |
2953 | + |
2954 | +func (p Interfaces_Future) Struct() (Interfaces, error) { |
2955 | + s, err := p.Future.Struct() |
2956 | + return Interfaces{s}, err |
2957 | +} |
2958 | + |
2959 | +const schema_dae346a935a6f239 = "x\xda|\x921h\x14O\x18\xc5\xdf\x9b\xd9\xfb'\x81" + |
2960 | + "\xfc/\xb7\xde\x15\x82\x85\"Q4\x18\x89\x1a\x0b\xd3$" + |
2961 | + "F\x11\"\x82\xf9\x0a\x11D\x82\x93\xdb\xd1,w\xb79" + |
2962 | + "\xee\x16C@9\x14,l\xad4\xa4PP\xd1\xde\xc2" + |
2963 | + "@\x04#j \x9d\x9d\xd8\xa9\x88X\x89v\xda\xac\xcc" + |
2964 | + "\x06\xf7\x16A\xbb\x9d\xc7o\xbf\xf7\xde|32\xc9\x09" + |
2965 | + "u\xa0\xb0\xae\x00\xd9Q\xf8/9v\xf2\xea\x8f\xd3\xcb" + |
2966 | + "\xb5\xeb\xf0\x8bL\x8e|\x7fx\xf8\xf1\x89\x8f\xefP`" + |
2967 | + "\x0fP\x9e\xe2F\xf9L\xfa%\x1c\x07\x93\x0f\xb3\xaf\xdf" + |
2968 | + "Tw/\xdd\xfa\x83U\x8e\xb8\xc6\x17\xe5\x9b){\x83" + |
2969 | + "\x0b`\x12\xcdl\xd9we\xdb\xaeuH\x91yX;" + |
2970 | + "\xe4=\x97\xca_R\xf8\x13?\x83_\xc3o\xa3\xb3C" + |
2971 | + "3\x1bR\xa4\xca\xa1\x9e\x03V\xd4\xcf\xf2+\xe7ph" + |
2972 | + "M\x9d%\x86\x93\xc8\xc6\x0b\xf3\xad\xda~U5\xcd\xa8" + |
2973 | + "96\x15\xc5\xb6u\xd1Tm\x1b\x98&\xc5\xd3\x1e\xe0" + |
2974 | + "\x11\xf0\xff\x1f\x03\xa4WS\x06\x15\xc7\xc3\x14a\x11\x9c" + |
2975 | + "\xd6d\xa9[\x05t\xe2_\xa7\xa63{\xb3\x99{\x87" + |
2976 | + "\x00\x19\xd4\x94\x11E\x9f\xac\xd0\x89\xc3\x07\x01\xd9\xa3)" + |
2977 | + "\xa3\x8a\x03\x91iX\xf6C\xb1\x1f\xdc\x9e\xba\xb2\xf4\xbb" + |
2978 | + "\x1f\xc8R\xce\x8b\x9b^\xa7B\x1d\xd5\x9cM)\xb31" + |
2979 | + "\xce\xe6\xbc\xa6\xcc\xe5l\xec$ \x174\xa5\xae\xe8+" + |
2980 | + "U\xa1\x02\xfc\xd0\x89\x81\xa64\x15\xa9+\xd4\x80\xdfp" + |
2981 | + "\xda\x9c\xa6\xc4\x8a\x03\x8d\xf9 \xcb\xd31A\xd0\xb2\xed" + |
2982 | + "vv\xbedb\xbb`\x16\xb3sd\xe3\x86i\xd7\xe8" + |
2983 | + "A\xd1\xfb\xc7\xad\x1c\x1f\xb7\xb1\x09\xebm\x97zk\x96" + |
2984 | + "\xfa\xce9@nk\xca\xfd\\\xea{\xae\xca\xb2\xa6<" + |
2985 | + "\xca\xa5~\xe0n\xec\xae\xa6\xacvS\xaf\xec\x04\xe4\x89" + |
2986 | + "\xa6<W\xf4\xbd\x89\x0a=\xc0\x7f\xe6\xaa<\xd5\x94\x97" + |
2987 | + "\x8a~AWX\x00\xfc5'\xaej\xca[\xc5\xa4a" + |
2988 | + "\xaaG]+\xe8n\xaf\x81x\xb1\xd9]B=\x8cj" + |
2989 | + "\xb9\xcdg\x0fss\xf3=\x97\xc3\x80}P\xec\x03;" + |
2990 | + "62\xb3u\x1b\x90P$\xd8i\x9a\x96\x8d\xe2\xecg" + |
2991 | + "7\xb1\x08\xfe\x0a\x00\x00\xff\xff\x8c{\xba\xe7" |
2992 | + |
2993 | +func init() { |
2994 | + schemas.Register(schema_dae346a935a6f239, |
2995 | + 0x826b9c4ff97d4a43, |
2996 | + 0x929a2663d1c662e2, |
2997 | + 0xc7251b7c2c125e6e, |
2998 | + 0xca5e2a006234f169) |
2999 | +} |
3000 | diff --git a/src/rpc/go.capnp b/src/rpc/go.capnp |
3001 | new file mode 100644 |
3002 | index 0000000..4072b57 |
3003 | --- /dev/null |
3004 | +++ b/src/rpc/go.capnp |
3005 | @@ -0,0 +1,27 @@ |
3006 | +@0xd12a1c51fedd6c88; |
3007 | + |
3008 | +annotation package(file) :Text; |
3009 | +# The Go package name for the generated file. |
3010 | + |
3011 | +annotation import(file) :Text; |
3012 | +# The Go import path that the generated file is accessible from. |
3013 | +# Used to generate import statements and check if two types are in the |
3014 | +# same package. |
3015 | + |
3016 | +annotation doc(struct, field, enum) :Text; |
3017 | +# Adds a doc comment to the generated code. |
3018 | + |
3019 | +annotation tag(enumerant) :Text; |
3020 | +# Changes the string representation of the enum in the generated code. |
3021 | + |
3022 | +annotation notag(enumerant) :Void; |
3023 | +# Removes the string representation of the enum in the generated code. |
3024 | + |
3025 | +annotation customtype(field) :Text; |
3026 | +# OBSOLETE, not used by code generator. |
3027 | + |
3028 | +annotation name(struct, field, union, enum, enumerant, interface, method, param, annotation, const, group) :Text; |
3029 | +# Used to rename the element in the generated code. |
3030 | + |
3031 | +$package("gocp"); |
3032 | +$import("capnproto.org/go/capnp/v3/std/go"); |
3033 | diff --git a/src/rpc/handshake.capnp b/src/rpc/handshake.capnp |
3034 | new file mode 100644 |
3035 | index 0000000..dc87b67 |
3036 | --- /dev/null |
3037 | +++ b/src/rpc/handshake.capnp |
3038 | @@ -0,0 +1,36 @@ |
3039 | +@0xdceab81b996ed67b; |
3040 | + |
3041 | +using Go = import "go.capnp"; |
3042 | +$Go.package("rpc"); |
3043 | +$Go.import("rpc"); |
3044 | + |
3045 | +using Network = import "network.capnp"; |
3046 | + |
3047 | +struct AuthResponse { |
3048 | + salt @0 :Data; |
3049 | + digest @1 :Data; |
3050 | +} |
3051 | + |
3052 | +interface Authenticator { |
3053 | + authenticate @0 (msg :Data) -> (resp :AuthResponse); |
3054 | +} |
3055 | + |
3056 | +struct RegisterRequest { |
3057 | + systemId @0 :Text; |
3058 | + hostname @1 :Text; |
3059 | + interfaces @2 :Network.Interfaces; |
3060 | + url @3 :Text; |
3061 | + nodegroup @4 :Text; |
3062 | + beaconSupport @5 :Bool; |
3063 | + version @6 :Text; |
3064 | +} |
3065 | + |
3066 | +struct RegisterResponse { |
3067 | + systemId @0 :Text; |
3068 | + uuid @1 :Text; |
3069 | + version @2 :Text; |
3070 | +} |
3071 | + |
3072 | +interface Registerer { |
3073 | + register @0 (req :RegisterRequest) -> (resp :RegisterResponse); |
3074 | +} |
3075 | diff --git a/src/rpc/network.capnp b/src/rpc/network.capnp |
3076 | new file mode 100644 |
3077 | index 0000000..5e719c9 |
3078 | --- /dev/null |
3079 | +++ b/src/rpc/network.capnp |
3080 | @@ -0,0 +1,30 @@ |
3081 | +@0xdae346a935a6f239; |
3082 | + |
3083 | +using Go = import "go.capnp"; |
3084 | +$Go.package("rpc"); |
3085 | +$Go.import("rpc"); |
3086 | + |
3087 | +struct Link { |
3088 | + mode @0 :Text; |
3089 | + address @1 :Text; |
3090 | + gateway @2 :Text; |
3091 | + netmask @3 :Int32; |
3092 | +} |
3093 | + |
3094 | +struct InterfaceDetails { |
3095 | + macAddress @0 :Text; |
3096 | + type @1 :Text; |
3097 | + links @2 :List(Link); |
3098 | + vid @3 :UInt64; |
3099 | + enabled @4 :Bool; |
3100 | + parents @5 :List(Text); |
3101 | +} |
3102 | + |
3103 | +struct Interface { |
3104 | + name @0 :Text; |
3105 | + iface @1 :InterfaceDetails; |
3106 | +} |
3107 | + |
3108 | +struct Interfaces { |
3109 | + ifaces @0 :List(Interface); |
3110 | +} |
UNIT TESTS exploration lp:~maas-committers/maas
-b rpc_client_server lp:~cgrabowski/maas/+git/maas into -b rack_region_
STATUS: SUCCESS 6ac5a4d5130940e 457ccd5ed9
COMMIT: b8a28beb8353fa6