From fe0a0eccd9271c77854bae480006fc09d7b3d6bb Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Thu, 25 Aug 2022 22:50:57 -0400 Subject: [PATCH 01/32] add tls cert generation and buildkit host-side dns it was either this or support host networking, which turned out to be a rat's nest. this feels more generally useful, but the story is a little incomplete; host->thunk uses a trusted CA, but there's no magic CA trusting for thunk->thunk yet. --- bass/buildkit.bass | 11 +- cmd/bass/main.go | 7 + go.mod | 8 + go.sum | 36 + pkg/bass/encoding_test.go | 4 + pkg/bass/ground.go | 5 + pkg/bass/proto.go | 17 + pkg/bass/thunk.go | 30 + pkg/basstls/basstls.go | 125 ++++ pkg/proto/bass.pb.go | 797 +++++++++++++---------- pkg/runtimes/buildkit.go | 35 + pkg/runtimes/command_test.go | 8 + pkg/runtimes/util/buildkitd/buildkitd.go | 56 +- proto/bass.proto | 6 + 14 files changed, 775 insertions(+), 370 deletions(-) create mode 100644 pkg/basstls/basstls.go diff --git a/bass/buildkit.bass b/bass/buildkit.bass index 8be7963a..129260ed 100644 --- a/bass/buildkit.bass +++ b/bass/buildkit.bass @@ -20,7 +20,7 @@ ($ tar -zxf (cni os arch) -C /opt/cni/bin/) ($ sh -c "cp $0/* /etc/buildkit/" $config-dir))) - (defn buildkitd-toml [cni-path dns] + (defn buildkitd-toml [cni-path] (str "# support insecure! thunks\n" "insecure-entitlements = [ \"security.insecure\" ]\n" @@ -32,10 +32,7 @@ "\n" "[worker.containerd]\n" "networkMode = \"cni\"\n" - "cniConfigPath = \"" (/etc/buildkit/ cni-path) "\"\n" - "\n" - "[dns]\n" - "nameservers = [\"" dns "\"]\n")) + "cniConfigPath = \"" (/etc/buildkit/ cni-path) "\"\n")) (def dnsname (subpath @@ -76,9 +73,9 @@ (def bass-config (mkfs ./bass.conflist (json (cni-config "bass" "10.64.0.0/16")) - ./buildkitd.toml (buildkitd-toml ./bass.conflist "10.64.0.1"))) + ./buildkitd.toml (buildkitd-toml ./bass.conflist))) (def test-config (mkfs ./test.conflist (json (cni-config "bass" "10.73.0.0/16")) - ./buildkitd.toml (buildkitd-toml ./test.conflist "10.73.0.1")))) + ./buildkitd.toml (buildkitd-toml ./test.conflist)))) diff --git a/cmd/bass/main.go b/cmd/bass/main.go index bb742946..9d963073 100644 --- a/cmd/bass/main.go +++ b/cmd/bass/main.go @@ -12,6 +12,7 @@ import ( flag "github.com/spf13/pflag" "github.com/vito/bass/pkg/bass" + "github.com/vito/bass/pkg/basstls" "github.com/vito/bass/pkg/cli" "github.com/vito/bass/pkg/ioctx" "github.com/vito/bass/pkg/runtimes" @@ -149,6 +150,12 @@ func root(ctx context.Context) error { return err } + err = basstls.Init() + if err != nil { + cli.WriteError(ctx, err) + return err + } + pool, err := runtimes.NewPool(ctx, config) if err != nil { cli.WriteError(ctx, err) diff --git a/go.mod b/go.mod index 01208ae0..4690e89a 100644 --- a/go.mod +++ b/go.mod @@ -54,6 +54,7 @@ require ( require ( cloud.google.com/go v0.81.0 // indirect + filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/AdamKorcz/go-fuzz-headers v0.0.0-20210312213058-32f4d319f0d2 // indirect github.com/Microsoft/go-winio v0.5.1 // indirect github.com/apex/log v1.4.0 // indirect @@ -64,6 +65,7 @@ require ( github.com/containerd/continuity v0.2.3-0.20220330195504-d132b287edc8 // indirect github.com/containerd/go-runc v1.0.0 // indirect github.com/containerd/typeurl v1.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/creack/pty v1.1.11 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect @@ -84,6 +86,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c // indirect github.com/jessevdk/go-flags v1.4.0 // indirect github.com/klauspost/compress v1.15.1 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect @@ -104,16 +107,21 @@ require ( github.com/pkg/term v1.2.0-beta.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rootless-containers/proto v0.1.0 // indirect + github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/sergi/go-diff v1.1.0 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect + github.com/square/certstrap v1.3.0 // indirect github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274 // indirect github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect + github.com/urfave/cli v1.22.9 // indirect github.com/vbatts/go-mtree v0.5.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect go.opentelemetry.io/otel/sdk v1.4.1 // indirect go.opentelemetry.io/otel/trace v1.4.1 // indirect go.opentelemetry.io/proto/otlp v0.12.0 // indirect + go.step.sm/crypto v0.16.2 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/goleak v1.1.12 // indirect go.uber.org/multierr v1.6.0 // indirect diff --git a/go.sum b/go.sum index 88e07090..744f5904 100644 --- a/go.sum +++ b/go.sum @@ -39,10 +39,15 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= github.com/AdamKorcz/go-fuzz-headers v0.0.0-20210312213058-32f4d319f0d2 h1:dIxAd7URQa+ovSiQURY3UJu8Q7A2dG7QKTlxOlvDZHI= github.com/AdamKorcz/go-fuzz-headers v0.0.0-20210312213058-32f4d319f0d2/go.mod h1:VPevheIvXETHZT/ddjwarP3POR5p/cnH9Hy5yoFnQjc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= @@ -131,6 +136,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -253,6 +259,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -276,6 +283,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -297,9 +305,15 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0= +github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -365,10 +379,14 @@ github.com/mattn/go-unicodeclass v0.0.1 h1:BKdh58FOa0n4QRd39jSeVEF7ncxxV3l4GL05L github.com/mattn/go-unicodeclass v0.0.1/go.mod h1:dDCkCgOKUwD3sYX4N+tVQdFh/xlFQ1+cWakbQzy98T8= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063 h1:V7s6vhIrNeOqocziAmRoVJh6gnPPx83ovlpT7Hf5shI= github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063/go.mod h1:rkFeDZ0gc+YbnrXPw0q2RlI0QRuKBBPu67fgYIyGRNg= github.com/moby/buildkit v0.10.3 h1:/dGykD8FW+H4p++q5+KqKEo6gAkYKyBQHdawdjVwVAU= @@ -466,6 +484,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rootless-containers/proto v0.1.0 h1:gS1JOMEtk1YDYHCzBAf/url+olMJbac7MTrgSeP6zh4= github.com/rootless-containers/proto v0.1.0/go.mod h1:vgkUFZbQd0gcE/K/ZwtE4MYjZPu0UNHLXIQxhyqAFh8= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= @@ -475,6 +494,8 @@ github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHW github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -483,6 +504,7 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= @@ -492,6 +514,8 @@ github.com/sourcegraph/jsonrpc2 v0.1.0/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -500,6 +524,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spy16/slurp v0.2.3 h1:NZGZ3MEyd0IUlnauMiGcTJe0DfpE4BVe3SMfdFvdwNU= github.com/spy16/slurp v0.2.3/go.mod h1:Omrszh5Bznh+fhYrxnR4R2XrRKRelPlbY5IwQizOui0= +github.com/square/certstrap v1.3.0 h1:N9P0ZRA+DjT8pq5fGDj0z3FjafRKnBDypP0QHpMlaAk= +github.com/square/certstrap v1.3.0/go.mod h1:wGZo9eE1B7WX2GKBn0htJ+B3OuRl2UsdCFySNooy9hU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -527,6 +553,8 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= +github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vbatts/go-mtree v0.5.0 h1:dM+5XZdqH0j9CSZeerhoN/tAySdwnmevaZHO1XGW2Vc= github.com/vbatts/go-mtree v0.5.0/go.mod h1:7JbaNHyBMng+RP8C3Q4E+4Ca8JnGQA2R/MB+jb4tSOk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -581,6 +609,8 @@ go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwY go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= +go.step.sm/crypto v0.16.2 h1:Pr9aazTwWBBZNogUsOqhOrPSdwAa9pPs+lMB602lnDA= +go.step.sm/crypto v0.16.2/go.mod h1:1WkTOTY+fOX/RY4TnZREp6trQAsBHRQ7nu6QJBiNQF8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -599,9 +629,11 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -683,6 +715,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -778,6 +812,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -988,6 +1023,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/pkg/bass/encoding_test.go b/pkg/bass/encoding_test.go index 30fc670b..cf4cf9b1 100644 --- a/pkg/bass/encoding_test.go +++ b/pkg/bass/encoding_test.go @@ -126,6 +126,10 @@ var validThiccThunk = bass.Thunk{ {"http", 80}, {"ssh", 22}, }, + TLS: &bass.ThunkTLS{ + Cert: bass.FilePath{"cert"}, + Key: bass.FilePath{"key"}, + }, } var validThunkImages = []bass.ThunkImage{ diff --git a/pkg/bass/ground.go b/pkg/bass/ground.go index 2edea47f..e0d65762 100644 --- a/pkg/bass/ground.go +++ b/pkg/bass/ground.go @@ -696,6 +696,11 @@ func init() { `returns thunk with a named port appended to its ports`, `=> (with-port ($ godoc -http=:6060) :godoc 6060)`) + Ground.Set("with-tls", + Func("with-tls", "[thunk cert-path key-path]", (Thunk).WithTLS), + `returns thunk with paths to a TLS certificate and key to generate`, + `=> (with-tls ($ godoc -http=:6060) ./cert.pem ./key.pem)`) + Ground.Set("with-mount", Func("with-mount", "[thunk source target]", (Thunk).WithMount), `returns thunk with a mount from source to the target path`, diff --git a/pkg/bass/proto.go b/pkg/bass/proto.go index 63fc751a..9cfad56a 100644 --- a/pkg/bass/proto.go +++ b/pkg/bass/proto.go @@ -415,6 +415,23 @@ func (value Thunk) MarshalProto() (proto.Message, error) { }) } + if value.TLS != nil { + cert, err := value.TLS.Cert.MarshalProto() + if err != nil { + return nil, fmt.Errorf("marshal cert: %w", err) + } + + key, err := value.TLS.Key.MarshalProto() + if err != nil { + return nil, fmt.Errorf("marshal cert: %w", err) + } + + thunk.Tls = &proto.ThunkTLS{ + Cert: cert.(*proto.FilePath), + Key: key.(*proto.FilePath), + } + } + return thunk, nil } diff --git a/pkg/bass/thunk.go b/pkg/bass/thunk.go index efaf8ac8..825ae3c5 100644 --- a/pkg/bass/thunk.go +++ b/pkg/bass/thunk.go @@ -75,6 +75,9 @@ type Thunk struct { // thunk its embedded thunk will be started and all ports will be polled // until they are listening. Ports []ThunkPort `json:"ports,omitempty"` + + // TLS configures paths to place generated certificates. + TLS *ThunkTLS `json:"tls,omitempty"` } type ThunkPort struct { @@ -82,6 +85,11 @@ type ThunkPort struct { Port int `json:"port"` } +type ThunkTLS struct { + Cert FilePath `json:"cert"` + Key FilePath `json:"key"` +} + func (thunk *Thunk) UnmarshalProto(msg proto.Message) error { p, ok := msg.(*proto.Thunk) if !ok { @@ -172,6 +180,19 @@ func (thunk *Thunk) UnmarshalProto(msg proto.Message) error { } } + if p.Tls != nil { + thunk.TLS = &ThunkTLS{} + err := thunk.TLS.Cert.UnmarshalProto(p.Tls.Cert) + if err != nil { + return fmt.Errorf("unmarshal cert: %w", err) + } + + err = thunk.TLS.Key.UnmarshalProto(p.Tls.Key) + if err != nil { + return fmt.Errorf("unmarshal key: %w", err) + } + } + return nil } @@ -430,6 +451,15 @@ func (thunk Thunk) WithPort(name Symbol, port int) Thunk { return thunk } +// WithTLS configures the thunk with TLS. +func (thunk Thunk) WithTLS(cert, key FilePath) Thunk { + thunk.TLS = &ThunkTLS{ + Cert: cert, + Key: key, + } + return thunk +} + var _ Value = Thunk{} func (thunk Thunk) String() string { diff --git a/pkg/basstls/basstls.go b/pkg/basstls/basstls.go new file mode 100644 index 00000000..5a9faefe --- /dev/null +++ b/pkg/basstls/basstls.go @@ -0,0 +1,125 @@ +package basstls + +import ( + "fmt" + "path/filepath" + "time" + + "github.com/adrg/xdg" + "github.com/square/certstrap/depot" + "github.com/square/certstrap/pkix" +) + +const ( + // Common name for the certificate authority. + CAName = "bass" + + CACountry = "CA" + CAProvince = "Ontario" + CALocality = "Toronto" + + // RSA key bits. + keySize = 2048 +) + +var ( + Dir = filepath.Join(xdg.ConfigHome, "bass", "tls") + CACert = filepath.Join(Dir, CAName+".crt") +) + +// Init initializes dir with a CA. +func Init() error { + d, err := depot.NewFileDepot(Dir) + if err != nil { + return fmt.Errorf("init depot: %w", err) + } + + _, err = depot.GetCertificate(d, CAName) + if err == nil { + // cert already exists + return nil + } + + key, err := pkix.CreateRSAKey(keySize) + if err != nil { + return fmt.Errorf("create key: %w", err) + } + + // TODO(vito): rotate rather than adding a ridiculous amount of time? + expiry := time.Now().AddDate(0, 0, 64) + + crt, err := pkix.CreateCertificateAuthority( + key, + "", + expiry, + "", + CACountry, + CAProvince, + CALocality, + CAName, + nil, + ) + if err != nil { + return fmt.Errorf("create ca: %w", err) + } + + err = depot.PutPrivateKey(d, CAName, key) + if err != nil { + return fmt.Errorf("put ca: %w", err) + } + + err = depot.PutCertificate(d, CAName, crt) + if err != nil { + return fmt.Errorf("put ca: %w", err) + } + + return nil +} + +func Generate(host string) (*pkix.Certificate, *pkix.Key, error) { + d, err := depot.NewFileDepot(Dir) + if err != nil { + return nil, nil, fmt.Errorf("init depot: %w", err) + } + + caCrt, err := depot.GetCertificate(d, CAName) + if err != nil { + return nil, nil, fmt.Errorf("get cert: %w", err) + } + + caKey, err := depot.GetPrivateKey(d, CAName) + if err != nil { + return nil, nil, fmt.Errorf("get key: %w", err) + } + + key, err := pkix.CreateRSAKey(keySize) + if err != nil { + return nil, nil, fmt.Errorf("create key: %w", err) + } + + csr, err := pkix.CreateCertificateSigningRequest( + key, + "", // Organizational Unit + nil, // IPs + []string{host}, // Domains + nil, // URLs + "", // Organization + CACountry, + CAProvince, + CALocality, + host, + ) + if err != nil { + return nil, nil, fmt.Errorf("create csr: %w", err) + } + + // TODO(vito): rotate rather than adding a ridiculous amount of time? + expiry := time.Now().AddDate(0, 0, 64) + + crt, err := pkix.CreateCertificateHost(caCrt, caKey, csr, expiry) + if err != nil { + return nil, nil, fmt.Errorf("create cert: %w", err) + } + + return crt, key, nil +} diff --git a/pkg/proto/bass.pb.go b/pkg/proto/bass.pb.go index 68c448eb..575095eb 100644 --- a/pkg/proto/bass.pb.go +++ b/pkg/proto/bass.pb.go @@ -297,6 +297,7 @@ type Thunk struct { Mounts []*ThunkMount `protobuf:"bytes,8,rep,name=mounts,proto3" json:"mounts,omitempty"` Labels []*Binding `protobuf:"bytes,9,rep,name=labels,proto3" json:"labels,omitempty"` Ports []*ThunkPort `protobuf:"bytes,10,rep,name=ports,proto3" json:"ports,omitempty"` + Tls *ThunkTLS `protobuf:"bytes,11,opt,name=tls,proto3" json:"tls,omitempty"` } func (x *Thunk) Reset() { @@ -401,6 +402,13 @@ func (x *Thunk) GetPorts() []*ThunkPort { return nil } +func (x *Thunk) GetTls() *ThunkTLS { + if x != nil { + return x.Tls + } + return nil +} + type ThunkAddr struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -519,6 +527,61 @@ func (x *ThunkPort) GetPort() int32 { return 0 } +type ThunkTLS struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cert *FilePath `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"` + Key *FilePath `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *ThunkTLS) Reset() { + *x = ThunkTLS{} + if protoimpl.UnsafeEnabled { + mi := &file_bass_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThunkTLS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunkTLS) ProtoMessage() {} + +func (x *ThunkTLS) ProtoReflect() protoreflect.Message { + mi := &file_bass_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunkTLS.ProtoReflect.Descriptor instead. +func (*ThunkTLS) Descriptor() ([]byte, []int) { + return file_bass_proto_rawDescGZIP(), []int{4} +} + +func (x *ThunkTLS) GetCert() *FilePath { + if x != nil { + return x.Cert + } + return nil +} + +func (x *ThunkTLS) GetKey() *FilePath { + if x != nil { + return x.Key + } + return nil +} + type ThunkImage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -534,7 +597,7 @@ type ThunkImage struct { func (x *ThunkImage) Reset() { *x = ThunkImage{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[4] + mi := &file_bass_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -547,7 +610,7 @@ func (x *ThunkImage) String() string { func (*ThunkImage) ProtoMessage() {} func (x *ThunkImage) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[4] + mi := &file_bass_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -560,7 +623,7 @@ func (x *ThunkImage) ProtoReflect() protoreflect.Message { // Deprecated: Use ThunkImage.ProtoReflect.Descriptor instead. func (*ThunkImage) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{4} + return file_bass_proto_rawDescGZIP(), []int{5} } func (m *ThunkImage) GetImage() isThunkImage_Image { @@ -631,7 +694,7 @@ type ImageRef struct { func (x *ImageRef) Reset() { *x = ImageRef{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[5] + mi := &file_bass_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -644,7 +707,7 @@ func (x *ImageRef) String() string { func (*ImageRef) ProtoMessage() {} func (x *ImageRef) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[5] + mi := &file_bass_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -657,7 +720,7 @@ func (x *ImageRef) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageRef.ProtoReflect.Descriptor instead. func (*ImageRef) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{5} + return file_bass_proto_rawDescGZIP(), []int{6} } func (m *ImageRef) GetSource() isImageRef_Source { @@ -746,7 +809,7 @@ type ImageArchive struct { func (x *ImageArchive) Reset() { *x = ImageArchive{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[6] + mi := &file_bass_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -759,7 +822,7 @@ func (x *ImageArchive) String() string { func (*ImageArchive) ProtoMessage() {} func (x *ImageArchive) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[6] + mi := &file_bass_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -772,7 +835,7 @@ func (x *ImageArchive) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageArchive.ProtoReflect.Descriptor instead. func (*ImageArchive) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{6} + return file_bass_proto_rawDescGZIP(), []int{7} } func (x *ImageArchive) GetFile() *ThunkPath { @@ -808,7 +871,7 @@ type Platform struct { func (x *Platform) Reset() { *x = Platform{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[7] + mi := &file_bass_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -821,7 +884,7 @@ func (x *Platform) String() string { func (*Platform) ProtoMessage() {} func (x *Platform) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[7] + mi := &file_bass_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -834,7 +897,7 @@ func (x *Platform) ProtoReflect() protoreflect.Message { // Deprecated: Use Platform.ProtoReflect.Descriptor instead. func (*Platform) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{7} + return file_bass_proto_rawDescGZIP(), []int{8} } func (x *Platform) GetOs() string { @@ -869,7 +932,7 @@ type ThunkCmd struct { func (x *ThunkCmd) Reset() { *x = ThunkCmd{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[8] + mi := &file_bass_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -882,7 +945,7 @@ func (x *ThunkCmd) String() string { func (*ThunkCmd) ProtoMessage() {} func (x *ThunkCmd) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[8] + mi := &file_bass_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -895,7 +958,7 @@ func (x *ThunkCmd) ProtoReflect() protoreflect.Message { // Deprecated: Use ThunkCmd.ProtoReflect.Descriptor instead. func (*ThunkCmd) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{8} + return file_bass_proto_rawDescGZIP(), []int{9} } func (m *ThunkCmd) GetCmd() isThunkCmd_Cmd { @@ -1002,7 +1065,7 @@ type ThunkDir struct { func (x *ThunkDir) Reset() { *x = ThunkDir{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[9] + mi := &file_bass_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1015,7 +1078,7 @@ func (x *ThunkDir) String() string { func (*ThunkDir) ProtoMessage() {} func (x *ThunkDir) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[9] + mi := &file_bass_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1028,7 +1091,7 @@ func (x *ThunkDir) ProtoReflect() protoreflect.Message { // Deprecated: Use ThunkDir.ProtoReflect.Descriptor instead. func (*ThunkDir) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{9} + return file_bass_proto_rawDescGZIP(), []int{10} } func (m *ThunkDir) GetDir() isThunkDir_Dir { @@ -1098,7 +1161,7 @@ type ThunkMountSource struct { func (x *ThunkMountSource) Reset() { *x = ThunkMountSource{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[10] + mi := &file_bass_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1111,7 +1174,7 @@ func (x *ThunkMountSource) String() string { func (*ThunkMountSource) ProtoMessage() {} func (x *ThunkMountSource) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[10] + mi := &file_bass_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1124,7 +1187,7 @@ func (x *ThunkMountSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ThunkMountSource.ProtoReflect.Descriptor instead. func (*ThunkMountSource) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{10} + return file_bass_proto_rawDescGZIP(), []int{11} } func (m *ThunkMountSource) GetSource() isThunkMountSource_Source { @@ -1215,7 +1278,7 @@ type ThunkMount struct { func (x *ThunkMount) Reset() { *x = ThunkMount{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[11] + mi := &file_bass_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1228,7 +1291,7 @@ func (x *ThunkMount) String() string { func (*ThunkMount) ProtoMessage() {} func (x *ThunkMount) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[11] + mi := &file_bass_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1241,7 +1304,7 @@ func (x *ThunkMount) ProtoReflect() protoreflect.Message { // Deprecated: Use ThunkMount.ProtoReflect.Descriptor instead. func (*ThunkMount) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{11} + return file_bass_proto_rawDescGZIP(), []int{12} } func (x *ThunkMount) GetSource() *ThunkMountSource { @@ -1269,7 +1332,7 @@ type Array struct { func (x *Array) Reset() { *x = Array{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[12] + mi := &file_bass_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1282,7 +1345,7 @@ func (x *Array) String() string { func (*Array) ProtoMessage() {} func (x *Array) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[12] + mi := &file_bass_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1295,7 +1358,7 @@ func (x *Array) ProtoReflect() protoreflect.Message { // Deprecated: Use Array.ProtoReflect.Descriptor instead. func (*Array) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{12} + return file_bass_proto_rawDescGZIP(), []int{13} } func (x *Array) GetValues() []*Value { @@ -1316,7 +1379,7 @@ type Object struct { func (x *Object) Reset() { *x = Object{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[13] + mi := &file_bass_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1329,7 +1392,7 @@ func (x *Object) String() string { func (*Object) ProtoMessage() {} func (x *Object) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[13] + mi := &file_bass_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1342,7 +1405,7 @@ func (x *Object) ProtoReflect() protoreflect.Message { // Deprecated: Use Object.ProtoReflect.Descriptor instead. func (*Object) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{13} + return file_bass_proto_rawDescGZIP(), []int{14} } func (x *Object) GetBindings() []*Binding { @@ -1364,7 +1427,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[14] + mi := &file_bass_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1377,7 +1440,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[14] + mi := &file_bass_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1390,7 +1453,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{14} + return file_bass_proto_rawDescGZIP(), []int{15} } func (x *Binding) GetSymbol() string { @@ -1416,7 +1479,7 @@ type Null struct { func (x *Null) Reset() { *x = Null{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[15] + mi := &file_bass_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1429,7 +1492,7 @@ func (x *Null) String() string { func (*Null) ProtoMessage() {} func (x *Null) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[15] + mi := &file_bass_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1442,7 +1505,7 @@ func (x *Null) ProtoReflect() protoreflect.Message { // Deprecated: Use Null.ProtoReflect.Descriptor instead. func (*Null) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{15} + return file_bass_proto_rawDescGZIP(), []int{16} } type Bool struct { @@ -1456,7 +1519,7 @@ type Bool struct { func (x *Bool) Reset() { *x = Bool{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[16] + mi := &file_bass_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1469,7 +1532,7 @@ func (x *Bool) String() string { func (*Bool) ProtoMessage() {} func (x *Bool) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[16] + mi := &file_bass_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1482,7 +1545,7 @@ func (x *Bool) ProtoReflect() protoreflect.Message { // Deprecated: Use Bool.ProtoReflect.Descriptor instead. func (*Bool) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{16} + return file_bass_proto_rawDescGZIP(), []int{17} } func (x *Bool) GetValue() bool { @@ -1503,7 +1566,7 @@ type Int struct { func (x *Int) Reset() { *x = Int{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[17] + mi := &file_bass_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1516,7 +1579,7 @@ func (x *Int) String() string { func (*Int) ProtoMessage() {} func (x *Int) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[17] + mi := &file_bass_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1529,7 +1592,7 @@ func (x *Int) ProtoReflect() protoreflect.Message { // Deprecated: Use Int.ProtoReflect.Descriptor instead. func (*Int) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{17} + return file_bass_proto_rawDescGZIP(), []int{18} } func (x *Int) GetValue() int64 { @@ -1550,7 +1613,7 @@ type String struct { func (x *String) Reset() { *x = String{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[18] + mi := &file_bass_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1563,7 +1626,7 @@ func (x *String) String() string { func (*String) ProtoMessage() {} func (x *String) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[18] + mi := &file_bass_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1576,7 +1639,7 @@ func (x *String) ProtoReflect() protoreflect.Message { // Deprecated: Use String.ProtoReflect.Descriptor instead. func (*String) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{18} + return file_bass_proto_rawDescGZIP(), []int{19} } func (x *String) GetValue() string { @@ -1598,7 +1661,7 @@ type CachePath struct { func (x *CachePath) Reset() { *x = CachePath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[19] + mi := &file_bass_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1611,7 +1674,7 @@ func (x *CachePath) String() string { func (*CachePath) ProtoMessage() {} func (x *CachePath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[19] + mi := &file_bass_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1624,7 +1687,7 @@ func (x *CachePath) ProtoReflect() protoreflect.Message { // Deprecated: Use CachePath.ProtoReflect.Descriptor instead. func (*CachePath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{19} + return file_bass_proto_rawDescGZIP(), []int{20} } func (x *CachePath) GetId() string { @@ -1652,7 +1715,7 @@ type Secret struct { func (x *Secret) Reset() { *x = Secret{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[20] + mi := &file_bass_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1665,7 +1728,7 @@ func (x *Secret) String() string { func (*Secret) ProtoMessage() {} func (x *Secret) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[20] + mi := &file_bass_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1678,7 +1741,7 @@ func (x *Secret) ProtoReflect() protoreflect.Message { // Deprecated: Use Secret.ProtoReflect.Descriptor instead. func (*Secret) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{20} + return file_bass_proto_rawDescGZIP(), []int{21} } func (x *Secret) GetName() string { @@ -1699,7 +1762,7 @@ type CommandPath struct { func (x *CommandPath) Reset() { *x = CommandPath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[21] + mi := &file_bass_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1712,7 +1775,7 @@ func (x *CommandPath) String() string { func (*CommandPath) ProtoMessage() {} func (x *CommandPath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[21] + mi := &file_bass_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1725,7 +1788,7 @@ func (x *CommandPath) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandPath.ProtoReflect.Descriptor instead. func (*CommandPath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{21} + return file_bass_proto_rawDescGZIP(), []int{22} } func (x *CommandPath) GetName() string { @@ -1746,7 +1809,7 @@ type FilePath struct { func (x *FilePath) Reset() { *x = FilePath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[22] + mi := &file_bass_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1759,7 +1822,7 @@ func (x *FilePath) String() string { func (*FilePath) ProtoMessage() {} func (x *FilePath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[22] + mi := &file_bass_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1772,7 +1835,7 @@ func (x *FilePath) ProtoReflect() protoreflect.Message { // Deprecated: Use FilePath.ProtoReflect.Descriptor instead. func (*FilePath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{22} + return file_bass_proto_rawDescGZIP(), []int{23} } func (x *FilePath) GetPath() string { @@ -1793,7 +1856,7 @@ type DirPath struct { func (x *DirPath) Reset() { *x = DirPath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[23] + mi := &file_bass_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1806,7 +1869,7 @@ func (x *DirPath) String() string { func (*DirPath) ProtoMessage() {} func (x *DirPath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[23] + mi := &file_bass_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1819,7 +1882,7 @@ func (x *DirPath) ProtoReflect() protoreflect.Message { // Deprecated: Use DirPath.ProtoReflect.Descriptor instead. func (*DirPath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{23} + return file_bass_proto_rawDescGZIP(), []int{24} } func (x *DirPath) GetPath() string { @@ -1843,7 +1906,7 @@ type FilesystemPath struct { func (x *FilesystemPath) Reset() { *x = FilesystemPath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[24] + mi := &file_bass_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1856,7 +1919,7 @@ func (x *FilesystemPath) String() string { func (*FilesystemPath) ProtoMessage() {} func (x *FilesystemPath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[24] + mi := &file_bass_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1869,7 +1932,7 @@ func (x *FilesystemPath) ProtoReflect() protoreflect.Message { // Deprecated: Use FilesystemPath.ProtoReflect.Descriptor instead. func (*FilesystemPath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{24} + return file_bass_proto_rawDescGZIP(), []int{25} } func (m *FilesystemPath) GetPath() isFilesystemPath_Path { @@ -1921,7 +1984,7 @@ type ThunkPath struct { func (x *ThunkPath) Reset() { *x = ThunkPath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[25] + mi := &file_bass_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1934,7 +1997,7 @@ func (x *ThunkPath) String() string { func (*ThunkPath) ProtoMessage() {} func (x *ThunkPath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[25] + mi := &file_bass_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1947,7 +2010,7 @@ func (x *ThunkPath) ProtoReflect() protoreflect.Message { // Deprecated: Use ThunkPath.ProtoReflect.Descriptor instead. func (*ThunkPath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{25} + return file_bass_proto_rawDescGZIP(), []int{26} } func (x *ThunkPath) GetThunk() *Thunk { @@ -1976,7 +2039,7 @@ type HostPath struct { func (x *HostPath) Reset() { *x = HostPath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[26] + mi := &file_bass_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1989,7 +2052,7 @@ func (x *HostPath) String() string { func (*HostPath) ProtoMessage() {} func (x *HostPath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[26] + mi := &file_bass_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2002,7 +2065,7 @@ func (x *HostPath) ProtoReflect() protoreflect.Message { // Deprecated: Use HostPath.ProtoReflect.Descriptor instead. func (*HostPath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{26} + return file_bass_proto_rawDescGZIP(), []int{27} } func (x *HostPath) GetContext() string { @@ -2033,7 +2096,7 @@ type LogicalPath struct { func (x *LogicalPath) Reset() { *x = LogicalPath{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[27] + mi := &file_bass_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2046,7 +2109,7 @@ func (x *LogicalPath) String() string { func (*LogicalPath) ProtoMessage() {} func (x *LogicalPath) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[27] + mi := &file_bass_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2059,7 +2122,7 @@ func (x *LogicalPath) ProtoReflect() protoreflect.Message { // Deprecated: Use LogicalPath.ProtoReflect.Descriptor instead. func (*LogicalPath) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{27} + return file_bass_proto_rawDescGZIP(), []int{28} } func (m *LogicalPath) GetPath() isLogicalPath_Path { @@ -2111,7 +2174,7 @@ type LogicalPath_File struct { func (x *LogicalPath_File) Reset() { *x = LogicalPath_File{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[28] + mi := &file_bass_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2124,7 +2187,7 @@ func (x *LogicalPath_File) String() string { func (*LogicalPath_File) ProtoMessage() {} func (x *LogicalPath_File) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[28] + mi := &file_bass_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2137,7 +2200,7 @@ func (x *LogicalPath_File) ProtoReflect() protoreflect.Message { // Deprecated: Use LogicalPath_File.ProtoReflect.Descriptor instead. func (*LogicalPath_File) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{27, 0} + return file_bass_proto_rawDescGZIP(), []int{28, 0} } func (x *LogicalPath_File) GetName() string { @@ -2166,7 +2229,7 @@ type LogicalPath_Dir struct { func (x *LogicalPath_Dir) Reset() { *x = LogicalPath_Dir{} if protoimpl.UnsafeEnabled { - mi := &file_bass_proto_msgTypes[29] + mi := &file_bass_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2179,7 +2242,7 @@ func (x *LogicalPath_Dir) String() string { func (*LogicalPath_Dir) ProtoMessage() {} func (x *LogicalPath_Dir) ProtoReflect() protoreflect.Message { - mi := &file_bass_proto_msgTypes[29] + mi := &file_bass_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2192,7 +2255,7 @@ func (x *LogicalPath_Dir) ProtoReflect() protoreflect.Message { // Deprecated: Use LogicalPath_Dir.ProtoReflect.Descriptor instead. func (*LogicalPath_Dir) Descriptor() ([]byte, []int) { - return file_bass_proto_rawDescGZIP(), []int{27, 1} + return file_bass_proto_rawDescGZIP(), []int{28, 1} } func (x *LogicalPath_Dir) GetName() string { @@ -2254,7 +2317,7 @@ var file_bass_proto_rawDesc = []byte{ 0x0a, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x48, 0x00, 0x52, 0x09, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x42, - 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xec, 0x02, 0x0a, 0x05, 0x54, 0x68, 0x75, + 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x8e, 0x03, 0x0a, 0x05, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x26, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, @@ -2277,161 +2340,169 @@ var file_bass_proto_rawDesc = []byte{ 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x6f, 0x72, 0x74, - 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, 0x6b, - 0x41, 0x64, 0x64, 0x72, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, - 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x22, 0x33, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x6f, 0x72, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x54, 0x68, 0x75, - 0x6e, 0x6b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x23, 0x0a, 0x05, 0x74, - 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, - 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, - 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x41, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x42, 0x07, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0xfb, 0x01, 0x0a, 0x08, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x52, 0x65, 0x66, 0x12, 0x20, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, - 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x41, 0x64, - 0x64, 0x72, 0x48, 0x00, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x2a, 0x0a, 0x08, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, - 0x61, 0x73, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x15, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x03, 0x74, 0x61, 0x67, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, - 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, - 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x74, 0x61, 0x67, 0x42, 0x09, 0x0a, 0x07, - 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x7e, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, - 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x08, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x15, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x88, 0x01, 0x01, 0x42, - 0x06, 0x0a, 0x04, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x2e, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x22, 0x8d, 0x02, 0x0a, 0x08, 0x54, 0x68, 0x75, 0x6e, - 0x6b, 0x43, 0x6d, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x12, 0x24, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, - 0x68, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x74, 0x68, 0x75, - 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, - 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x74, 0x68, 0x75, - 0x6e, 0x6b, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x48, 0x00, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x69, - 0x63, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x73, - 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, - 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x43, 0x61, - 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, - 0x42, 0x05, 0x0a, 0x03, 0x63, 0x6d, 0x64, 0x22, 0x87, 0x01, 0x0a, 0x08, 0x54, 0x68, 0x75, 0x6e, - 0x6b, 0x44, 0x69, 0x72, 0x12, 0x25, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x50, 0x61, - 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x05, 0x74, - 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, - 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x74, - 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, - 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x42, 0x05, 0x0a, 0x03, 0x64, 0x69, - 0x72, 0x22, 0xeb, 0x01, 0x0a, 0x10, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x6f, 0x75, 0x6e, 0x74, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, - 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, - 0x24, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, - 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, - 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x67, - 0x69, 0x63, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x63, 0x61, 0x63, 0x68, 0x65, 0x12, 0x26, 0x0a, - 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, - 0x6a, 0x0a, 0x0a, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, - 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2c, 0x0a, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, - 0x61, 0x74, 0x68, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x2c, 0x0a, 0x05, 0x41, - 0x72, 0x72, 0x61, 0x79, 0x12, 0x23, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x06, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x29, 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x42, 0x69, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x44, - 0x0a, 0x07, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, - 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, - 0x6c, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x22, 0x06, 0x0a, 0x04, 0x4e, 0x75, 0x6c, 0x6c, 0x22, 0x1c, 0x0a, 0x04, - 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1b, 0x0a, 0x03, 0x49, 0x6e, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1e, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x45, 0x0a, 0x09, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x1c, - 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x0b, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x1e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, - 0x1d, 0x0a, 0x07, 0x44, 0x69, 0x72, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x61, - 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, - 0x12, 0x24, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, - 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x64, 0x69, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x50, 0x61, - 0x74, 0x68, 0x48, 0x00, 0x52, 0x03, 0x64, 0x69, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x22, 0x58, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x12, 0x21, - 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, - 0x6b, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x4e, 0x0a, 0x08, 0x48, - 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xec, 0x01, 0x0a, 0x0b, - 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x61, 0x73, 0x73, - 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x03, 0x64, 0x69, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, - 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x44, 0x69, 0x72, 0x48, 0x00, 0x52, - 0x03, 0x64, 0x69, 0x72, 0x1a, 0x34, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, + 0x6b, 0x54, 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x22, 0x5a, 0x0a, 0x09, 0x54, 0x68, 0x75, + 0x6e, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, + 0x6e, 0x6b, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x33, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x6f, + 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x50, 0x0a, 0x08, 0x54, 0x68, + 0x75, 0x6e, 0x6b, 0x54, 0x4c, 0x53, 0x12, 0x22, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x63, 0x65, 0x72, 0x74, 0x12, 0x20, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x8e, 0x01, 0x0a, + 0x0a, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x03, 0x72, + 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x66, 0x48, 0x00, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, + 0x23, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x74, + 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0xfb, 0x01, + 0x0a, 0x08, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x66, 0x12, 0x20, 0x0a, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x04, + 0x66, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, + 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x42, 0x02, 0x18, 0x01, 0x48, + 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, + 0x6e, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x48, 0x00, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x2a, + 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x15, 0x0a, 0x03, 0x74, 0x61, + 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x03, 0x74, 0x61, 0x67, 0x88, 0x01, + 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x02, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x88, 0x01, 0x01, 0x42, 0x08, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x74, 0x61, 0x67, + 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x7e, 0x0a, 0x0c, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x66, + 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, + 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x2a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x15, 0x0a, 0x03, + 0x74, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, + 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x2e, 0x0a, 0x08, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x22, 0x8d, 0x02, 0x0a, 0x08, + 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6d, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x73, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x24, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x27, 0x0a, + 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, + 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, + 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, + 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, + 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, + 0x48, 0x00, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x05, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, + 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x63, 0x6d, 0x64, 0x22, 0x87, 0x01, 0x0a, 0x08, + 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x44, 0x69, 0x72, 0x12, 0x25, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x44, + 0x69, 0x72, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x12, + 0x27, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x48, + 0x00, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x48, 0x6f, + 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x42, 0x05, + 0x0a, 0x03, 0x64, 0x69, 0x72, 0x22, 0xeb, 0x01, 0x0a, 0x10, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x4d, + 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x74, 0x68, + 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, + 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x74, 0x68, + 0x75, 0x6e, 0x6b, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, + 0x68, 0x48, 0x00, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x6c, 0x6f, 0x67, + 0x69, 0x63, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, + 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, + 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x05, 0x63, 0x61, 0x63, 0x68, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x63, 0x61, 0x63, 0x68, + 0x65, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, + 0x00, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x22, 0x6a, 0x0a, 0x0a, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, + 0x2c, 0x0a, 0x05, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x23, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x33, 0x0a, + 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x29, 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, + 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x22, 0x44, 0x0a, 0x07, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x06, 0x0a, 0x04, 0x4e, 0x75, 0x6c, 0x6c, + 0x22, 0x1c, 0x0a, 0x04, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1b, + 0x0a, 0x03, 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1e, 0x0a, 0x06, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x45, 0x0a, 0x09, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x22, 0x1c, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x46, 0x0a, 0x03, 0x44, 0x69, - 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, - 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, - 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x21, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x1e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x22, 0x1d, 0x0a, 0x07, 0x44, 0x69, 0x72, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x22, 0x61, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, + 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x64, 0x69, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x44, + 0x69, 0x72, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x03, 0x64, 0x69, 0x72, 0x42, 0x06, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x58, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, + 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, + 0x4e, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, + 0xec, 0x01, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x2c, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, 0x0a, + 0x03, 0x64, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x73, + 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x44, 0x69, + 0x72, 0x48, 0x00, 0x52, 0x03, 0x64, 0x69, 0x72, 0x1a, 0x34, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x46, + 0x0a, 0x03, 0x44, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, + 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x07, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x0b, + 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -2446,106 +2517,110 @@ func file_bass_proto_rawDescGZIP() []byte { return file_bass_proto_rawDescData } -var file_bass_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_bass_proto_msgTypes = make([]protoimpl.MessageInfo, 31) var file_bass_proto_goTypes = []interface{}{ (*Value)(nil), // 0: bass.Value (*Thunk)(nil), // 1: bass.Thunk (*ThunkAddr)(nil), // 2: bass.ThunkAddr (*ThunkPort)(nil), // 3: bass.ThunkPort - (*ThunkImage)(nil), // 4: bass.ThunkImage - (*ImageRef)(nil), // 5: bass.ImageRef - (*ImageArchive)(nil), // 6: bass.ImageArchive - (*Platform)(nil), // 7: bass.Platform - (*ThunkCmd)(nil), // 8: bass.ThunkCmd - (*ThunkDir)(nil), // 9: bass.ThunkDir - (*ThunkMountSource)(nil), // 10: bass.ThunkMountSource - (*ThunkMount)(nil), // 11: bass.ThunkMount - (*Array)(nil), // 12: bass.Array - (*Object)(nil), // 13: bass.Object - (*Binding)(nil), // 14: bass.Binding - (*Null)(nil), // 15: bass.Null - (*Bool)(nil), // 16: bass.Bool - (*Int)(nil), // 17: bass.Int - (*String)(nil), // 18: bass.String - (*CachePath)(nil), // 19: bass.CachePath - (*Secret)(nil), // 20: bass.Secret - (*CommandPath)(nil), // 21: bass.CommandPath - (*FilePath)(nil), // 22: bass.FilePath - (*DirPath)(nil), // 23: bass.DirPath - (*FilesystemPath)(nil), // 24: bass.FilesystemPath - (*ThunkPath)(nil), // 25: bass.ThunkPath - (*HostPath)(nil), // 26: bass.HostPath - (*LogicalPath)(nil), // 27: bass.LogicalPath - (*LogicalPath_File)(nil), // 28: bass.LogicalPath.File - (*LogicalPath_Dir)(nil), // 29: bass.LogicalPath.Dir + (*ThunkTLS)(nil), // 4: bass.ThunkTLS + (*ThunkImage)(nil), // 5: bass.ThunkImage + (*ImageRef)(nil), // 6: bass.ImageRef + (*ImageArchive)(nil), // 7: bass.ImageArchive + (*Platform)(nil), // 8: bass.Platform + (*ThunkCmd)(nil), // 9: bass.ThunkCmd + (*ThunkDir)(nil), // 10: bass.ThunkDir + (*ThunkMountSource)(nil), // 11: bass.ThunkMountSource + (*ThunkMount)(nil), // 12: bass.ThunkMount + (*Array)(nil), // 13: bass.Array + (*Object)(nil), // 14: bass.Object + (*Binding)(nil), // 15: bass.Binding + (*Null)(nil), // 16: bass.Null + (*Bool)(nil), // 17: bass.Bool + (*Int)(nil), // 18: bass.Int + (*String)(nil), // 19: bass.String + (*CachePath)(nil), // 20: bass.CachePath + (*Secret)(nil), // 21: bass.Secret + (*CommandPath)(nil), // 22: bass.CommandPath + (*FilePath)(nil), // 23: bass.FilePath + (*DirPath)(nil), // 24: bass.DirPath + (*FilesystemPath)(nil), // 25: bass.FilesystemPath + (*ThunkPath)(nil), // 26: bass.ThunkPath + (*HostPath)(nil), // 27: bass.HostPath + (*LogicalPath)(nil), // 28: bass.LogicalPath + (*LogicalPath_File)(nil), // 29: bass.LogicalPath.File + (*LogicalPath_Dir)(nil), // 30: bass.LogicalPath.Dir } var file_bass_proto_depIdxs = []int32{ - 15, // 0: bass.Value.null:type_name -> bass.Null - 16, // 1: bass.Value.bool:type_name -> bass.Bool - 17, // 2: bass.Value.int:type_name -> bass.Int - 18, // 3: bass.Value.string:type_name -> bass.String - 20, // 4: bass.Value.secret:type_name -> bass.Secret - 12, // 5: bass.Value.array:type_name -> bass.Array - 13, // 6: bass.Value.object:type_name -> bass.Object + 16, // 0: bass.Value.null:type_name -> bass.Null + 17, // 1: bass.Value.bool:type_name -> bass.Bool + 18, // 2: bass.Value.int:type_name -> bass.Int + 19, // 3: bass.Value.string:type_name -> bass.String + 21, // 4: bass.Value.secret:type_name -> bass.Secret + 13, // 5: bass.Value.array:type_name -> bass.Array + 14, // 6: bass.Value.object:type_name -> bass.Object 1, // 7: bass.Value.thunk:type_name -> bass.Thunk - 21, // 8: bass.Value.command_path:type_name -> bass.CommandPath - 22, // 9: bass.Value.file_path:type_name -> bass.FilePath - 23, // 10: bass.Value.dir_path:type_name -> bass.DirPath - 26, // 11: bass.Value.host_path:type_name -> bass.HostPath - 25, // 12: bass.Value.thunk_path:type_name -> bass.ThunkPath - 27, // 13: bass.Value.logical_path:type_name -> bass.LogicalPath + 22, // 8: bass.Value.command_path:type_name -> bass.CommandPath + 23, // 9: bass.Value.file_path:type_name -> bass.FilePath + 24, // 10: bass.Value.dir_path:type_name -> bass.DirPath + 27, // 11: bass.Value.host_path:type_name -> bass.HostPath + 26, // 12: bass.Value.thunk_path:type_name -> bass.ThunkPath + 28, // 13: bass.Value.logical_path:type_name -> bass.LogicalPath 2, // 14: bass.Value.thunk_addr:type_name -> bass.ThunkAddr - 4, // 15: bass.Thunk.image:type_name -> bass.ThunkImage - 8, // 16: bass.Thunk.cmd:type_name -> bass.ThunkCmd + 5, // 15: bass.Thunk.image:type_name -> bass.ThunkImage + 9, // 16: bass.Thunk.cmd:type_name -> bass.ThunkCmd 0, // 17: bass.Thunk.args:type_name -> bass.Value 0, // 18: bass.Thunk.stdin:type_name -> bass.Value - 14, // 19: bass.Thunk.env:type_name -> bass.Binding - 9, // 20: bass.Thunk.dir:type_name -> bass.ThunkDir - 11, // 21: bass.Thunk.mounts:type_name -> bass.ThunkMount - 14, // 22: bass.Thunk.labels:type_name -> bass.Binding + 15, // 19: bass.Thunk.env:type_name -> bass.Binding + 10, // 20: bass.Thunk.dir:type_name -> bass.ThunkDir + 12, // 21: bass.Thunk.mounts:type_name -> bass.ThunkMount + 15, // 22: bass.Thunk.labels:type_name -> bass.Binding 3, // 23: bass.Thunk.ports:type_name -> bass.ThunkPort - 1, // 24: bass.ThunkAddr.thunk:type_name -> bass.Thunk - 5, // 25: bass.ThunkImage.ref:type_name -> bass.ImageRef - 1, // 26: bass.ThunkImage.thunk:type_name -> bass.Thunk - 6, // 27: bass.ThunkImage.archive:type_name -> bass.ImageArchive - 25, // 28: bass.ImageRef.file:type_name -> bass.ThunkPath - 2, // 29: bass.ImageRef.addr:type_name -> bass.ThunkAddr - 7, // 30: bass.ImageRef.platform:type_name -> bass.Platform - 25, // 31: bass.ImageArchive.file:type_name -> bass.ThunkPath - 7, // 32: bass.ImageArchive.platform:type_name -> bass.Platform - 21, // 33: bass.ThunkCmd.command:type_name -> bass.CommandPath - 22, // 34: bass.ThunkCmd.file:type_name -> bass.FilePath - 25, // 35: bass.ThunkCmd.thunk:type_name -> bass.ThunkPath - 26, // 36: bass.ThunkCmd.host:type_name -> bass.HostPath - 27, // 37: bass.ThunkCmd.logical:type_name -> bass.LogicalPath - 19, // 38: bass.ThunkCmd.cache:type_name -> bass.CachePath - 23, // 39: bass.ThunkDir.local:type_name -> bass.DirPath - 25, // 40: bass.ThunkDir.thunk:type_name -> bass.ThunkPath - 26, // 41: bass.ThunkDir.host:type_name -> bass.HostPath - 25, // 42: bass.ThunkMountSource.thunk:type_name -> bass.ThunkPath - 26, // 43: bass.ThunkMountSource.host:type_name -> bass.HostPath - 27, // 44: bass.ThunkMountSource.logical:type_name -> bass.LogicalPath - 19, // 45: bass.ThunkMountSource.cache:type_name -> bass.CachePath - 20, // 46: bass.ThunkMountSource.secret:type_name -> bass.Secret - 10, // 47: bass.ThunkMount.source:type_name -> bass.ThunkMountSource - 24, // 48: bass.ThunkMount.target:type_name -> bass.FilesystemPath - 0, // 49: bass.Array.values:type_name -> bass.Value - 14, // 50: bass.Object.bindings:type_name -> bass.Binding - 0, // 51: bass.Binding.value:type_name -> bass.Value - 24, // 52: bass.CachePath.path:type_name -> bass.FilesystemPath - 22, // 53: bass.FilesystemPath.file:type_name -> bass.FilePath - 23, // 54: bass.FilesystemPath.dir:type_name -> bass.DirPath - 1, // 55: bass.ThunkPath.thunk:type_name -> bass.Thunk - 24, // 56: bass.ThunkPath.path:type_name -> bass.FilesystemPath - 24, // 57: bass.HostPath.path:type_name -> bass.FilesystemPath - 28, // 58: bass.LogicalPath.file:type_name -> bass.LogicalPath.File - 29, // 59: bass.LogicalPath.dir:type_name -> bass.LogicalPath.Dir - 27, // 60: bass.LogicalPath.Dir.entries:type_name -> bass.LogicalPath - 61, // [61:61] is the sub-list for method output_type - 61, // [61:61] is the sub-list for method input_type - 61, // [61:61] is the sub-list for extension type_name - 61, // [61:61] is the sub-list for extension extendee - 0, // [0:61] is the sub-list for field type_name + 4, // 24: bass.Thunk.tls:type_name -> bass.ThunkTLS + 1, // 25: bass.ThunkAddr.thunk:type_name -> bass.Thunk + 23, // 26: bass.ThunkTLS.cert:type_name -> bass.FilePath + 23, // 27: bass.ThunkTLS.key:type_name -> bass.FilePath + 6, // 28: bass.ThunkImage.ref:type_name -> bass.ImageRef + 1, // 29: bass.ThunkImage.thunk:type_name -> bass.Thunk + 7, // 30: bass.ThunkImage.archive:type_name -> bass.ImageArchive + 26, // 31: bass.ImageRef.file:type_name -> bass.ThunkPath + 2, // 32: bass.ImageRef.addr:type_name -> bass.ThunkAddr + 8, // 33: bass.ImageRef.platform:type_name -> bass.Platform + 26, // 34: bass.ImageArchive.file:type_name -> bass.ThunkPath + 8, // 35: bass.ImageArchive.platform:type_name -> bass.Platform + 22, // 36: bass.ThunkCmd.command:type_name -> bass.CommandPath + 23, // 37: bass.ThunkCmd.file:type_name -> bass.FilePath + 26, // 38: bass.ThunkCmd.thunk:type_name -> bass.ThunkPath + 27, // 39: bass.ThunkCmd.host:type_name -> bass.HostPath + 28, // 40: bass.ThunkCmd.logical:type_name -> bass.LogicalPath + 20, // 41: bass.ThunkCmd.cache:type_name -> bass.CachePath + 24, // 42: bass.ThunkDir.local:type_name -> bass.DirPath + 26, // 43: bass.ThunkDir.thunk:type_name -> bass.ThunkPath + 27, // 44: bass.ThunkDir.host:type_name -> bass.HostPath + 26, // 45: bass.ThunkMountSource.thunk:type_name -> bass.ThunkPath + 27, // 46: bass.ThunkMountSource.host:type_name -> bass.HostPath + 28, // 47: bass.ThunkMountSource.logical:type_name -> bass.LogicalPath + 20, // 48: bass.ThunkMountSource.cache:type_name -> bass.CachePath + 21, // 49: bass.ThunkMountSource.secret:type_name -> bass.Secret + 11, // 50: bass.ThunkMount.source:type_name -> bass.ThunkMountSource + 25, // 51: bass.ThunkMount.target:type_name -> bass.FilesystemPath + 0, // 52: bass.Array.values:type_name -> bass.Value + 15, // 53: bass.Object.bindings:type_name -> bass.Binding + 0, // 54: bass.Binding.value:type_name -> bass.Value + 25, // 55: bass.CachePath.path:type_name -> bass.FilesystemPath + 23, // 56: bass.FilesystemPath.file:type_name -> bass.FilePath + 24, // 57: bass.FilesystemPath.dir:type_name -> bass.DirPath + 1, // 58: bass.ThunkPath.thunk:type_name -> bass.Thunk + 25, // 59: bass.ThunkPath.path:type_name -> bass.FilesystemPath + 25, // 60: bass.HostPath.path:type_name -> bass.FilesystemPath + 29, // 61: bass.LogicalPath.file:type_name -> bass.LogicalPath.File + 30, // 62: bass.LogicalPath.dir:type_name -> bass.LogicalPath.Dir + 28, // 63: bass.LogicalPath.Dir.entries:type_name -> bass.LogicalPath + 64, // [64:64] is the sub-list for method output_type + 64, // [64:64] is the sub-list for method input_type + 64, // [64:64] is the sub-list for extension type_name + 64, // [64:64] is the sub-list for extension extendee + 0, // [0:64] is the sub-list for field type_name } func init() { file_bass_proto_init() } @@ -2603,7 +2678,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ThunkImage); i { + switch v := v.(*ThunkTLS); i { case 0: return &v.state case 1: @@ -2615,7 +2690,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImageRef); i { + switch v := v.(*ThunkImage); i { case 0: return &v.state case 1: @@ -2627,7 +2702,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImageArchive); i { + switch v := v.(*ImageRef); i { case 0: return &v.state case 1: @@ -2639,7 +2714,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Platform); i { + switch v := v.(*ImageArchive); i { case 0: return &v.state case 1: @@ -2651,7 +2726,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ThunkCmd); i { + switch v := v.(*Platform); i { case 0: return &v.state case 1: @@ -2663,7 +2738,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ThunkDir); i { + switch v := v.(*ThunkCmd); i { case 0: return &v.state case 1: @@ -2675,7 +2750,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ThunkMountSource); i { + switch v := v.(*ThunkDir); i { case 0: return &v.state case 1: @@ -2687,7 +2762,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ThunkMount); i { + switch v := v.(*ThunkMountSource); i { case 0: return &v.state case 1: @@ -2699,7 +2774,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Array); i { + switch v := v.(*ThunkMount); i { case 0: return &v.state case 1: @@ -2711,7 +2786,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Object); i { + switch v := v.(*Array); i { case 0: return &v.state case 1: @@ -2723,7 +2798,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Binding); i { + switch v := v.(*Object); i { case 0: return &v.state case 1: @@ -2735,7 +2810,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Null); i { + switch v := v.(*Binding); i { case 0: return &v.state case 1: @@ -2747,7 +2822,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Bool); i { + switch v := v.(*Null); i { case 0: return &v.state case 1: @@ -2759,7 +2834,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Int); i { + switch v := v.(*Bool); i { case 0: return &v.state case 1: @@ -2771,7 +2846,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*String); i { + switch v := v.(*Int); i { case 0: return &v.state case 1: @@ -2783,7 +2858,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CachePath); i { + switch v := v.(*String); i { case 0: return &v.state case 1: @@ -2795,7 +2870,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Secret); i { + switch v := v.(*CachePath); i { case 0: return &v.state case 1: @@ -2807,7 +2882,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommandPath); i { + switch v := v.(*Secret); i { case 0: return &v.state case 1: @@ -2819,7 +2894,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FilePath); i { + switch v := v.(*CommandPath); i { case 0: return &v.state case 1: @@ -2831,7 +2906,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DirPath); i { + switch v := v.(*FilePath); i { case 0: return &v.state case 1: @@ -2843,7 +2918,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FilesystemPath); i { + switch v := v.(*DirPath); i { case 0: return &v.state case 1: @@ -2855,7 +2930,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ThunkPath); i { + switch v := v.(*FilesystemPath); i { case 0: return &v.state case 1: @@ -2867,7 +2942,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HostPath); i { + switch v := v.(*ThunkPath); i { case 0: return &v.state case 1: @@ -2879,7 +2954,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LogicalPath); i { + switch v := v.(*HostPath); i { case 0: return &v.state case 1: @@ -2891,7 +2966,7 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LogicalPath_File); i { + switch v := v.(*LogicalPath); i { case 0: return &v.state case 1: @@ -2903,6 +2978,18 @@ func file_bass_proto_init() { } } file_bass_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogicalPath_File); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_bass_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LogicalPath_Dir); i { case 0: return &v.state @@ -2932,18 +3019,18 @@ func file_bass_proto_init() { (*Value_LogicalPath)(nil), (*Value_ThunkAddr)(nil), } - file_bass_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[5].OneofWrappers = []interface{}{ (*ThunkImage_Ref)(nil), (*ThunkImage_Thunk)(nil), (*ThunkImage_Archive)(nil), } - file_bass_proto_msgTypes[5].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[6].OneofWrappers = []interface{}{ (*ImageRef_Repository)(nil), (*ImageRef_File)(nil), (*ImageRef_Addr)(nil), } - file_bass_proto_msgTypes[6].OneofWrappers = []interface{}{} - file_bass_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[7].OneofWrappers = []interface{}{} + file_bass_proto_msgTypes[9].OneofWrappers = []interface{}{ (*ThunkCmd_Command)(nil), (*ThunkCmd_File)(nil), (*ThunkCmd_Thunk)(nil), @@ -2951,23 +3038,23 @@ func file_bass_proto_init() { (*ThunkCmd_Logical)(nil), (*ThunkCmd_Cache)(nil), } - file_bass_proto_msgTypes[9].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[10].OneofWrappers = []interface{}{ (*ThunkDir_Local)(nil), (*ThunkDir_Thunk)(nil), (*ThunkDir_Host)(nil), } - file_bass_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[11].OneofWrappers = []interface{}{ (*ThunkMountSource_Thunk)(nil), (*ThunkMountSource_Host)(nil), (*ThunkMountSource_Logical)(nil), (*ThunkMountSource_Cache)(nil), (*ThunkMountSource_Secret)(nil), } - file_bass_proto_msgTypes[24].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[25].OneofWrappers = []interface{}{ (*FilesystemPath_File)(nil), (*FilesystemPath_Dir)(nil), } - file_bass_proto_msgTypes[27].OneofWrappers = []interface{}{ + file_bass_proto_msgTypes[28].OneofWrappers = []interface{}{ (*LogicalPath_File_)(nil), (*LogicalPath_Dir_)(nil), } @@ -2977,7 +3064,7 @@ func file_bass_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_bass_proto_rawDesc, NumEnums: 0, - NumMessages: 30, + NumMessages: 31, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index d57f881a..3bcf11dd 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -33,6 +33,7 @@ import ( ocispecs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/tonistiigi/units" "github.com/vito/bass/pkg/bass" + "github.com/vito/bass/pkg/basstls" "github.com/vito/bass/pkg/cli" "github.com/vito/bass/pkg/ioctx" "github.com/vito/bass/pkg/runtimes/util/buildkitd" @@ -645,6 +646,40 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru llb.Args([]string{shimExePath, "run", inputFile}), } + if thunk.TLS != nil { + crt, key, err := basstls.Generate(id) + if err != nil { + return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) + } + + crtContent, err := crt.Export() + if err != nil { + return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) + } + + keyContent, err := key.ExportPrivate() + if err != nil { + return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) + } + + runOpt = append(runOpt, + llb.AddMount( + thunk.TLS.Cert.FromSlash(), + llb.Scratch().File( + llb.Mkfile(thunk.TLS.Cert.Name(), 0600, crtContent), + ), + llb.SourcePath(thunk.TLS.Cert.Name()), + ), + llb.AddMount( + thunk.TLS.Key.FromSlash(), + llb.Scratch().File( + llb.Mkfile(thunk.TLS.Key.Name(), 0600, keyContent), + ), + llb.SourcePath(thunk.TLS.Key.Name()), + ), + ) + } + if thunk.Insecure { needsInsecure = true diff --git a/pkg/runtimes/command_test.go b/pkg/runtimes/command_test.go index 7759b25e..ca817827 100644 --- a/pkg/runtimes/command_test.go +++ b/pkg/runtimes/command_test.go @@ -41,6 +41,14 @@ var svcThunk = bass.Thunk{ Name: "http", Port: 80, }, + { + Name: "https", + Port: 443, + }, + }, + TLS: &bass.ThunkTLS{ + Cert: bass.FilePath{Path: "cert"}, + Key: bass.FilePath{Path: "key"}, }, } diff --git a/pkg/runtimes/util/buildkitd/buildkitd.go b/pkg/runtimes/util/buildkitd/buildkitd.go index ebc1a2d9..73c38d4e 100644 --- a/pkg/runtimes/util/buildkitd/buildkitd.go +++ b/pkg/runtimes/util/buildkitd/buildkitd.go @@ -9,10 +9,12 @@ import ( "time" "github.com/adrg/xdg" + "github.com/docker/docker/libnetwork/resolvconf" "github.com/gofrs/flock" _ "github.com/moby/buildkit" bk "github.com/moby/buildkit/client" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // import the container connection driver + "github.com/vito/bass/pkg/basstls" "github.com/vito/bass/pkg/zapctx" "go.opentelemetry.io/otel" "go.uber.org/zap" @@ -182,25 +184,49 @@ func installBuildkit(ctx context.Context) error { return err } - // FIXME: buildkitd currently runs without network isolation (--net=host) - // in order for containers to be able to reach localhost. - // This is required for things such as kubectl being able to - // reach a KinD/minikube cluster locally - // #nosec - cmd = exec.CommandContext(ctx, - "docker", + rc, err := resolvconf.Get() + if err != nil { + logger.Error("failed to get resolv.conf", zap.Error(err)) + return fmt.Errorf("get resolv.conf: %w", err) + } + + dockerArgs := []string{ "run", "--net=host", "-d", "--restart", "always", - "-v", volumeName+":/var/lib/buildkit", + "-v", volumeName + ":/var/lib/buildkit", "--name", containerName, "--privileged", + "--dns", "10.64.0.1", + "--dns-search", "dns.bass", + } + + for _, ns := range resolvconf.GetNameservers(rc.Content, resolvconf.IP) { + dockerArgs = append(dockerArgs, "--dns", ns) + } + + for _, domain := range resolvconf.GetSearchDomains(rc.Content) { + dockerArgs = append(dockerArgs, "--dns-search", domain) + } + + for _, opt := range resolvconf.GetOptions(rc.Content) { + dockerArgs = append(dockerArgs, "--dns-option", opt) + } + + dockerArgs = append(dockerArgs, image+":"+Version, "dumb-init", "buildkitd", "--debug", ) + + // FIXME: buildkitd currently runs without network isolation (--net=host) + // in order for containers to be able to reach localhost. + // This is required for things such as kubectl being able to + // reach a KinD/minikube cluster locally + // #nosec + cmd = exec.CommandContext(ctx, "docker", dockerArgs...) output, err = cmd.CombinedOutput() if err != nil { // If the daemon failed to start because it's already running, @@ -213,6 +239,20 @@ func installBuildkit(ctx context.Context) error { return err } } + + // trust the user's bass CA cert so you can fetch images from a registry + // running in a thunk + cmd = exec.CommandContext( + ctx, + "docker", + "cp", + basstls.CACert, containerName+":/etc/ssl/certs/bass.crt", + ) + output, err = cmd.CombinedOutput() + if err != nil { + return nil + } + return waitBuildkit(ctx) } diff --git a/proto/bass.proto b/proto/bass.proto index 0e58c0b4..6bd04cd1 100644 --- a/proto/bass.proto +++ b/proto/bass.proto @@ -34,6 +34,7 @@ message Thunk { repeated ThunkMount mounts = 8; repeated Binding labels = 9; repeated ThunkPort ports = 10; + ThunkTLS tls = 11; }; message ThunkAddr { @@ -47,6 +48,11 @@ message ThunkPort { int32 port = 2; }; +message ThunkTLS { + FilePath cert = 1; + FilePath key = 2; +}; + message ThunkImage { oneof image { ImageRef ref = 1; From 6dd9dfc6bc4bd5479ae853e2c3d1eab32da26c70 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Thu, 25 Aug 2022 12:24:11 -0400 Subject: [PATCH 02/32] shim: remove runtime.GOMAXPROCS this was preventing reaping since that happens in a separate goroutine --- pkg/runtimes/shim/main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index c2fb43c6..5ca4800a 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -15,7 +15,6 @@ import ( "os/signal" "path" "path/filepath" - "runtime" "sort" "strings" "syscall" @@ -102,8 +101,6 @@ func main() { } func run(args []string) error { - runtime.GOMAXPROCS(1) - if len(args) != 1 { return fmt.Errorf("usage: run ") } From 93bb9ac25e1afa16ef5855bc154b6f02e90bd485 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Thu, 25 Aug 2022 13:38:43 -0400 Subject: [PATCH 03/32] buffer SIGCHLD channel guessing this is the root cause for stuck zombies signal.Notify expects the channel to never block --- pkg/runtimes/shim/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index 5ca4800a..3a95bdd4 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -195,7 +195,7 @@ func reap() error { reaper.SetSubreaper(1) - children := make(chan os.Signal) + children := make(chan os.Signal, 32) signal.Notify(children, syscall.SIGCHLD) go func() { From f548e592b21e5db68edc8fc4fc49414dde3ff52f Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Thu, 25 Aug 2022 23:00:29 -0400 Subject: [PATCH 04/32] bump buildkit --- bass/buildkit.bass | 12 ++-- go.mod | 37 +++++------ go.sum | 82 +++++++++++------------- pkg/runtimes/buildkit.go | 3 +- pkg/runtimes/util/buildkitd/buildkitd.go | 2 +- 5 files changed, 61 insertions(+), 75 deletions(-) diff --git a/bass/buildkit.bass b/bass/buildkit.bass index 129260ed..f6014af5 100644 --- a/bass/buildkit.bass +++ b/bass/buildkit.bass @@ -1,9 +1,7 @@ -; bumped by hack/bump-buildkit -(def *buildkit-version* "v0.10.3") +(def *buildkit-repository* "moby/buildkit") -; TODO: move back to upstream once PRs are merged -(def *buildkit-repository* "vito/buildkit") -(def *buildkit-variant* "-conflist-hostname") +; bumped by hack/bump-buildkit +(def *buildkit-tag* "master") ; TODO: go back to a pinned version (def *cni-version* "v1.1.1") @@ -13,7 +11,7 @@ (defn image [os arch config-dir] (from (resolve {:platform {:os os} ; TODO: :arch arch} :repository *buildkit-repository* - :tag (str *buildkit-version* *buildkit-variant*)}) + :tag *buildkit-tag*}) ($ apk add --no-cache dumb-init iptables ip6tables dnsmasq) ; TODO: nix? ($ mkdir -p /opt/cni/bin/ /etc/buildkit/) ($ cp $dnsname /opt/cni/bin/dnsname) @@ -23,7 +21,7 @@ (defn buildkitd-toml [cni-path] (str "# support insecure! thunks\n" - "insecure-entitlements = [ \"security.insecure\" ]\n" + "insecure-entitlements = [\"security.insecure\"]\n" "\n" "# configure bridge networking\n" "[worker.oci]\n" diff --git a/go.mod b/go.mod index 4690e89a..74ff8f34 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,9 @@ require ( github.com/alecthomas/chroma v0.9.2 github.com/c-bata/go-prompt v0.2.6 github.com/cenkalti/backoff/v4 v4.1.2 - github.com/containerd/containerd v1.6.3-0.20220401172941-5ff8fce1fcc6 - github.com/docker/distribution v2.8.0+incompatible + github.com/containerd/containerd v1.6.6 + github.com/docker/distribution v2.8.1+incompatible + github.com/docker/docker v20.10.7+incompatible github.com/gertd/go-pluralize v0.1.7 github.com/gofrs/flock v0.8.1 github.com/google/go-cmp v0.5.7 @@ -19,8 +20,8 @@ require ( github.com/mattn/go-colorable v0.1.12 github.com/mattn/go-isatty v0.0.14 github.com/mattn/go-unicodeclass v0.0.1 - github.com/moby/buildkit v0.10.3 - github.com/moby/sys/mountinfo v0.6.0 + github.com/moby/buildkit v0.10.1-0.20220826012947-46c8b9ee45d0 + github.com/moby/sys/mountinfo v0.6.2 github.com/morikuni/aec v1.0.0 github.com/neovim/go-client v1.2.2-0.20220118223211-7c85d516f28c github.com/opencontainers/go-digest v1.0.0 @@ -33,6 +34,7 @@ require ( github.com/sourcegraph/jsonrpc2 v0.1.0 github.com/spf13/pflag v1.0.5 github.com/spy16/slurp v0.2.3 + github.com/square/certstrap v1.3.0 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea github.com/vito/booklit v0.12.2-0.20220630023834-33787382be72 github.com/vito/go-interact v1.0.1 @@ -48,7 +50,7 @@ require ( golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 - google.golang.org/grpc v1.45.0 + google.golang.org/grpc v1.47.0 google.golang.org/protobuf v1.27.1 ) @@ -56,22 +58,20 @@ require ( cloud.google.com/go v0.81.0 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/AdamKorcz/go-fuzz-headers v0.0.0-20210312213058-32f4d319f0d2 // indirect - github.com/Microsoft/go-winio v0.5.1 // indirect + github.com/Microsoft/go-winio v0.5.2 // indirect github.com/apex/log v1.4.0 // indirect github.com/charmbracelet/bubbles v0.13.0 // indirect github.com/charmbracelet/bubbletea v0.22.0 // indirect github.com/charmbracelet/lipgloss v0.5.0 // indirect github.com/containerd/console v1.0.3 // indirect - github.com/containerd/continuity v0.2.3-0.20220330195504-d132b287edc8 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/go-runc v1.0.0 // indirect github.com/containerd/typeurl v1.0.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/creack/pty v1.1.11 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect - github.com/docker/cli v20.10.13+incompatible // indirect - github.com/docker/docker v20.10.7+incompatible // indirect + github.com/docker/cli v20.10.17+incompatible // indirect github.com/docker/docker-credential-helpers v0.6.4 // indirect github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776 // indirect github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect @@ -86,9 +86,8 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c // indirect github.com/jessevdk/go-flags v1.4.0 // indirect - github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/compress v1.15.7 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/klauspost/pgzip v1.2.4 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -101,20 +100,16 @@ require ( github.com/muesli/cancelreader v0.2.1 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect - github.com/opencontainers/runc v1.1.1 // indirect + github.com/opencontainers/runc v1.1.3 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/term v1.2.0-beta.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rootless-containers/proto v0.1.0 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/sergi/go-diff v1.1.0 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect - github.com/square/certstrap v1.3.0 // indirect - github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274 // indirect + github.com/tonistiigi/fsutil v0.0.0-20220510150904-0dbf3a8a7d58 // indirect github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect - github.com/urfave/cli v1.22.9 // indirect github.com/vbatts/go-mtree v0.5.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect @@ -129,15 +124,15 @@ require ( golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/tools v0.1.10 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect + google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) // BEGIN SYNC buildkit -replace github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible +replace github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220414164044-61404de7df1a+incompatible // END SYNC diff --git a/go.sum b/go.sum index 744f5904..1b3a4eb9 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -48,9 +47,9 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= @@ -110,19 +109,19 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.6.3-0.20220401172941-5ff8fce1fcc6 h1:nig7zto6cp3Wt1lPMK8EmyP6f/ZNmn/tL6ASQ7stews= -github.com/containerd/containerd v1.6.3-0.20220401172941-5ff8fce1fcc6/go.mod h1:WSt2SnDLAGWlu+Vl+EWay37seZLKqgRt6XLjIMy8SYM= +github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0= +github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/continuity v0.2.3-0.20220330195504-d132b287edc8 h1:yGFEcFNMhze29DxAAB33v/1OMRYF/cM9iwwgV2P0ZrE= -github.com/containerd/continuity v0.2.3-0.20220330195504-d132b287edc8/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU= github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0= github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= @@ -136,7 +135,6 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -156,12 +154,12 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/cli v20.10.13+incompatible h1:o/STAn7e+b/pQ6keReGRoewVmAgXUkZAMQ8st4vHdKg= -github.com/docker/cli v20.10.13+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY= -github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible h1:Ptj2To+ezU/mCBUKdYXBQ2r3/2EJojAlOZrsgprF+is= -github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= +github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.3-0.20220414164044-61404de7df1a+incompatible h1:jnhU41Zm9biz6e4GPOvAtuognZ+pi8S77ZlRir/SHRA= +github.com/docker/docker v20.10.3-0.20220414164044-61404de7df1a+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -174,8 +172,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -305,8 +303,6 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0= -github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -314,6 +310,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/in-toto/in-toto-golang v0.3.3 h1:tkkEBU5i09UEeWKnrp6Rq4fXKAfpVXYMLRO5mDfnb3I= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -329,8 +326,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.7 h1:7cgTQxJCU/vy+oP/E3B9RGbQTgbiVzIJWIKOLoAsPok= +github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A= @@ -389,12 +386,12 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063 h1:V7s6vhIrNeOqocziAmRoVJh6gnPPx83ovlpT7Hf5shI= github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063/go.mod h1:rkFeDZ0gc+YbnrXPw0q2RlI0QRuKBBPu67fgYIyGRNg= -github.com/moby/buildkit v0.10.3 h1:/dGykD8FW+H4p++q5+KqKEo6gAkYKyBQHdawdjVwVAU= -github.com/moby/buildkit v0.10.3/go.mod h1:jxeOuly98l9gWHai0Ojrbnczrk/rf+o9/JqNhY+UCSo= +github.com/moby/buildkit v0.10.1-0.20220826012947-46c8b9ee45d0 h1:LCGBQM8P/GrQ41zFuLg10ey20n0ZEPquYBxZ/LkM09U= +github.com/moby/buildkit v0.10.1-0.20220826012947-46c8b9ee45d0/go.mod h1:g7HO1tvhm/frAzTc9tjPUPkQefHWxdGAqz2hscGrOyo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo= -github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= +github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/signal v0.6.0 h1:aDpY94H8VlhTGa9sNYUFCFsMZIUh5wm0B6XkIoJj/iY= github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -440,13 +437,13 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v1.0.0-rc90/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.1.1 h1:PJ9DSs2sVwE0iVr++pAHE6QkS9tzcVWozlPifdwMgrU= -github.com/opencontainers/runc v1.1.1/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.10.1 h1:09LIPVRP3uuZGQvgR+SgMSNBd1Eb3vlRbGqQpoHsF8w= github.com/opencontainers/umoci v0.4.7 h1:mbIbtMpZ3v9oMpKaLopnWoLykgmnixeLzq51EzAX5nQ= github.com/opencontainers/umoci v0.4.7/go.mod h1:lgJ4bnwJezsN1o/5d7t/xdRPvmf8TvBko5kKYJsYvgo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -484,18 +481,17 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rootless-containers/proto v0.1.0 h1:gS1JOMEtk1YDYHCzBAf/url+olMJbac7MTrgSeP6zh4= github.com/rootless-containers/proto v0.1.0/go.mod h1:vgkUFZbQd0gcE/K/ZwtE4MYjZPu0UNHLXIQxhyqAFh8= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/segmentio/textio v1.2.0 h1:Ug4IkV3kh72juJbG8azoSBlgebIbUUxVNrfFcKHfTSQ= github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHWiqtvY8ag= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shibumi/go-pathspec v1.2.0 h1:KVKEDHYk7bQolRMs7nfzjT3SBOCgcXFJzccnj9bsGbA= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -504,6 +500,7 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= @@ -543,18 +540,15 @@ github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eN github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274 h1:wbyZxD6IPFp0sl5uscMOJRsz5UKGFiNiD16e+MVfKZY= -github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274/go.mod h1:oPAfvw32vlUJSjyDcQ3Bu0nb2ON2B+G0dtVN/SZNJiA= +github.com/tonistiigi/fsutil v0.0.0-20220510150904-0dbf3a8a7d58 h1:rNya5ozLqz0lK46XhmsmqJuxmQLM8dAWabiT+5gZqLY= +github.com/tonistiigi/fsutil v0.0.0-20220510150904-0dbf3a8a7d58/go.mod h1:oPAfvw32vlUJSjyDcQ3Bu0nb2ON2B+G0dtVN/SZNJiA= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f h1:DLpt6B5oaaS8jyXHa9VA4rrZloBVPVXeCtrOsrFauxc= github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= -github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vbatts/go-mtree v0.5.0 h1:dM+5XZdqH0j9CSZeerhoN/tAySdwnmevaZHO1XGW2Vc= github.com/vbatts/go-mtree v0.5.0/go.mod h1:7JbaNHyBMng+RP8C3Q4E+4Ca8JnGQA2R/MB+jb4tSOk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -769,7 +763,6 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -840,8 +833,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -972,8 +965,8 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 h1:FglFEfyj61zP3c6LgjmVHxYxZWXYul9oiS1EZqD5gLc= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -994,11 +987,10 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1038,8 +1030,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 3bcf11dd..879bf6fd 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -17,6 +17,7 @@ import ( "github.com/adrg/xdg" "github.com/containerd/containerd/platforms" + dockerconfig "github.com/docker/cli/cli/config" "github.com/docker/distribution/reference" "github.com/hashicorp/go-multierror" "github.com/moby/buildkit/client" @@ -127,7 +128,7 @@ func NewBuildkit(ctx context.Context, _ bass.RuntimePool, cfg *bass.Scope) (bass Client: client, Platform: platform, - authp: authprovider.NewDockerAuthProvider(os.Stderr), + authp: authprovider.NewDockerAuthProvider(dockerconfig.LoadDefaultConfigFile(os.Stderr)), }, nil } diff --git a/pkg/runtimes/util/buildkitd/buildkitd.go b/pkg/runtimes/util/buildkitd/buildkitd.go index 73c38d4e..af69334a 100644 --- a/pkg/runtimes/util/buildkitd/buildkitd.go +++ b/pkg/runtimes/util/buildkitd/buildkitd.go @@ -21,7 +21,7 @@ import ( ) // bumped by hack/bump-buildkit -const Version = "v0.10.3" +const Version = "master" const ( image = "basslang/buildkit" From 7d83b95031944509cdb704aefc77e3f9ff725117 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 00:22:38 -0400 Subject: [PATCH 05/32] add test for TLS cert generation --- pkg/runtimes/suite.go | 4 ++++ pkg/runtimes/testdata/tls.bass | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 pkg/runtimes/testdata/tls.bass diff --git a/pkg/runtimes/suite.go b/pkg/runtimes/suite.go index 50281d3e..e7fc6862 100644 --- a/pkg/runtimes/suite.go +++ b/pkg/runtimes/suite.go @@ -210,6 +210,10 @@ func Suite(t *testing.T, pool bass.RuntimePool) { File: "addrs.bass", Result: bass.String("hello, world!"), }, + { + File: "tls.bass", + Result: bass.Bool(true), + }, } { test := test t.Run(filepath.Base(test.File), func(t *testing.T) { diff --git a/pkg/runtimes/testdata/tls.bass b/pkg/runtimes/testdata/tls.bass new file mode 100644 index 00000000..3a52d89c --- /dev/null +++ b/pkg/runtimes/testdata/tls.bass @@ -0,0 +1,12 @@ +(use (.regexp)) + +(def reflect + (-> ($ openssl x509 -in ./cert.pem -noout -subject) + (with-image (linux/nixery.dev/openssl)) + (with-tls ./cert.pem ./key.pem))) + +; the certificate name should match the thunk's name +(let [subject (next (read reflect :raw))] + (regexp:case subject + ".*CN\\s*=\\s*(\\w+)" + (= (path-name reflect) $1))) From f34a1dd101ee3b5aad7a7d3b806282857eeaddf4 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 00:30:05 -0400 Subject: [PATCH 06/32] bump nix vendorsha --- nix/vendorSha256.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/vendorSha256.txt b/nix/vendorSha256.txt index b8a223f8..a4e18484 100644 --- a/nix/vendorSha256.txt +++ b/nix/vendorSha256.txt @@ -1 +1 @@ -sha256-MsCqrSxISHbOKHTc1brHyInzu1KblwBVQ6rbHnTK4GA= +sha256-O41vov8FQLY0/mOR8Zdqmg7D2vWRgHfam/qkMSB8VF0= From d6aa2f328e77233ef918c1ee72adc8890abfbaab Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 00:31:04 -0400 Subject: [PATCH 07/32] remove explicit .dns.bass this is handled by a search domain now --- pkg/runtimes/buildkit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 879bf6fd..27dfdb26 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -567,7 +567,7 @@ func (d *portHealthChecker) doBuild(ctx context.Context, gw gwclient.Client) (*g defer container.Release(ctx) - args := []string{shimExePath, "check", d.host + ".dns.bass"} + args := []string{shimExePath, "check", d.host} for _, port := range d.ports { args = append(args, fmt.Sprintf("%s:%d", port.Name, port.Port)) } From ddff61998bf8bac658abbc9202b226435eaadaf3 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 00:38:37 -0400 Subject: [PATCH 08/32] override dns address for test buildkit --- bass/buildkit.bass | 7 ++++++- pkg/runtimes/util/buildkitd/buildkitd.go | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/bass/buildkit.bass b/bass/buildkit.bass index f6014af5..738d5a8b 100644 --- a/bass/buildkit.bass +++ b/bass/buildkit.bass @@ -76,4 +76,9 @@ (def test-config (mkfs ./test.conflist (json (cni-config "bass" "10.73.0.0/16")) - ./buildkitd.toml (buildkitd-toml ./test.conflist)))) + ./buildkitd.toml (str (buildkitd-toml ./test.conflist) + "\n" + ; override the default nameserver + "[dns]\n" + "nameservers = [\"10.73.0.1\"]\n"))) + ) diff --git a/pkg/runtimes/util/buildkitd/buildkitd.go b/pkg/runtimes/util/buildkitd/buildkitd.go index af69334a..59a8ff79 100644 --- a/pkg/runtimes/util/buildkitd/buildkitd.go +++ b/pkg/runtimes/util/buildkitd/buildkitd.go @@ -31,6 +31,10 @@ const ( // Long timeout to allow for slow image pulls of // buildkitd while not blocking for infinity lockTimeout = 10 * time.Minute + + // coordinate with bass/buildkit.bass + bassGateway = "10.64.0.1" + bassDNS = "dns.bass" ) func Start(ctx context.Context) (string, error) { @@ -198,8 +202,8 @@ func installBuildkit(ctx context.Context) error { "-v", volumeName + ":/var/lib/buildkit", "--name", containerName, "--privileged", - "--dns", "10.64.0.1", - "--dns-search", "dns.bass", + "--dns", bassGateway, + "--dns-search", bassDNS, } for _, ns := range resolvconf.GetNameservers(rc.Content, resolvconf.IP) { From 57c027d86f1ecb2e71a3c8cfc8bc5a0ca3543139 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 00:50:05 -0400 Subject: [PATCH 09/32] buildkit in docker: get rid of --net=host --- pkg/runtimes/util/buildkitd/buildkitd.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/runtimes/util/buildkitd/buildkitd.go b/pkg/runtimes/util/buildkitd/buildkitd.go index 59a8ff79..ae088ddb 100644 --- a/pkg/runtimes/util/buildkitd/buildkitd.go +++ b/pkg/runtimes/util/buildkitd/buildkitd.go @@ -24,7 +24,6 @@ import ( const Version = "master" const ( - image = "basslang/buildkit" containerName = "bass-buildkitd" volumeName = "bass-buildkitd" @@ -32,6 +31,9 @@ const ( // buildkitd while not blocking for infinity lockTimeout = 10 * time.Minute + // built from bass/buildkit.bass + image = "basslang/buildkit" + // coordinate with bass/buildkit.bass bassGateway = "10.64.0.1" bassDNS = "dns.bass" @@ -104,7 +106,7 @@ func checkBuildkit(ctx context.Context) error { zap.Bool("isActive", config.IsActive), zap.Bool("haveHostNetwork", config.HaveHostNetwork)) - if config.Version != Version || !config.HaveHostNetwork { + if config.Version != Version || config.HaveHostNetwork { logger.Info("upgrading buildkit", zap.String("version", Version), zap.Bool("have host network", config.HaveHostNetwork)) @@ -196,7 +198,6 @@ func installBuildkit(ctx context.Context) error { dockerArgs := []string{ "run", - "--net=host", "-d", "--restart", "always", "-v", volumeName + ":/var/lib/buildkit", @@ -225,11 +226,6 @@ func installBuildkit(ctx context.Context) error { "--debug", ) - // FIXME: buildkitd currently runs without network isolation (--net=host) - // in order for containers to be able to reach localhost. - // This is required for things such as kubectl being able to - // reach a KinD/minikube cluster locally - // #nosec cmd = exec.CommandContext(ctx, "docker", dockerArgs...) output, err = cmd.CombinedOutput() if err != nil { From 45f52841b911c792399dc14e5b89cb2a88c49a54 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 03:01:02 -0400 Subject: [PATCH 10/32] shim: install bass CA so thunks trust each other --- Makefile | 2 +- pkg/runtimes/buildkit.go | 12 ++++ pkg/runtimes/shim/main.go | 74 ++-------------------- pkg/runtimes/shim/tls.go | 130 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 70 deletions(-) create mode 100644 pkg/runtimes/shim/tls.go diff --git a/Makefile b/Makefile index fab34762..bacd580b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ shims=$(foreach arch,$(arches),pkg/runtimes/bin/exe.$(arch)) all: cmd/bass/bass -pkg/runtimes/bin/exe.%: pkg/runtimes/shim/main.go +pkg/runtimes/bin/exe.%: pkg/runtimes/shim/*.go env GOOS=linux GOARCH=$* CGO_ENABLED=0 go build -ldflags "-s -w" -o $@ ./pkg/runtimes/shim cmd/bass/bass: shims diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 27dfdb26..b8459310 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -66,6 +66,7 @@ const workDir = "/bass/work" const ioDir = "/bass/io" const inputFile = "/bass/io/in" const outputFile = "/bass/io/out" +const caFile = "/bass/ca.crt" const digestBucket = "_digests" const configBucket = "_configs" @@ -632,6 +633,11 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru return llb.ExecState{}, "", false, err } + rootCA, err := os.ReadFile(basstls.CACert) + if err != nil { + return llb.ExecState{}, "", false, err + } + runOpt := []llb.RunOption{ llb.WithCustomName(thunk.Cmdline()), // NB: this is load-bearing; it's what busts the cache with different labels @@ -643,6 +649,10 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru llb.WithCustomName("[hide] mount command json"), )), llb.AddMount(shimExePath, shimExe, llb.SourcePath("run")), + llb.AddMount(caFile, llb.Scratch().File( + llb.Mkfile("ca.crt", 0600, rootCA), + llb.WithCustomName("[hide] mount bass ca"), + ), llb.SourcePath("ca.crt")), llb.With(llb.Dir(workDir)), llb.Args([]string{shimExePath, "run", inputFile}), } @@ -668,6 +678,7 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru thunk.TLS.Cert.FromSlash(), llb.Scratch().File( llb.Mkfile(thunk.TLS.Cert.Name(), 0600, crtContent), + llb.WithCustomName("[hide] mount thunk tls cert"), ), llb.SourcePath(thunk.TLS.Cert.Name()), ), @@ -675,6 +686,7 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru thunk.TLS.Key.FromSlash(), llb.Scratch().File( llb.Mkfile(thunk.TLS.Key.Name(), 0600, keyContent), + llb.WithCustomName("[hide] mount thunk tls key"), ), llb.SourcePath(thunk.TLS.Key.Name()), ), diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index 3a95bdd4..9ca4b618 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -45,18 +45,12 @@ type Command struct { } var stdoutPath string -var pingAddr string func init() { stdoutPath = os.Getenv("_BASS_OUTPUT") os.Unsetenv("_BASS_OUTPUT") - - pingAddr = os.Getenv("_BASS_PING") - os.Unsetenv("_BASS_PING") } -const cidr = "10.0.0.0/8" - var cmds = map[string]func([]string) error{ "run": run, "unpack": unpack, @@ -110,15 +104,13 @@ func run(args []string) error { return fmt.Errorf("reap: %w", err) } - cmdPath := args[0] - - if pingAddr != "" { - err := ping(pingAddr) - if err != nil { - return err - } + err = installCert() + if err != nil { + return fmt.Errorf("install bass CA: %w", err) } + cmdPath := args[0] + cmdPayload, err := os.ReadFile(cmdPath) if err != nil { return fmt.Errorf("read cmd: %w", err) @@ -534,62 +526,6 @@ func check(args []string) error { return nil } -func containerIP() (net.IP, error) { - ifaces, err := net.Interfaces() - if err != nil { - return nil, err - } - - _, blk, err := net.ParseCIDR(cidr) - if err != nil { - return nil, err - } - - for _, i := range ifaces { - addrs, err := i.Addrs() - if err != nil { - return nil, err - } - - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - ip = v.IP - case *net.IPAddr: - ip = v.IP - } - - if blk.Contains(ip) { - return ip, nil - } - } - } - - return nil, fmt.Errorf("could not determine container IP (must be in %s)", cidr) -} - -func ping(addr string) error { - ip, err := containerIP() - if err != nil { - return err - } - - conn, err := net.Dial("tcp", pingAddr) - if err != nil { - return fmt.Errorf("ping: %w", err) - } - - defer conn.Close() - - _, err = io.WriteString(conn, ip.String()) - if err != nil { - return fmt.Errorf("write host: %w", err) - } - - return nil -} - func pollForPort(logger *zap.Logger, addr string) error { retry := backoff.NewExponentialBackOff() retry.InitialInterval = 100 * time.Millisecond diff --git a/pkg/runtimes/shim/tls.go b/pkg/runtimes/shim/tls.go new file mode 100644 index 00000000..15a63435 --- /dev/null +++ b/pkg/runtimes/shim/tls.go @@ -0,0 +1,130 @@ +// Copyright 2018 The mkcert Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "io" + "os" + "os/exec" + "path/filepath" +) + +var ( + BassCAFile = "/bass/ca.crt" + + SystemTrustFilename string + SystemTrustCommand []string + + SystemTrustFile string +) + +var trusts = map[string][]string{ + "/usr/local/share/ca-certificates/%s.crt": { + "update-ca-certificates", + }, + "/usr/share/pki/trust/anchors/%s.pem": { + "update-ca-certificates", + }, + "/etc/pki/ca-trust/source/anchors/%s.pem": { + "update-ca-trust", "extract", + }, + "/etc/ca-certificates/trust-source/anchors/%s.crt": { + "trust", "extract-compat", + }, +} + +var bundles = []string{ + // alpine, ubuntu + "/etc/ssl/certs/ca-certificates.crt", + // nixery + "/etc/ssl/certs/ca-bundle.crt", +} + +func init() { + if SystemTrustFilename != "" { + SystemTrustFile = fmt.Sprintf(SystemTrustFilename, "bass") + } +} + +func pathExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} + +func binaryExists(name string) bool { + _, err := exec.LookPath(name) + return err == nil +} + +func installCert() error { + // first try to install gracefully to the system trust + for pathTemplate, cmd := range trusts { + if _, err := os.Stat(filepath.Dir(pathTemplate)); err != nil { + continue + } + + trustPath := fmt.Sprintf(pathTemplate, "bass") + + cert, err := os.ReadFile(BassCAFile) + if err != nil { + return fmt.Errorf("read bass CA: %w", err) + } + + if err := os.WriteFile(trustPath, cert, 0600); err != nil { + return fmt.Errorf("write bass CA to system trust: %w", err) + } + + if _, err := exec.LookPath(cmd[0]); err != nil { + // installer not found; fall back on injecting + break + } + + out, err := exec.Command(cmd[0], cmd[1:]...).CombinedOutput() + if err != nil { + return fmt.Errorf("failed to install cert: %w\n\noutput:\n\n%s", err, string(out)) + } + + return nil + } + + return injectCert() +} + +func injectCert() error { + for _, path := range bundles { + if _, err := os.Stat(path); err != nil { + continue + } + + bundle, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0600) + if err != nil { + return err + } + + cert, err := os.Open(BassCAFile) + if err != nil { + return err + } + + if _, err := bundle.Seek(0, os.SEEK_END); err != nil { + return err + } + + if _, err := bundle.WriteString("\n"); err != nil { + return err + } + + if _, err := io.Copy(bundle, cert); err != nil { + return err + } + + return nil + } + + // this is best-effort + + return nil +} From f609f51ecbf8da4cdbe0dfbd203168415c2af099 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 03:01:28 -0400 Subject: [PATCH 11/32] add registry mirror demo --- demos/registry-mirror.bass | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 demos/registry-mirror.bass diff --git a/demos/registry-mirror.bass b/demos/registry-mirror.bass new file mode 100644 index 00000000..046a44a5 --- /dev/null +++ b/demos/registry-mirror.bass @@ -0,0 +1,48 @@ +(use (.strings)) + +(def config + {:version "0.1" + :http {:addr "0.0.0.0:5000" + :tls {:certificate "/registry.crt" + :key "/registry.key"}} + :storage {:filesystem {:rootdirectory "/var/lib/registry"}} + :proxy {:remoteurl "https://registry-1.docker.io"}}) + +(def mirror + (-> ($ registry serve (mkfile ./config.yml (json config))) + (with-image (linux/registry)) + (with-mount (cache-dir "registry-mirror") /var/lib/registry/) + (with-tls /registry.crt /registry.key) + (with-port :http 5000))) + +(defn resolver [thunk platform names] + (fn optional + (case optional + [] + (let [expand (case names [lib] ["library" lib] _ names) + repository (str "$host:$port/" (strings:join "/" expand))] + (resolve {:platform platform + :repository (addr thunk :http repository) + :tag "latest"})) + + [dep] + (resolver thunk platform (conj names (path-name dep))) + + _ + (error "invalid image path segment" :segment optional)))) + +(def xunil + (resolver mirror {:os "linux"} [])) + +(defn main [] + ; buildkit -> thunk TLS + (-> ($ echo "I'm mirrored!") + (with-image (xunil/alpine)) + run) + + ; thunk -> thunk TLS + (-> ($ wget -O- (addr mirror :http "https://$host:$port/v2/library/alpine/manifests/latest")) + (with-image (xunil/alpine)) + (read :json) + next + dump)) From 89ded3fdfd5352eae4273adef7cc320e35f8b8be Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 11:04:55 -0400 Subject: [PATCH 12/32] more thorough TLS test that covers thunk->thunk --- pkg/runtimes/testdata/tls.bass | 40 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/pkg/runtimes/testdata/tls.bass b/pkg/runtimes/testdata/tls.bass index 3a52d89c..cc5187b5 100644 --- a/pkg/runtimes/testdata/tls.bass +++ b/pkg/runtimes/testdata/tls.bass @@ -1,12 +1,32 @@ (use (.regexp)) -(def reflect - (-> ($ openssl x509 -in ./cert.pem -noout -subject) - (with-image (linux/nixery.dev/openssl)) - (with-tls ./cert.pem ./key.pem))) - -; the certificate name should match the thunk's name -(let [subject (next (read reflect :raw))] - (regexp:case subject - ".*CN\\s*=\\s*(\\w+)" - (= (path-name reflect) $1))) +(def config + {:version "0.1" + :http {:addr "0.0.0.0:5000" + :tls {:certificate "/registry.crt" + :key "/registry.key"}} + :storage {:filesystem {:rootdirectory "/var/lib/registry"}} + :proxy {:remoteurl "https://registry-1.docker.io"}}) + +(def mirror + (-> ($ registry serve (mkfile ./config.yml (json config))) + (with-image (linux/registry)) + (with-mount (cache-dir "registry-mirror") /var/lib/registry/) + (with-tls /registry.crt /registry.key) + (with-port :http 5000))) + +; buildkit -> thunk TLS +(def image + (resolve {:platform {:os "linux"} + :repository (addr mirror :http "$host:$port/library/alpine") + :tag "latest"})) + +; thunk -> thunk TLS +(def manifest + (from image + ($ wget -O- + (addr mirror :http + "https://$host:$port/v2/library/alpine/manifests/latest")))) + +(= (-> manifest (read :json) next :tag) + "latest") From 3d6f7bf80a70aa24172ae7437ec4f66954097396 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 12:59:43 -0400 Subject: [PATCH 13/32] set up DNS + TLS appropriately for test buildkit --- bass/bass.bass | 7 ++++-- cmd/bass/main.go | 2 +- pkg/basstls/basstls.go | 18 ++++++++++------ pkg/runtimes/buildkit.go | 9 ++++++-- pkg/runtimes/buildkit_test.go | 3 +++ pkg/runtimes/testdata/tls/bass.crt | 20 ++++++++++++++++++ pkg/runtimes/testdata/tls/bass.key | 27 ++++++++++++++++++++++++ pkg/runtimes/util/buildkitd/buildkitd.go | 3 ++- 8 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 pkg/runtimes/testdata/tls/bass.crt create mode 100644 pkg/runtimes/testdata/tls/bass.key diff --git a/bass/bass.bass b/bass/bass.bass index 6ae6e17a..85122e4b 100644 --- a/bass/bass.bass +++ b/bass/bass.bass @@ -129,15 +129,18 @@ (map (fn [image] (check-dist dist image)) smoke-tests)) - (defn test-buildkit [os arch] + (defn test-buildkit [os arch cert] (-> ($ buildkitd --addr "tcp://0.0.0.0:6107") (with-image (buildkit:image os arch buildkit:test-config)) (with-mount (cache-dir "bass buildkitd") /var/lib/buildkit/) + (with-mount cert /etc/ssl/certs/bass.crt) + (with-mount (mkfile ./resolv.conf "nameserver 10.73.0.1\nnameserver 1.1.1.1\nsearch dns.bass\n") /etc/resolv.conf) (with-port :grpc 6107) insecure!)) (defn with-bass-and-buildkitd [thunk src] - (let [buildkit-host (addr (test-buildkit "linux" "amd64") :grpc "tcp://$host:$port") + (let [buildkit (test-buildkit "linux" "amd64" src/pkg/runtimes/testdata/tls/bass.crt) + buildkit-host (addr buildkit :grpc "tcp://$host:$port") built-bass (dist src "dev" "linux" "amd64")] (-> thunk (with-env {:BUILDKIT_HOST buildkit-host}) diff --git a/cmd/bass/main.go b/cmd/bass/main.go index 9d963073..f6feac82 100644 --- a/cmd/bass/main.go +++ b/cmd/bass/main.go @@ -150,7 +150,7 @@ func root(ctx context.Context) error { return err } - err = basstls.Init() + err = basstls.Init(basstls.DefaultDir) if err != nil { cli.WriteError(ctx, err) return err diff --git a/pkg/basstls/basstls.go b/pkg/basstls/basstls.go index 5a9faefe..037f7682 100644 --- a/pkg/basstls/basstls.go +++ b/pkg/basstls/basstls.go @@ -23,13 +23,19 @@ const ( ) var ( - Dir = filepath.Join(xdg.ConfigHome, "bass", "tls") - CACert = filepath.Join(Dir, CAName+".crt") + // DefaultDir is the canonical location to store certs on the user's + // local machine. + DefaultDir = filepath.Join(xdg.ConfigHome, "bass", "tls") ) +// CACert returns the path to the CA certificate in the given dir. +func CACert(dir string) string { + return filepath.Join(dir, CAName+".crt") +} + // Init initializes dir with a CA. -func Init() error { - d, err := depot.NewFileDepot(Dir) +func Init(dir string) error { + d, err := depot.NewFileDepot(dir) if err != nil { return fmt.Errorf("init depot: %w", err) } @@ -76,8 +82,8 @@ func Init() error { return nil } -func Generate(host string) (*pkix.Certificate, *pkix.Key, error) { - d, err := depot.NewFileDepot(Dir) +func Generate(dir, host string) (*pkix.Certificate, *pkix.Key, error) { + d, err := depot.NewFileDepot(dir) if err != nil { return nil, nil, fmt.Errorf("init depot: %w", err) } diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index b8459310..59f6848e 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -52,6 +52,7 @@ const buildkitProduct = "bass" type BuildkitConfig struct { Addr string `json:"addr,omitempty"` DisableCache bool `json:"disable_cache,omitempty"` + CertsDir string `json:"certs_dir,omitempty"` } var _ bass.Runtime = &Buildkit{} @@ -103,6 +104,10 @@ func NewBuildkit(ctx context.Context, _ bass.RuntimePool, cfg *bass.Scope) (bass } } + if config.CertsDir == "" { + config.CertsDir = basstls.DefaultDir + } + client, err := dialBuildkit(ctx, config.Addr) if err != nil { return nil, fmt.Errorf("dial buildkit: %w", err) @@ -633,7 +638,7 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru return llb.ExecState{}, "", false, err } - rootCA, err := os.ReadFile(basstls.CACert) + rootCA, err := os.ReadFile(basstls.CACert(b.runtime.Config.CertsDir)) if err != nil { return llb.ExecState{}, "", false, err } @@ -658,7 +663,7 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru } if thunk.TLS != nil { - crt, key, err := basstls.Generate(id) + crt, key, err := basstls.Generate(b.runtime.Config.CertsDir, id) if err != nil { return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) } diff --git a/pkg/runtimes/buildkit_test.go b/pkg/runtimes/buildkit_test.go index 8954bf48..eed0a5b4 100644 --- a/pkg/runtimes/buildkit_test.go +++ b/pkg/runtimes/buildkit_test.go @@ -25,6 +25,9 @@ func TestBuildkitRuntime(t *testing.T) { { Platform: bass.LinuxPlatform, Runtime: runtimes.BuildkitName, + Config: bass.Bindings{ + "certs_dir": bass.String("./testdata/tls/"), + }.Scope(), }, }, }) diff --git a/pkg/runtimes/testdata/tls/bass.crt b/pkg/runtimes/testdata/tls/bass.crt new file mode 100644 index 00000000..7284f910 --- /dev/null +++ b/pkg/runtimes/testdata/tls/bass.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJDQTEQ +MA4GA1UECBMHT250YXJpbzEQMA4GA1UEBxMHVG9yb250bzENMAsGA1UEAxMEYmFz +czAeFw0yMjA4MjYwMTUwNTNaFw0yMjEwMjkwMjAwNTNaMEAxCzAJBgNVBAYTAkNB +MRAwDgYDVQQIEwdPbnRhcmlvMRAwDgYDVQQHEwdUb3JvbnRvMQ0wCwYDVQQDEwRi +YXNzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs1YAdwMgr4MJQwa8 +c3i12yWxdbw0DjjZqDDN59CUpyGGVAk91S0IHSmsBjSvMZmH/tqEJQO1e6HK5eY/ +Ziy0ETbrVYhGtEPhCRVZAM7wVcqI2ZCY0lSSGhgD0/dlY0OW/DaxOTg/QI0UUQpX +3QJ8Jld4gDJLls6NFyu3o4N0Afag2ch6bpvSVX4p0dHYmovY2FTABEIFyJZ+LWsT +QYcL3jCNWVo8bNjGkKUjxqbfuCOiNx4gSyRgkZVvdv0e/K/bM6vC7dlKKVC2OSp0 +YGfLma1PpyqMjN91xVhg6CAutS+oV5YPU20vr9JC4qHgK6c5TFfRPae8aNjd+1sw +IyApnQIDAQABo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB +ADAdBgNVHQ4EFgQU1oiylsE9jj057p2W6pR/UqyGtoQwDQYJKoZIhvcNAQELBQAD +ggEBADTz1bKkERi8ZlOPvzXbDjL4KMU2ziMbphhN7o8jc7rrMHv1pb5M+33ZyB3h +JHUs3yKvMfEUO5u7vju5L1YTS0DkS9950F43+YnNtPqcvjRR5FfUH8zKFPajY7Ny +c4muQ5uX8PtF/C+gaNmAIT75l7J10YB/KssdUcjITZNwk7enfbrutil38wT1vNWt +UG5uh5O9V9qmQANwmEPex1ByfpL48euwykWSvFhgbpMW49v3Mo+i/vdm8MpIWkUL +aKVvsKgpowNYM8IQSf9v/ibvyFaLmMeYMDnMyJEgyR84KHxftmFWXYTybk/JAFen +9tH1Mg0hyeUDcQIgukWwg565N3w= +-----END CERTIFICATE----- diff --git a/pkg/runtimes/testdata/tls/bass.key b/pkg/runtimes/testdata/tls/bass.key new file mode 100644 index 00000000..0909c619 --- /dev/null +++ b/pkg/runtimes/testdata/tls/bass.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAs1YAdwMgr4MJQwa8c3i12yWxdbw0DjjZqDDN59CUpyGGVAk9 +1S0IHSmsBjSvMZmH/tqEJQO1e6HK5eY/Ziy0ETbrVYhGtEPhCRVZAM7wVcqI2ZCY +0lSSGhgD0/dlY0OW/DaxOTg/QI0UUQpX3QJ8Jld4gDJLls6NFyu3o4N0Afag2ch6 +bpvSVX4p0dHYmovY2FTABEIFyJZ+LWsTQYcL3jCNWVo8bNjGkKUjxqbfuCOiNx4g +SyRgkZVvdv0e/K/bM6vC7dlKKVC2OSp0YGfLma1PpyqMjN91xVhg6CAutS+oV5YP +U20vr9JC4qHgK6c5TFfRPae8aNjd+1swIyApnQIDAQABAoIBAQCxkt3g+lLaF1kL +alcdy4/e0GL4noO49WfoF3M7MBiRqSt2eLQmKnHXVpUEjBRRe6Hio4KnmBWStrDO +lf9+75LZXNUHm2nPQ0tHkEDSARaPDH4XWAtKcP0+IztfHp/g+2M8l/dCHkTbaRaN +7Dz2FWjTGleyMJsSV7HzGJG8sgQjj+TJfjFprLPdiNcS7/Ehs2R081o3eyc1eFox +PkLy9zmQz7sWlaJ7PT3VO2ep94tDllsA86Bx2D4lqxOTvUkvIfxa7S6x5Ornvbi6 +v5YMbg4HdaDr1IaR37D8ROzWmenKscsIbDuCJlWTtLNN++C6cWfd1gqTl6E3yS0F +QwgraXuhAoGBAMPcSGOk3sSuXz1jSVHPBzWNU6AzOyJa1dGK2Q6iPJCvmpRM1r2w +b7ZBZvXlXB6xTXRAABTR+woWobD48R+e5zfM+a9hZwmN5w7FiOKHlVB9UtkSf8Et +m80Uv4NIw0xZ4fytrJ2/xJ/KK2yKZgjKl+h8RiRxPKQXDKV9upNfYpwVAoGBAOpm +zJcH+0ZlaCnH2Nd0eHmV53EkdhUGtEjaWarksJ4wem333enGY2cEjllZGXgBS6Ro +TbTJ9poNxEcGKQNSTJ9ryVNSjTmOCnDU+L8DP/GXbfAdd/RGmnTXaG/gLvGS6sWH +qiixNfJJvfVokrLT7rWa/XKUjpSjo2MfRI4cfdFpAoGAYt7BYCOrHMgVZczIB1cm +AX+NNnKGKGqIQ1X/CmcVgchTlQdQ48K8MdnEGt8kaI4CVmu0Xs49FrOj/c09E0RI +3h9H76OQuv76I7fNyOS+mDobZ17yRNc8LgOKRcCmbdV1wfL+D0ft/ue0kf8vUMLM +ely5n83V2dOU27mjRJ/DDJ0CgYEAsiM57LXmItPCW65Df0pGnLBt2bCKBOS5cnxu +lM+D4lSZVqV/AsEAnjP6MrDiCC+D2whhtbmfLei0d/2Ygau0C5wQvsAID+uAx8sy +14eSuvoIVOkwVnapv45NEmjfhDvRLBk0GgTDKMUeFjlI85rY2S9W2hNIYHIUI6qJ +oS7J97ECgYEAq3+9kljKyFwDLZMbCDmx4oWH0ftbgmkQUQjTgbiXRXvBjDgxBgAw +jmUefppEcX9W6IERSL7i8a5lWIy/h9Vpo3ulG890jvfyr0AZ0AguygTbp1zR1OsF +uAMYlpLKHSKidWevu4+k1i76qzToaXxkgi2nPW9d8eJWzp0HQ2qEJyQ= +-----END RSA PRIVATE KEY----- diff --git a/pkg/runtimes/util/buildkitd/buildkitd.go b/pkg/runtimes/util/buildkitd/buildkitd.go index ae088ddb..6e756fc5 100644 --- a/pkg/runtimes/util/buildkitd/buildkitd.go +++ b/pkg/runtimes/util/buildkitd/buildkitd.go @@ -246,7 +246,8 @@ func installBuildkit(ctx context.Context) error { ctx, "docker", "cp", - basstls.CACert, containerName+":/etc/ssl/certs/bass.crt", + basstls.CACert(basstls.DefaultDir), + containerName+":/etc/ssl/certs/bass.crt", ) output, err = cmd.CombinedOutput() if err != nil { From d7549bfc4f27c1b5d3c7a97ec322e18dbd6927a1 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 13:26:21 -0400 Subject: [PATCH 14/32] install cert before reaping cert installation requires spawning a child process, so we don't want to be listening for SIGCHLD yet --- pkg/runtimes/shim/main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index 9ca4b618..d8b40a87 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -99,14 +99,14 @@ func run(args []string) error { return fmt.Errorf("usage: run ") } - err := reap() + err := installCert() if err != nil { - return fmt.Errorf("reap: %w", err) + return fmt.Errorf("install bass CA: %w", err) } - err = installCert() + err = reap() if err != nil { - return fmt.Errorf("install bass CA: %w", err) + return fmt.Errorf("reap: %w", err) } cmdPath := args[0] From c1e91c508f760f035fc0d7d8a53e9923ccc32513 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 19:41:43 -0400 Subject: [PATCH 15/32] fix permissions for test cert --- bass/bass.bass | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/bass/bass.bass b/bass/bass.bass index 85122e4b..f3470bb7 100644 --- a/bass/bass.bass +++ b/bass/bass.bass @@ -130,13 +130,16 @@ smoke-tests)) (defn test-buildkit [os arch cert] - (-> ($ buildkitd --addr "tcp://0.0.0.0:6107") - (with-image (buildkit:image os arch buildkit:test-config)) - (with-mount (cache-dir "bass buildkitd") /var/lib/buildkit/) - (with-mount cert /etc/ssl/certs/bass.crt) - (with-mount (mkfile ./resolv.conf "nameserver 10.73.0.1\nnameserver 1.1.1.1\nsearch dns.bass\n") /etc/resolv.conf) - (with-port :grpc 6107) - insecure!)) + (from (buildkit:image os arch buildkit:test-config) + ($ cp $cert /etc/ssl/certs/bass.crt) + ($ chmod "0600" /etc/ssl/certs/bass.crt) + (-> ($ buildkitd --addr "tcp://0.0.0.0:6107") + (with-mount (cache-dir "bass buildkitd") /var/lib/buildkit/) + (with-mount + (mkfile ./resolv.conf "nameserver 10.73.0.1\nnameserver 1.1.1.1\nsearch dns.bass\n") + /etc/resolv.conf) + (with-port :grpc 6107) + insecure!)) (defn with-bass-and-buildkitd [thunk src] (let [buildkit (test-buildkit "linux" "amd64" src/pkg/runtimes/testdata/tls/bass.crt) From c521c944d53ebd245edebe65f454f90c7dc3923e Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 19:58:59 -0400 Subject: [PATCH 16/32] fix syntax --- bass/bass.bass | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/bass/bass.bass b/bass/bass.bass index f3470bb7..bc4f943c 100644 --- a/bass/bass.bass +++ b/bass/bass.bass @@ -130,16 +130,17 @@ smoke-tests)) (defn test-buildkit [os arch cert] - (from (buildkit:image os arch buildkit:test-config) - ($ cp $cert /etc/ssl/certs/bass.crt) - ($ chmod "0600" /etc/ssl/certs/bass.crt) - (-> ($ buildkitd --addr "tcp://0.0.0.0:6107") - (with-mount (cache-dir "bass buildkitd") /var/lib/buildkit/) - (with-mount - (mkfile ./resolv.conf "nameserver 10.73.0.1\nnameserver 1.1.1.1\nsearch dns.bass\n") - /etc/resolv.conf) - (with-port :grpc 6107) - insecure!)) + (let [resolv (str "nameserver 10.73.0.1\n" + "nameserver 1.1.1.1\n" + "search dns.bass\n")] + (from (buildkit:image os arch buildkit:test-config) + ($ cp $cert /etc/ssl/certs/bass.crt) + ($ chmod "0600" /etc/ssl/certs/bass.crt) + (-> ($ buildkitd --addr "tcp://0.0.0.0:6107") + (with-mount (cache-dir "bass buildkitd") /var/lib/buildkit/) + (with-mount (mkfile ./resolv.conf resolv) /etc/resolv.conf) + (with-port :grpc 6107) + insecure!)))) (defn with-bass-and-buildkitd [thunk src] (let [buildkit (test-buildkit "linux" "amd64" src/pkg/runtimes/testdata/tls/bass.crt) From 783eeb5cf474a38f9a45b4a32199e3bdeea74f7a Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 19:59:12 -0400 Subject: [PATCH 17/32] refactor health check to prevent hanging previously if the thunk failed we'd keep waiting on the health check; now it'll be interrupted --- pkg/runtimes/buildkit.go | 75 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 59f6848e..961858d6 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -42,7 +42,6 @@ import ( "github.com/vito/progrock" "github.com/vito/progrock/graph" "go.uber.org/zap" - "golang.org/x/sync/errgroup" _ "embed" ) @@ -238,12 +237,16 @@ func (runtime *Buildkit) Start(ctx context.Context, thunk bass.Thunk) (StartResu host := thunk.Name() - health := runtime.newHealth(ctx, host, thunk.Ports) - - health.Start() + health := runtime.newHealth(host, thunk.Ports) runs := bass.RunsFromContext(ctx) + checked := make(chan error, 1) + runs.Go(stop, func() error { + checked <- health.Check(ctx) + return nil + }) + exited := make(chan error, 1) runs.Go(stop, func() error { exited <- runtime.build( @@ -255,26 +258,33 @@ func (runtime *Buildkit) Start(ctx context.Context, thunk bass.Thunk) (StartResu nil, // exports llb.IgnoreCache, // never cache services ) - return nil // disregard err; services don't have to exit cleanly + + return nil }) - result := StartResult{ - Ports: PortInfos{}, - } + select { + case <-checked: + result := StartResult{ + Ports: PortInfos{}, + } - for _, port := range thunk.Ports { - result.Ports[port.Name] = bass.Bindings{ - "host": bass.String(host), - "port": bass.Int(port.Port), - }.Scope() - } + for _, port := range thunk.Ports { + result.Ports[port.Name] = bass.Bindings{ + "host": bass.String(host), + "port": bass.Int(port.Port), + }.Scope() + } - err := health.Wait() - if err != nil { - return StartResult{}, err - } + return result, nil + case err := <-exited: + stop() // interrupt healthcheck - return result, nil + if err != nil { + return StartResult{}, err + } + + return StartResult{}, fmt.Errorf("service exited before healthcheck") + } } func (runtime *Buildkit) Read(ctx context.Context, w io.Writer, thunk bass.Thunk) error { @@ -502,38 +512,27 @@ func result(ctx context.Context, gw gwclient.Client, st marshalable) (*gwclient. type portHealthChecker struct { runtime *Buildkit - eg *errgroup.Group - ctx context.Context host string ports []bass.ThunkPort } -func (runtime *Buildkit) newHealth(ctx context.Context, host string, ports []bass.ThunkPort) *portHealthChecker { - eg, ctx := errgroup.WithContext(ctx) +func (runtime *Buildkit) newHealth(host string, ports []bass.ThunkPort) *portHealthChecker { return &portHealthChecker{ runtime: runtime, - eg: eg, - ctx: ctx, host: host, ports: ports, } } -func (d *portHealthChecker) Start() { - d.eg.Go(func() error { - _, err := d.runtime.Client.Build(d.ctx, kitdclient.SolveOpt{ - Session: []session.Attachable{ - d.runtime.authp, - }, - }, buildkitProduct, d.doBuild, nil) - return err - }) -} - -func (d *portHealthChecker) Wait() error { - return d.eg.Wait() +func (d *portHealthChecker) Check(ctx context.Context) error { + _, err := d.runtime.Client.Build(ctx, kitdclient.SolveOpt{ + Session: []session.Attachable{ + d.runtime.authp, + }, + }, buildkitProduct, d.doBuild, nil) + return err } func (d *portHealthChecker) doBuild(ctx context.Context, gw gwclient.Client) (*gwclient.Result, error) { From 3523c00cbc1cc69c6381755983254f1a057721aa Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 20:17:54 -0400 Subject: [PATCH 18/32] adjust perms for tls fixtures at test runtime certstrap checks perms, can't exceed r--r--r-- --- bass/bass.bass | 2 +- pkg/runtimes/buildkit.go | 6 +++--- pkg/runtimes/buildkit_test.go | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bass/bass.bass b/bass/bass.bass index bc4f943c..d63dcb70 100644 --- a/bass/bass.bass +++ b/bass/bass.bass @@ -135,7 +135,7 @@ "search dns.bass\n")] (from (buildkit:image os arch buildkit:test-config) ($ cp $cert /etc/ssl/certs/bass.crt) - ($ chmod "0600" /etc/ssl/certs/bass.crt) + ($ chmod "0400" /etc/ssl/certs/bass.crt) (-> ($ buildkitd --addr "tcp://0.0.0.0:6107") (with-mount (cache-dir "bass buildkitd") /var/lib/buildkit/) (with-mount (mkfile ./resolv.conf resolv) /etc/resolv.conf) diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 961858d6..4f46b13b 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -664,17 +664,17 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru if thunk.TLS != nil { crt, key, err := basstls.Generate(b.runtime.Config.CertsDir, id) if err != nil { - return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) + return llb.ExecState{}, "", false, fmt.Errorf("tls: generate: %w", err) } crtContent, err := crt.Export() if err != nil { - return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) + return llb.ExecState{}, "", false, fmt.Errorf("export crt: %w", err) } keyContent, err := key.ExportPrivate() if err != nil { - return llb.ExecState{}, "", false, fmt.Errorf("init tls: %w", err) + return llb.ExecState{}, "", false, fmt.Errorf("export key: %w", err) } runOpt = append(runOpt, diff --git a/pkg/runtimes/buildkit_test.go b/pkg/runtimes/buildkit_test.go index eed0a5b4..a6e9fc9e 100644 --- a/pkg/runtimes/buildkit_test.go +++ b/pkg/runtimes/buildkit_test.go @@ -2,6 +2,7 @@ package runtimes_test import ( "context" + "os" "testing" _ "github.com/moby/buildkit/client" @@ -20,6 +21,9 @@ func TestBuildkitRuntime(t *testing.T) { ctx := context.Background() + is.NoErr(os.Chmod("./testdata/tls/bass.crt", 0400)) + is.NoErr(os.Chmod("./testdata/tls/bass.key", 0400)) + pool, err := runtimes.NewPool(ctx, &bass.Config{ Runtimes: []bass.RuntimeConfig{ { From 7769e7a45fcc57e59f581f57de42bf91b4e3b999 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 20:41:01 -0400 Subject: [PATCH 19/32] try 1.1.1.1 first --- bass/bass.bass | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bass/bass.bass b/bass/bass.bass index d63dcb70..2310b9b4 100644 --- a/bass/bass.bass +++ b/bass/bass.bass @@ -130,8 +130,8 @@ smoke-tests)) (defn test-buildkit [os arch cert] - (let [resolv (str "nameserver 10.73.0.1\n" - "nameserver 1.1.1.1\n" + (let [resolv (str "nameserver 1.1.1.1\n" + "nameserver 10.73.0.1\n" "search dns.bass\n")] (from (buildkit:image os arch buildkit:test-config) ($ cp $cert /etc/ssl/certs/bass.crt) From 7ad1c0293ec3446d4b4f45eba7929d3ec1668c98 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 20:46:53 -0400 Subject: [PATCH 20/32] add 1.1.1.1 to test buildkitd config --- bass/bass.bass | 4 ++-- bass/buildkit.bass | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bass/bass.bass b/bass/bass.bass index 2310b9b4..d63dcb70 100644 --- a/bass/bass.bass +++ b/bass/bass.bass @@ -130,8 +130,8 @@ smoke-tests)) (defn test-buildkit [os arch cert] - (let [resolv (str "nameserver 1.1.1.1\n" - "nameserver 10.73.0.1\n" + (let [resolv (str "nameserver 10.73.0.1\n" + "nameserver 1.1.1.1\n" "search dns.bass\n")] (from (buildkit:image os arch buildkit:test-config) ($ cp $cert /etc/ssl/certs/bass.crt) diff --git a/bass/buildkit.bass b/bass/buildkit.bass index 738d5a8b..5e8861f6 100644 --- a/bass/buildkit.bass +++ b/bass/buildkit.bass @@ -80,5 +80,5 @@ "\n" ; override the default nameserver "[dns]\n" - "nameservers = [\"10.73.0.1\"]\n"))) + "nameservers = [\"10.73.0.1\", \"1.1.1.1\"]\n"))) ) From d94a9d46470492dd0ae91c40c1a50d668f84e888 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 21:43:58 -0400 Subject: [PATCH 21/32] use bass.lock in tests to prevent rate limit --- pkg/runtimes/suite.go | 2 + pkg/runtimes/testdata/bass.lock | 252 ++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) diff --git a/pkg/runtimes/suite.go b/pkg/runtimes/suite.go index e7fc6862..a1f74123 100644 --- a/pkg/runtimes/suite.go +++ b/pkg/runtimes/suite.go @@ -335,6 +335,8 @@ func RunTest(ctx context.Context, t *testing.T, pool bass.RuntimePool, file stri Stdout: bass.NewSink(bass.NewJSONSink("stdout", vtx.Stdout())), }) + scope.Set("*memos*", bass.NewHostPath("./testdata/", bass.ParseFileOrDirPath("bass.lock"))) + source := bass.NewFSPath(testdata.FS, bass.ParseFileOrDirPath(file)) res, err := bass.EvalFSFile(ctx, scope, source) diff --git a/pkg/runtimes/testdata/bass.lock b/pkg/runtimes/testdata/bass.lock index f4b123b1..fe888c1a 100644 --- a/pkg/runtimes/testdata/bass.lock +++ b/pkg/runtimes/testdata/bass.lock @@ -92,5 +92,257 @@ memos: { } } } + results: { + input: { + array: { + values: { + object: { + bindings: { + symbol: "platform" + value: { + object: { + bindings: { + symbol: "os" + value: { + string: { + value: "linux" + } + } + } + } + } + } + bindings: { + symbol: "repository" + value: { + string: { + value: "registry" + } + } + } + bindings: { + symbol: "tag" + value: { + string: { + value: "latest" + } + } + } + } + } + } + } + output: { + object: { + bindings: { + symbol: "repository" + value: { + string: { + value: "registry" + } + } + } + bindings: { + symbol: "platform" + value: { + object: { + bindings: { + symbol: "os" + value: { + string: { + value: "linux" + } + } + } + } + } + } + bindings: { + symbol: "tag" + value: { + string: { + value: "latest" + } + } + } + bindings: { + symbol: "digest" + value: { + string: { + value: "sha256:83bb78d7b28f1ac99c68133af32c93e9a1c149bcd3cb6e683a3ee56e312f1c96" + } + } + } + } + } + } + results: { + input: { + array: { + values: { + object: { + bindings: { + symbol: "platform" + value: { + object: { + bindings: { + symbol: "os" + value: { + string: { + value: "linux" + } + } + } + } + } + } + bindings: { + symbol: "repository" + value: { + string: { + value: "nixery.dev/simple-http-server" + } + } + } + bindings: { + symbol: "tag" + value: { + string: { + value: "latest" + } + } + } + } + } + } + } + output: { + object: { + bindings: { + symbol: "repository" + value: { + string: { + value: "nixery.dev/simple-http-server" + } + } + } + bindings: { + symbol: "platform" + value: { + object: { + bindings: { + symbol: "os" + value: { + string: { + value: "linux" + } + } + } + } + } + } + bindings: { + symbol: "tag" + value: { + string: { + value: "latest" + } + } + } + bindings: { + symbol: "digest" + value: { + string: { + value: "sha256:13a32cf276567978ad829355e336174aa107f29e7cf078a25ec30ba1d1bc8d5d" + } + } + } + } + } + } + results: { + input: { + array: { + values: { + object: { + bindings: { + symbol: "platform" + value: { + object: { + bindings: { + symbol: "os" + value: { + string: { + value: "linux" + } + } + } + } + } + } + bindings: { + symbol: "repository" + value: { + string: { + value: "nixery.dev/curl" + } + } + } + bindings: { + symbol: "tag" + value: { + string: { + value: "latest" + } + } + } + } + } + } + } + output: { + object: { + bindings: { + symbol: "repository" + value: { + string: { + value: "nixery.dev/curl" + } + } + } + bindings: { + symbol: "platform" + value: { + object: { + bindings: { + symbol: "os" + value: { + string: { + value: "linux" + } + } + } + } + } + } + bindings: { + symbol: "tag" + value: { + string: { + value: "latest" + } + } + } + bindings: { + symbol: "digest" + value: { + string: { + value: "sha256:ea6ad85d3dfbf10668b325aa4382eea4859df41cdd160d7204bd9200a698b24d" + } + } + } + } + } + } } } From 66f686b4859a6811e769e7641b0c16eb774ec680 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Fri, 26 Aug 2022 22:15:53 -0400 Subject: [PATCH 22/32] initialize tls depot in runtime the runtime is the only thing that depends on basstls, but it relies on it being initialized. so now it just initializes it too. the alternative is making sure to initialize it everywhere the runtime is used (docs, tests, irl), which feels messy. --- cmd/bass/main.go | 7 ------- pkg/runtimes/buildkit.go | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cmd/bass/main.go b/cmd/bass/main.go index f6feac82..bb742946 100644 --- a/cmd/bass/main.go +++ b/cmd/bass/main.go @@ -12,7 +12,6 @@ import ( flag "github.com/spf13/pflag" "github.com/vito/bass/pkg/bass" - "github.com/vito/bass/pkg/basstls" "github.com/vito/bass/pkg/cli" "github.com/vito/bass/pkg/ioctx" "github.com/vito/bass/pkg/runtimes" @@ -150,12 +149,6 @@ func root(ctx context.Context) error { return err } - err = basstls.Init(basstls.DefaultDir) - if err != nil { - cli.WriteError(ctx, err) - return err - } - pool, err := runtimes.NewPool(ctx, config) if err != nil { cli.WriteError(ctx, err) diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 4f46b13b..2fa4f795 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -107,6 +107,11 @@ func NewBuildkit(ctx context.Context, _ bass.RuntimePool, cfg *bass.Scope) (bass config.CertsDir = basstls.DefaultDir } + err := basstls.Init(config.CertsDir) + if err != nil { + return nil, fmt.Errorf("init tls depot: %w", err) + } + client, err := dialBuildkit(ctx, config.Addr) if err != nil { return nil, fmt.Errorf("dial buildkit: %w", err) From 3448e66e667810686c28218b441b4692785ce0e3 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Sat, 27 Aug 2022 10:54:02 -0400 Subject: [PATCH 23/32] debug: log container ip+hostname in shim --- pkg/runtimes/shim/main.go | 55 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index d8b40a87..98bec57e 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -35,7 +35,7 @@ import ( ) // NB: change this to Debug if you're troubleshooting the shim -const LogLevel = zapcore.ErrorLevel +const LogLevel = zapcore.DebugLevel //ErrorLevel type Command struct { Args []string `json:"args"` @@ -99,7 +99,21 @@ func run(args []string) error { return fmt.Errorf("usage: run ") } - err := installCert() + ip, err := containerIP() + if err != nil { + return fmt.Errorf("get container ip: %w", err) + } + + logger := StdLogger(LogLevel) + + hn, err := os.Hostname() + if err != nil { + return fmt.Errorf("get hostname: %w", err) + } + + logger.Debug("starting", zap.String("ip", ip.String()), zap.String("hostname", hn)) + + err = installCert() if err != nil { return fmt.Errorf("install bass CA: %w", err) } @@ -565,3 +579,40 @@ func LoggerTo(w io.Writer, level zapcore.LevelEnabler) *zap.Logger { func StdLogger(level zapcore.LevelEnabler) *zap.Logger { return LoggerTo(colorable.NewColorableStderr(), level) } + +const cidr = "10.0.0.0/8" + +func containerIP() (net.IP, error) { + ifaces, err := net.Interfaces() + if err != nil { + return nil, err + } + + _, blk, err := net.ParseCIDR(cidr) + if err != nil { + return nil, err + } + + for _, i := range ifaces { + addrs, err := i.Addrs() + if err != nil { + return nil, err + } + + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + + if blk.Contains(ip) { + return ip, nil + } + } + } + + return nil, fmt.Errorf("could not determine container IP (must be in %s)", cidr) +} From 1e75126367f28211fdc0107932a137fa8248408b Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Sat, 27 Aug 2022 11:26:24 -0400 Subject: [PATCH 24/32] log which IP was reached during polling --- pkg/runtimes/shim/main.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index 98bec57e..00855a18 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -529,18 +529,18 @@ func check(args []string) error { pollAddr := net.JoinHostPort(host, port) - err := pollForPort(logger, pollAddr) + reached, err := pollForPort(logger, pollAddr) if err != nil { return fmt.Errorf("poll %s: %w", name, err) } - logger.Info("port is up") + logger.Info("port is up", zap.String("reached", reached)) } return nil } -func pollForPort(logger *zap.Logger, addr string) error { +func pollForPort(logger *zap.Logger, addr string) (string, error) { retry := backoff.NewExponentialBackOff() retry.InitialInterval = 100 * time.Millisecond @@ -548,17 +548,32 @@ func pollForPort(logger *zap.Logger, addr string) error { Timeout: time.Second, } - return backoff.Retry(func() error { + var reached string + err := backoff.Retry(func() error { conn, err := dialer.Dial("tcp", addr) if err != nil { logger.Debug("failed to dial", zap.Duration("elapsed", retry.GetElapsedTime()), zap.Error(err)) return err } + host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) + if err != nil { + // don't know how this would happen but it's likely not recoverable + logger.Error("malformed host:port", zap.Error(err)) + return backoff.Permanent(err) + } + + reached = host + _ = conn.Close() return nil }, retry) + if err != nil { + return "", err + } + + return reached, nil } // yoinked from pkg/bass/log.go, avoiding too many dependencies From e7eba7238498e62a85cf01da19b66cc85649cf30 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Sat, 27 Aug 2022 15:04:58 -0400 Subject: [PATCH 25/32] persist certs created for thunks regenerating them all the time means we can't dedupe services --- pkg/basstls/basstls.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/pkg/basstls/basstls.go b/pkg/basstls/basstls.go index 037f7682..bfc2ca48 100644 --- a/pkg/basstls/basstls.go +++ b/pkg/basstls/basstls.go @@ -88,6 +88,19 @@ func Generate(dir, host string) (*pkix.Certificate, *pkix.Key, error) { return nil, nil, fmt.Errorf("init depot: %w", err) } + // TODO: file locking? + crt, err := depot.GetCertificate(d, host) + if err == nil { + // cert and key already exist + + key, err := depot.GetPrivateKey(d, host) + if err != nil { + return nil, nil, fmt.Errorf("get key: %w", err) + } + + return crt, key, nil + } + caCrt, err := depot.GetCertificate(d, CAName) if err != nil { return nil, nil, fmt.Errorf("get cert: %w", err) @@ -103,6 +116,11 @@ func Generate(dir, host string) (*pkix.Certificate, *pkix.Key, error) { return nil, nil, fmt.Errorf("create key: %w", err) } + err = depot.PutPrivateKey(d, host, key) + if err != nil { + return nil, nil, fmt.Errorf("put cert: %w", err) + } + csr, err := pkix.CreateCertificateSigningRequest( key, "", // Organizational Unit @@ -122,10 +140,15 @@ func Generate(dir, host string) (*pkix.Certificate, *pkix.Key, error) { // TODO(vito): rotate rather than adding a ridiculous amount of time? expiry := time.Now().AddDate(0, 0, 64) - crt, err := pkix.CreateCertificateHost(caCrt, caKey, csr, expiry) + crt, err = pkix.CreateCertificateHost(caCrt, caKey, csr, expiry) if err != nil { return nil, nil, fmt.Errorf("create cert: %w", err) } + err = depot.PutCertificate(d, host, crt) + if err != nil { + return nil, nil, fmt.Errorf("put cert: %w", err) + } + return crt, key, nil } From 5236ea7c5db18e634771d072131e036097f2bf0c Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Sat, 27 Aug 2022 16:15:27 -0400 Subject: [PATCH 26/32] add locking to basstls --- pkg/basstls/basstls.go | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/pkg/basstls/basstls.go b/pkg/basstls/basstls.go index bfc2ca48..eccd149d 100644 --- a/pkg/basstls/basstls.go +++ b/pkg/basstls/basstls.go @@ -2,10 +2,12 @@ package basstls import ( "fmt" + "os" "path/filepath" "time" "github.com/adrg/xdg" + "github.com/gofrs/flock" "github.com/square/certstrap/depot" "github.com/square/certstrap/pkix" ) @@ -14,12 +16,16 @@ const ( // Common name for the certificate authority. CAName = "bass" - CACountry = "CA" + // Arbitrary values for the CA cert. + CACountry = "CA" // Canada (coincidence) CAProvince = "Ontario" CALocality = "Toronto" // RSA key bits. keySize = 2048 + + // File stored within the cert depot to synchronize cert generation. + lockFile = "certs.lock" ) var ( @@ -33,8 +39,29 @@ func CACert(dir string) string { return filepath.Join(dir, CAName+".crt") } +func lockDepot(dir string) (*flock.Flock, error) { + lock := flock.New(filepath.Join(dir, lockFile)) + + if err := os.MkdirAll(dir, 0755); err != nil { + return nil, err + } + + if err := lock.Lock(); err != nil { + return nil, err + } + + return lock, nil +} + // Init initializes dir with a CA. func Init(dir string) error { + lock, err := lockDepot(dir) + if err != nil { + return err + } + + defer lock.Unlock() + d, err := depot.NewFileDepot(dir) if err != nil { return fmt.Errorf("init depot: %w", err) @@ -79,16 +106,22 @@ func Init(dir string) error { return fmt.Errorf("put ca: %w", err) } - return nil + return lock.Unlock() } func Generate(dir, host string) (*pkix.Certificate, *pkix.Key, error) { + lock, err := lockDepot(dir) + if err != nil { + return nil, nil, err + } + + defer lock.Unlock() + d, err := depot.NewFileDepot(dir) if err != nil { return nil, nil, fmt.Errorf("init depot: %w", err) } - // TODO: file locking? crt, err := depot.GetCertificate(d, host) if err == nil { // cert and key already exist From 12f18d36192bb7c08c6defd5d07cf869db0c3220 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Mon, 29 Aug 2022 00:06:06 -0400 Subject: [PATCH 27/32] install test cert into bass-buildkitd otherwise running tls.bass directly on the host (as opposed to via bass) fails --- pkg/runtimes/testdata/tls/.gitignore | 5 ++ pkg/runtimes/testdata/tls/fs.go | 6 +++ pkg/runtimes/util/buildkitd/buildkitd.go | 62 +++++++++++++++++++++--- 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 pkg/runtimes/testdata/tls/.gitignore create mode 100644 pkg/runtimes/testdata/tls/fs.go diff --git a/pkg/runtimes/testdata/tls/.gitignore b/pkg/runtimes/testdata/tls/.gitignore new file mode 100644 index 00000000..f4107977 --- /dev/null +++ b/pkg/runtimes/testdata/tls/.gitignore @@ -0,0 +1,5 @@ +* +!bass.crt +!bass.key +!.gitignore +!fs.go diff --git a/pkg/runtimes/testdata/tls/fs.go b/pkg/runtimes/testdata/tls/fs.go new file mode 100644 index 00000000..6fd8bafc --- /dev/null +++ b/pkg/runtimes/testdata/tls/fs.go @@ -0,0 +1,6 @@ +package tls + +import _ "embed" + +//go:embed bass.crt +var TestCert []byte diff --git a/pkg/runtimes/util/buildkitd/buildkitd.go b/pkg/runtimes/util/buildkitd/buildkitd.go index 6e756fc5..9dac421d 100644 --- a/pkg/runtimes/util/buildkitd/buildkitd.go +++ b/pkg/runtimes/util/buildkitd/buildkitd.go @@ -1,9 +1,12 @@ package buildkitd import ( + "archive/tar" + "bytes" "context" "errors" "fmt" + "os" "os/exec" "strings" "time" @@ -15,6 +18,7 @@ import ( bk "github.com/moby/buildkit/client" _ "github.com/moby/buildkit/client/connhelper/dockercontainer" // import the container connection driver "github.com/vito/bass/pkg/basstls" + "github.com/vito/bass/pkg/runtimes/testdata/tls" "github.com/vito/bass/pkg/zapctx" "go.opentelemetry.io/otel" "go.uber.org/zap" @@ -240,21 +244,67 @@ func installBuildkit(ctx context.Context) error { } } + userCert, err := os.ReadFile(basstls.CACert(basstls.DefaultDir)) + if err != nil { + logger.Error("failed to read bass.crt", zap.Error(err)) + return err + } + + err = installCert(ctx, "bass.crt", userCert) + if err != nil { + logger.Error("failed to install bass.crt", zap.Error(err)) + return err + } + + err = installCert(ctx, "bass-tests.crt", tls.TestCert) + if err != nil { + logger.Error("failed to install bass.crt", zap.Error(err)) + return err + } + + return waitBuildkit(ctx) +} + +func installCert(ctx context.Context, name string, cert []byte) error { // trust the user's bass CA cert so you can fetch images from a registry // running in a thunk - cmd = exec.CommandContext( + cmd := exec.CommandContext( ctx, "docker", "cp", - basstls.CACert(basstls.DefaultDir), - containerName+":/etc/ssl/certs/bass.crt", + "-", + containerName+":/etc/ssl/certs", ) - output, err = cmd.CombinedOutput() + + buf := new(bytes.Buffer) + cmd.Stdin = buf + + tw := tar.NewWriter(buf) + err := tw.WriteHeader(&tar.Header{ + Name: name, + Size: int64(len(cert)), + Mode: 0400, + }) if err != nil { - return nil + return err } - return waitBuildkit(ctx) + _, err = tw.Write(cert) + if err != nil { + return err + } + + err = tw.Flush() + if err != nil { + return err + } + + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("install cert: %w\n\noutput:\n\n%s", err, string(output)) + } + + return nil } // waitBuildkit waits for the buildkit daemon to be responsive. From 0f4608f234b74c552171114df1d481c6a0b169f2 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Mon, 29 Aug 2022 00:08:48 -0400 Subject: [PATCH 28/32] add hack/test, tweak contributing.md --- CONTRIBUTING.md | 10 ++++------ hack/test | 13 +++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100755 hack/test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a0e9093..e4d73578 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,8 +7,8 @@ whether that's writing code or just providing good signals to the project. ## Contributing feedback & discussions Languages evolve as more people speak them. Bass is very young, so feedback is -incredibly valuable. Using it for my own projects has led to dramatic changes, -and it'd be best to get the bulk of these out of the way early on. +incredibly valuable. Using it for my own projects has led to dramatic changes +to Bass, and it'd be best to get the bulk of these out of the way early on. The best place to leave feedback is in [Discussions], but feel free to just hop in [Discord] too. @@ -16,7 +16,7 @@ in [Discord] too. It's hard to use a language without having something to say, so if you don't have a project to apply Bass to feel free to critique Bass's own Bass code: -* [project.bass](project.bass) contains the bulk of the project code. +* [bass/bass.bass](bass/bass.bass) contains the bulk of the project code. * [bass/build](bass/build) builds Bass binaries. * [bass/docs](bass/docs) builds Bass's docs. * [bass/test](bass/test) runs Bass's test suite. @@ -74,9 +74,7 @@ this is a debt that I won't let grow out of control. To run the tests: ```sh -# for lsp, which have a lsp config submodule for lsp config -git submodule update --init --recursive -go test ./... +./hack/test ``` The tests assume Buildkit is running somewhere, and they discover it the same diff --git a/hack/test b/hack/test new file mode 100755 index 00000000..d63a39cb --- /dev/null +++ b/hack/test @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e -u -x + +# for lsp tests, which have a submodule for lsp config +git submodule update --init --recursive + +if which gotestsum 2>&1 >/dev/null; then + # run tests + exec gotestsum -f dots -- "$@" +else + exec go test "$@" +fi From c487eb81869352c1b37f38f4f5dd0c04e102be38 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Mon, 29 Aug 2022 01:11:33 -0400 Subject: [PATCH 29/32] add draft for v0.10.0 release notes --- notes/v0.10.0.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 notes/v0.10.0.md diff --git a/notes/v0.10.0.md b/notes/v0.10.0.md new file mode 100644 index 00000000..dbab8279 --- /dev/null +++ b/notes/v0.10.0.md @@ -0,0 +1,37 @@ +This is a big release that overhauls the networking stack and adds a new kind +of value: a *thunk addr*. + +Thunks can now provide ports: + +```clojure +(-> ($ python -m http.server 80) + (with-image (linux/python)) + (with-port :http 80)) +``` + +Ports can be referenced using a [thunk addr]. A thunk addr is a lot like a +[thunk path] except it represents to a TCP address instead of a filesystem +path. + + +```clojure +(def srv + (-> ($ python -m http.server 80) + (with-image (linux/python)) + (with-port :http 80))) + +(-> ($ wget (addr srv :http "http://$host:$port")) + (with-image (linux/ubuntu)) + run) +``` + +The server thunk runs lazily. The client thunk doesn't run until the server's +ports are listening. + +Thunks no longer run in the host network. Instead they run in a [bridge +network] to prevent port collisions. + +Thunks use DNS to address each other in order to maximize caching. (Using IPs +would introduce a source of randomness!) + +[bridge network]: https://www.cni.dev/plugins/current/main/bridge/ From 079a51aa6b36266241f3b98e27de2754a3ce171a Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Mon, 29 Aug 2022 11:08:56 -0400 Subject: [PATCH 30/32] set a per-test timeout --- pkg/runtimes/suite.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pkg/runtimes/suite.go b/pkg/runtimes/suite.go index a1f74123..68a14bcd 100644 --- a/pkg/runtimes/suite.go +++ b/pkg/runtimes/suite.go @@ -220,8 +220,18 @@ func Suite(t *testing.T, pool bass.RuntimePool) { is := is.New(t) t.Parallel() + ctx := context.Background() + + // set a reasonable timeout so we get a more descriptive failure than the + // global go test timeout + // + // ideally this would be even lower but we should account for slow + // networks for image fetching/etc. + ctx, stop := context.WithTimeout(ctx, 5*time.Minute) + defer stop() + displayBuf := new(bytes.Buffer) - ctx := bass.WithTrace(context.Background(), &bass.Trace{}) + ctx = bass.WithTrace(ctx, &bass.Trace{}) ctx = ioctx.StderrToContext(ctx, displayBuf) res, err := RunTest(ctx, t, pool, test.File, nil) t.Logf("progress:\n%s", displayBuf.String()) From 2b2b2247a9ae2bf9fa6d7619be15ad892ce9a5df Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Mon, 29 Aug 2022 12:13:08 -0400 Subject: [PATCH 31/32] split shim up, make debugging configurable --- pkg/runtimes/buildkit.go | 5 + pkg/runtimes/buildkit_test.go | 1 + pkg/runtimes/shim/check.go | 79 +++++ pkg/runtimes/shim/get_config.go | 91 +++++ pkg/runtimes/shim/log.go | 52 +++ pkg/runtimes/shim/main.go | 583 +------------------------------- pkg/runtimes/shim/run.go | 208 ++++++++++++ pkg/runtimes/shim/tls.go | 15 - pkg/runtimes/shim/unpack.go | 174 ++++++++++ 9 files changed, 617 insertions(+), 591 deletions(-) create mode 100644 pkg/runtimes/shim/check.go create mode 100644 pkg/runtimes/shim/get_config.go create mode 100644 pkg/runtimes/shim/log.go create mode 100644 pkg/runtimes/shim/run.go create mode 100644 pkg/runtimes/shim/unpack.go diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 2fa4f795..a0096b34 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -49,6 +49,7 @@ import ( const buildkitProduct = "bass" type BuildkitConfig struct { + Debug bool `json:"debug,omitempty"` Addr string `json:"addr,omitempty"` DisableCache bool `json:"disable_cache,omitempty"` CertsDir string `json:"certs_dir,omitempty"` @@ -702,6 +703,10 @@ func (b *builder) llb(ctx context.Context, thunk bass.Thunk, extraOpts ...llb.Ru ) } + if b.runtime.Config.Debug { + runOpt = append(runOpt, llb.AddEnv("_BASS_DEBUG", "1")) + } + if thunk.Insecure { needsInsecure = true diff --git a/pkg/runtimes/buildkit_test.go b/pkg/runtimes/buildkit_test.go index a6e9fc9e..fd47c4b4 100644 --- a/pkg/runtimes/buildkit_test.go +++ b/pkg/runtimes/buildkit_test.go @@ -30,6 +30,7 @@ func TestBuildkitRuntime(t *testing.T) { Platform: bass.LinuxPlatform, Runtime: runtimes.BuildkitName, Config: bass.Bindings{ + "debug": bass.Bool(true), "certs_dir": bass.String("./testdata/tls/"), }.Scope(), }, diff --git a/pkg/runtimes/shim/check.go b/pkg/runtimes/shim/check.go new file mode 100644 index 00000000..1a52e29f --- /dev/null +++ b/pkg/runtimes/shim/check.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "net" + "strings" + "time" + + "github.com/cenkalti/backoff/v4" + "go.uber.org/zap" +) + +func check(args []string) error { + logger := StdLogger(logLevel) + + if len(args) == 0 { + return fmt.Errorf("usage: check name:port...") + } + + host, ports := args[0], args[1:] + + for _, nameAndPort := range ports { + name, port, ok := strings.Cut(nameAndPort, ":") + if !ok { + return fmt.Errorf("port must be in form name:number: %s", nameAndPort) + } + + logger := logger.With(zap.String("name", name), zap.String("port", port)) + + logger.Debug("polling for port") + + pollAddr := net.JoinHostPort(host, port) + + reached, err := pollForPort(logger, pollAddr) + if err != nil { + return fmt.Errorf("poll %s: %w", name, err) + } + + logger.Info("port is up", zap.String("reached", reached)) + } + + return nil +} + +func pollForPort(logger *zap.Logger, addr string) (string, error) { + retry := backoff.NewExponentialBackOff() + retry.InitialInterval = 100 * time.Millisecond + + dialer := net.Dialer{ + Timeout: time.Second, + } + + var reached string + err := backoff.Retry(func() error { + conn, err := dialer.Dial("tcp", addr) + if err != nil { + logger.Debug("failed to dial", zap.Duration("elapsed", retry.GetElapsedTime()), zap.Error(err)) + return err + } + + host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) + if err != nil { + // don't know how this would happen but it's likely not recoverable + logger.Error("malformed host:port", zap.Error(err)) + return backoff.Permanent(err) + } + + reached = host + + _ = conn.Close() + + return nil + }, retry) + if err != nil { + return "", err + } + + return reached, nil +} diff --git a/pkg/runtimes/shim/get_config.go b/pkg/runtimes/shim/get_config.go new file mode 100644 index 00000000..43cc3a44 --- /dev/null +++ b/pkg/runtimes/shim/get_config.go @@ -0,0 +1,91 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + + ispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/opencontainers/umoci/oci/casext" +) + +func getConfig(args []string) error { + ctx := context.Background() + + if len(args) != 3 { + return fmt.Errorf("usage: get-config image.tar tag dest/") + } + + archiveSrc := args[0] + fromName := args[1] + configDst := args[2] + + layout, err := openTar(archiveSrc) + if err != nil { + return fmt.Errorf("create layout: %w", err) + } + + defer layout.Close() + + ext := casext.NewEngine(layout) + + mspec, err := loadManifest(ctx, ext, fromName) + if err != nil { + return err + } + + config, err := ext.FromDescriptor(ctx, mspec.Config) + if err != nil { + return fmt.Errorf("load config: %w", err) + } + + if config.Descriptor.MediaType != ispec.MediaTypeImageConfig { + return fmt.Errorf("bad config media type: %s", config.Descriptor.MediaType) + } + + ispec := config.Data.(ispec.Image) + + configPath := filepath.Join(configDst, "config.json") + + configFile, err := os.Create(configPath) + if err != nil { + return fmt.Errorf("create config.json: %w", err) + } + + defer configFile.Close() + + err = json.NewEncoder(configFile).Encode(ispec.Config) + if err != nil { + return fmt.Errorf("encode image config: %w", err) + } + + return nil +} + +func loadManifest(ctx context.Context, ext casext.Engine, name string) (ispec.Manifest, error) { + descPaths, err := ext.ResolveReference(context.Background(), name) + if err != nil { + return ispec.Manifest{}, fmt.Errorf("resolve ref: %w", err) + } + + if len(descPaths) == 0 { + return ispec.Manifest{}, fmt.Errorf("tag not found: %s", name) + } + + if len(descPaths) != 1 { + return ispec.Manifest{}, fmt.Errorf("ambiguous tag?: %s (%d paths returned)", name, len(descPaths)) + } + + manifest, err := ext.FromDescriptor(ctx, descPaths[0].Descriptor()) + if err != nil { + return ispec.Manifest{}, fmt.Errorf("load manifest: %w", err) + } + + if manifest.Descriptor.MediaType != ispec.MediaTypeImageManifest { + return ispec.Manifest{}, fmt.Errorf("bad manifest media type: %s", manifest.Descriptor.MediaType) + } + + return manifest.Data.(ispec.Manifest), nil +} diff --git a/pkg/runtimes/shim/log.go b/pkg/runtimes/shim/log.go new file mode 100644 index 00000000..f3cf33b2 --- /dev/null +++ b/pkg/runtimes/shim/log.go @@ -0,0 +1,52 @@ +package main + +import ( + "io" + "net" + "time" + + "github.com/mattn/go-colorable" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// yoinked from pkg/bass/log.go, avoiding too many dependencies +func LoggerTo(w io.Writer, level zapcore.LevelEnabler) *zap.Logger { + zapcfg := zap.NewDevelopmentEncoderConfig() + zapcfg.EncodeLevel = zapcore.LowercaseColorLevelEncoder + zapcfg.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(t.Format("15:04:05.000")) + } + + return zap.New(zapcore.NewCore( + zapcore.NewConsoleEncoder(zapcfg), + zapcore.AddSync(w), + level, + )) +} + +func StdLogger(level zapcore.LevelEnabler) *zap.Logger { + return LoggerTo(colorable.NewColorableStderr(), level) +} + +func logIPs(logger *zap.Logger) { + ifaces, err := net.Interfaces() + if err != nil { + logger.Error("failed to get interfaces", zap.Error(err)) + return + } + + for _, i := range ifaces { + logger = logger.With(zap.String("iface", i.Name)) + + addrs, err := i.Addrs() + if err != nil { + logger.Error("failed to get addrs", zap.Error(err)) + continue + } + + for _, addr := range addrs { + logger.Debug("addr", zap.String("addr", addr.String())) + } + } +} diff --git a/pkg/runtimes/shim/main.go b/pkg/runtimes/shim/main.go index 00855a18..8dee16b3 100644 --- a/pkg/runtimes/shim/main.go +++ b/pkg/runtimes/shim/main.go @@ -1,54 +1,23 @@ package main import ( - "archive/tar" - "bytes" - "context" - "encoding/json" - "errors" "fmt" - "io" - "io/fs" - "net" "os" - "os/exec" - "os/signal" - "path" - "path/filepath" "sort" "strings" - "syscall" - "time" - "github.com/cenkalti/backoff/v4" - "github.com/containerd/containerd/sys/reaper" - "github.com/mattn/go-colorable" - "github.com/moby/sys/mountinfo" - "github.com/opencontainers/go-digest" - ispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/opencontainers/umoci/oci/cas" - "github.com/opencontainers/umoci/oci/casext" - "github.com/opencontainers/umoci/oci/layer" - "go.uber.org/zap" "go.uber.org/zap/zapcore" - "golang.org/x/sys/unix" ) -// NB: change this to Debug if you're troubleshooting the shim -const LogLevel = zapcore.DebugLevel //ErrorLevel - -type Command struct { - Args []string `json:"args"` - Stdin []byte `json:"stdin"` - Env []string `json:"env"` - Dir *string `json:"dir"` -} - -var stdoutPath string +var debug bool +var logLevel = zapcore.ErrorLevel func init() { - stdoutPath = os.Getenv("_BASS_OUTPUT") - os.Unsetenv("_BASS_OUTPUT") + if os.Getenv("_BASS_DEBUG") != "" { + debug = true + logLevel = zapcore.DebugLevel + os.Unsetenv("_BASS_DEBUG") + } } var cmds = map[string]func([]string) error{ @@ -93,541 +62,3 @@ func main() { os.Exit(1) } } - -func run(args []string) error { - if len(args) != 1 { - return fmt.Errorf("usage: run ") - } - - ip, err := containerIP() - if err != nil { - return fmt.Errorf("get container ip: %w", err) - } - - logger := StdLogger(LogLevel) - - hn, err := os.Hostname() - if err != nil { - return fmt.Errorf("get hostname: %w", err) - } - - logger.Debug("starting", zap.String("ip", ip.String()), zap.String("hostname", hn)) - - err = installCert() - if err != nil { - return fmt.Errorf("install bass CA: %w", err) - } - - err = reap() - if err != nil { - return fmt.Errorf("reap: %w", err) - } - - cmdPath := args[0] - - cmdPayload, err := os.ReadFile(cmdPath) - if err != nil { - return fmt.Errorf("read cmd: %w", err) - } - - var cmd Command - err = json.Unmarshal(cmdPayload, &cmd) - if err != nil { - return fmt.Errorf("unmarshal cmd: %w", err) - } - - err = os.Remove(cmdPath) - if err != nil { - return fmt.Errorf("burn after reading: %w", err) - } - - var stdout io.Writer = os.Stdout - if stdoutPath != "" { - response, err := os.Create(stdoutPath) - if err != nil { - return fmt.Errorf("create output error: %w", err) - } - - defer response.Close() - - stdout = response - } - - for _, e := range cmd.Env { - segs := strings.SplitN(e, "=", 2) - if len(segs) != 2 { - return fmt.Errorf("malformed env: %s", e) - } - - os.Setenv(segs[0], segs[1]) - } - - bin := cmd.Args[0] - argv := cmd.Args[1:] - execCmd := exec.Command(bin, argv...) - if cmd.Dir != nil { - execCmd.Dir = *cmd.Dir - } - execCmd.Stdin = bytes.NewBuffer(cmd.Stdin) - execCmd.Stdout = stdout - execCmd.Stderr = os.Stderr - - ch, err := reaper.Default.Start(execCmd) - if err != nil { - return fmt.Errorf("start: %w", err) - } - - status, err := reaper.Default.Wait(execCmd, ch) - if err != nil { - return fmt.Errorf("wait: %w", err) - } - - if status != 0 { - // propagate exit status - os.Exit(status) - return nil - } - - err = normalizeTimes(".") - if err != nil { - return fmt.Errorf("failed to normalize timestamps: %w", err) - } - - return nil -} - -func reap() error { - logger := StdLogger(LogLevel) - - reaper.SetSubreaper(1) - - children := make(chan os.Signal, 32) - signal.Notify(children, syscall.SIGCHLD) - - go func() { - for range children { - err := reaper.Reap() - if err != nil { - logger.Warn("failed to reap", zap.Error(err)) - } - } - }() - - return nil -} - -func getConfig(args []string) error { - ctx := context.Background() - - if len(args) != 3 { - return fmt.Errorf("usage: get-config image.tar tag dest/") - } - - archiveSrc := args[0] - fromName := args[1] - configDst := args[2] - - layout, err := openTar(archiveSrc) - if err != nil { - return fmt.Errorf("create layout: %w", err) - } - - defer layout.Close() - - ext := casext.NewEngine(layout) - - mspec, err := loadManifest(ctx, ext, fromName) - if err != nil { - return err - } - - config, err := ext.FromDescriptor(ctx, mspec.Config) - if err != nil { - return fmt.Errorf("load config: %w", err) - } - - if config.Descriptor.MediaType != ispec.MediaTypeImageConfig { - return fmt.Errorf("bad config media type: %s", config.Descriptor.MediaType) - } - - ispec := config.Data.(ispec.Image) - - configPath := filepath.Join(configDst, "config.json") - - configFile, err := os.Create(configPath) - if err != nil { - return fmt.Errorf("create config.json: %w", err) - } - - defer configFile.Close() - - err = json.NewEncoder(configFile).Encode(ispec.Config) - if err != nil { - return fmt.Errorf("encode image config: %w", err) - } - - return nil -} - -func unpack(args []string) error { - ctx := context.Background() - - if len(args) != 3 { - return fmt.Errorf("usage: unpack ") - } - - archiveSrc := args[0] - fromName := args[1] - rootfsPath := args[2] - - layout, err := openTar(archiveSrc) - if err != nil { - return fmt.Errorf("create layout: %w", err) - } - - defer layout.Close() - - ext := casext.NewEngine(layout) - - mspec, err := loadManifest(ctx, ext, fromName) - if err != nil { - return err - } - - err = layer.UnpackRootfs(context.Background(), ext, rootfsPath, mspec, &layer.UnpackOptions{}) - if err != nil { - return fmt.Errorf("unpack rootfs: %w", err) - } - - return nil -} - -func loadManifest(ctx context.Context, ext casext.Engine, name string) (ispec.Manifest, error) { - descPaths, err := ext.ResolveReference(context.Background(), name) - if err != nil { - return ispec.Manifest{}, fmt.Errorf("resolve ref: %w", err) - } - - if len(descPaths) == 0 { - return ispec.Manifest{}, fmt.Errorf("tag not found: %s", name) - } - - if len(descPaths) != 1 { - return ispec.Manifest{}, fmt.Errorf("ambiguous tag?: %s (%d paths returned)", name, len(descPaths)) - } - - manifest, err := ext.FromDescriptor(ctx, descPaths[0].Descriptor()) - if err != nil { - return ispec.Manifest{}, fmt.Errorf("load manifest: %w", err) - } - - if manifest.Descriptor.MediaType != ispec.MediaTypeImageManifest { - return ispec.Manifest{}, fmt.Errorf("bad manifest media type: %s", manifest.Descriptor.MediaType) - } - - return manifest.Data.(ispec.Manifest), nil -} - -func openTar(tarPath string) (cas.Engine, error) { - archive, err := os.Open(tarPath) - if err != nil { - return nil, err - } - - return &tarEngine{archive}, nil -} - -// tarEngine implements a read-only cas.Engine backed by a .tar archive. -type tarEngine struct { - archive *os.File -} - -func (engine *tarEngine) PutBlob(ctx context.Context, reader io.Reader) (digest.Digest, int64, error) { - return "", 0, fmt.Errorf("PutBlob: %w", cas.ErrNotImplemented) -} - -func (engine *tarEngine) GetBlob(ctx context.Context, dig digest.Digest) (io.ReadCloser, error) { - r, err := engine.open(path.Join("blobs", dig.Algorithm().String(), dig.Encoded())) - if err != nil { - return nil, err - } - - return io.NopCloser(r), nil -} - -func (engine *tarEngine) StatBlob(ctx context.Context, dig digest.Digest) (bool, error) { - _, err := engine.open(path.Join("blobs", dig.Algorithm().String(), dig.Encoded())) - if err != nil { - if errors.Is(err, cas.ErrNotExist) { - return false, nil - } - - return false, err - } - - return true, nil -} - -func (engine *tarEngine) PutIndex(ctx context.Context, index ispec.Index) error { - return fmt.Errorf("PutIndex: %w", cas.ErrNotImplemented) -} - -func (engine *tarEngine) GetIndex(ctx context.Context) (ispec.Index, error) { - var idx ispec.Index - r, err := engine.open("index.json") - if err != nil { - return ispec.Index{}, err - } - - err = json.NewDecoder(r).Decode(&idx) - if err != nil { - return ispec.Index{}, err - } - - return idx, nil -} - -func (engine *tarEngine) open(p string) (io.Reader, error) { - _, err := engine.archive.Seek(0, 0) - if err != nil { - return nil, fmt.Errorf("seek: %w", err) - } - - tr := tar.NewReader(engine.archive) - - for { - hdr, err := tr.Next() - if err != nil { - if err == io.EOF { - return nil, fmt.Errorf("open %s: %w", p, cas.ErrNotExist) - } - - return nil, err - } - - if path.Clean(hdr.Name) == p { - return tr, nil - } - } -} - -func (engine *tarEngine) DeleteBlob(ctx context.Context, digest digest.Digest) (err error) { - return fmt.Errorf("DeleteBlob: %w", cas.ErrNotImplemented) -} - -func (engine *tarEngine) ListBlobs(ctx context.Context) ([]digest.Digest, error) { - _, err := engine.archive.Seek(0, 0) - if err != nil { - return nil, fmt.Errorf("seek: %w", err) - } - - tr := tar.NewReader(engine.archive) - - var digs []digest.Digest - for { - hdr, err := tr.Next() - if err != nil { - if err == io.EOF { - break - } - - return nil, fmt.Errorf("next: %w", err) - } - - if strings.HasPrefix(path.Clean(hdr.Name), "blobs/") { - dir, encoded := path.Split(hdr.Name) - _, alg := path.Split(dir) - digs = append(digs, digest.NewDigestFromEncoded(digest.Algorithm(alg), encoded)) - } - } - - return digs, nil -} - -func (engine *tarEngine) Clean(ctx context.Context) error { return nil } - -func (engine *tarEngine) Close() error { - return engine.archive.Close() -} - -var epoch = time.Date(1985, 10, 26, 8, 15, 0, 0, time.UTC) - -func normalizeTimes(root string) error { - logger := StdLogger(LogLevel) - - skipped := 0 - unchanged := 0 - changed := 0 - start := time.Now() - tspec := unix.NsecToTimespec(epoch.UnixNano()) - targetTime := []unix.Timespec{tspec, tspec} - err := filepath.Walk(root, func(path string, info fs.FileInfo, err error) error { - if path != root && info.IsDir() { - mp, err := mountinfo.Mounted(path) - if err != nil { - return fmt.Errorf("check mounted: %w", err) - } - - if mp { - logger.Debug("skipping mountpoint", zap.String("path", path)) - skipped++ - return fs.SkipDir - } - } - - if info.ModTime().Equal(epoch) { - unchanged++ - return nil - } - - changed++ - - logger.Debug("chtimes", - zap.String("path", path), - zap.Time("from", info.ModTime()), - zap.Time("to", epoch)) - - err = unix.UtimesNanoAt(unix.AT_FDCWD, path, targetTime, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - return fmt.Errorf("chtimes: %w", err) - } - - return nil - }) - if err != nil { - return err - } - - logger.Info("times normalized", - zap.Duration("took", time.Since(start)), - zap.Int("changed", changed), - zap.Int("unchanged", unchanged), - zap.Int("skipped", skipped), - ) - - return nil -} - -func check(args []string) error { - logger := StdLogger(LogLevel) - - if len(args) == 0 { - return fmt.Errorf("usage: check name:port...") - } - - host, ports := args[0], args[1:] - - for _, nameAndPort := range ports { - name, port, ok := strings.Cut(nameAndPort, ":") - if !ok { - return fmt.Errorf("port must be in form name:number: %s", nameAndPort) - } - - logger := logger.With(zap.String("name", name), zap.String("port", port)) - - logger.Debug("polling for port") - - pollAddr := net.JoinHostPort(host, port) - - reached, err := pollForPort(logger, pollAddr) - if err != nil { - return fmt.Errorf("poll %s: %w", name, err) - } - - logger.Info("port is up", zap.String("reached", reached)) - } - - return nil -} - -func pollForPort(logger *zap.Logger, addr string) (string, error) { - retry := backoff.NewExponentialBackOff() - retry.InitialInterval = 100 * time.Millisecond - - dialer := net.Dialer{ - Timeout: time.Second, - } - - var reached string - err := backoff.Retry(func() error { - conn, err := dialer.Dial("tcp", addr) - if err != nil { - logger.Debug("failed to dial", zap.Duration("elapsed", retry.GetElapsedTime()), zap.Error(err)) - return err - } - - host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) - if err != nil { - // don't know how this would happen but it's likely not recoverable - logger.Error("malformed host:port", zap.Error(err)) - return backoff.Permanent(err) - } - - reached = host - - _ = conn.Close() - - return nil - }, retry) - if err != nil { - return "", err - } - - return reached, nil -} - -// yoinked from pkg/bass/log.go, avoiding too many dependencies -func LoggerTo(w io.Writer, level zapcore.LevelEnabler) *zap.Logger { - zapcfg := zap.NewDevelopmentEncoderConfig() - zapcfg.EncodeLevel = zapcore.LowercaseColorLevelEncoder - zapcfg.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(t.Format("15:04:05.000")) - } - - return zap.New(zapcore.NewCore( - zapcore.NewConsoleEncoder(zapcfg), - zapcore.AddSync(w), - level, - )) -} - -func StdLogger(level zapcore.LevelEnabler) *zap.Logger { - return LoggerTo(colorable.NewColorableStderr(), level) -} - -const cidr = "10.0.0.0/8" - -func containerIP() (net.IP, error) { - ifaces, err := net.Interfaces() - if err != nil { - return nil, err - } - - _, blk, err := net.ParseCIDR(cidr) - if err != nil { - return nil, err - } - - for _, i := range ifaces { - addrs, err := i.Addrs() - if err != nil { - return nil, err - } - - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - ip = v.IP - case *net.IPAddr: - ip = v.IP - } - - if blk.Contains(ip) { - return ip, nil - } - } - } - - return nil, fmt.Errorf("could not determine container IP (must be in %s)", cidr) -} diff --git a/pkg/runtimes/shim/run.go b/pkg/runtimes/shim/run.go new file mode 100644 index 00000000..c653df64 --- /dev/null +++ b/pkg/runtimes/shim/run.go @@ -0,0 +1,208 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/fs" + "os" + "os/exec" + "os/signal" + "path/filepath" + "strings" + "syscall" + "time" + + "github.com/containerd/containerd/sys/reaper" + "github.com/moby/sys/mountinfo" + "go.uber.org/zap" + "golang.org/x/sys/unix" +) + +type Command struct { + Args []string `json:"args"` + Stdin []byte `json:"stdin"` + Env []string `json:"env"` + Dir *string `json:"dir"` +} + +func run(args []string) error { + if len(args) != 1 { + return fmt.Errorf("usage: run ") + } + + logger := StdLogger(logLevel) + + if debug { + hn, err := os.Hostname() + if err != nil { + return fmt.Errorf("get hostname: %w", err) + } + + logger.Debug("starting", zap.String("hostname", hn)) + + logIPs(logger) + } + + if err := installCert(); err != nil { + return fmt.Errorf("install bass CA: %w", err) + } + + if err := spawnReaper(); err != nil { + return fmt.Errorf("reap: %w", err) + } + + cmdPath := args[0] + + cmdPayload, err := os.ReadFile(cmdPath) + if err != nil { + return fmt.Errorf("read cmd: %w", err) + } + + var cmd Command + err = json.Unmarshal(cmdPayload, &cmd) + if err != nil { + return fmt.Errorf("unmarshal cmd: %w", err) + } + + err = os.Remove(cmdPath) + if err != nil { + return fmt.Errorf("burn after reading: %w", err) + } + + stdoutPath := os.Getenv("_BASS_OUTPUT") + os.Unsetenv("_BASS_OUTPUT") + + var stdout io.Writer = os.Stdout + if stdoutPath != "" { + response, err := os.Create(stdoutPath) + if err != nil { + return fmt.Errorf("create output error: %w", err) + } + + defer response.Close() + + stdout = response + } + + for _, e := range cmd.Env { + segs := strings.SplitN(e, "=", 2) + if len(segs) != 2 { + return fmt.Errorf("malformed env: %s", e) + } + + os.Setenv(segs[0], segs[1]) + } + + bin := cmd.Args[0] + argv := cmd.Args[1:] + execCmd := exec.Command(bin, argv...) + if cmd.Dir != nil { + execCmd.Dir = *cmd.Dir + } + execCmd.Stdin = bytes.NewBuffer(cmd.Stdin) + execCmd.Stdout = stdout + execCmd.Stderr = os.Stderr + + ch, err := reaper.Default.Start(execCmd) + if err != nil { + return fmt.Errorf("start: %w", err) + } + + status, err := reaper.Default.Wait(execCmd, ch) + if err != nil { + return fmt.Errorf("wait: %w", err) + } + + if status != 0 { + // propagate exit status + os.Exit(status) + return nil + } + + err = normalizeTimes(".") + if err != nil { + return fmt.Errorf("failed to normalize timestamps: %w", err) + } + + return nil +} + +func spawnReaper() error { + logger := StdLogger(logLevel) + + reaper.SetSubreaper(1) + + children := make(chan os.Signal, 32) + signal.Notify(children, syscall.SIGCHLD) + + go func() { + for range children { + err := reaper.Reap() + if err != nil { + logger.Warn("failed to reap", zap.Error(err)) + } + } + }() + + return nil +} + +var epoch = time.Date(1985, 10, 26, 8, 15, 0, 0, time.UTC) + +func normalizeTimes(root string) error { + logger := StdLogger(logLevel) + + skipped := 0 + unchanged := 0 + changed := 0 + start := time.Now() + tspec := unix.NsecToTimespec(epoch.UnixNano()) + targetTime := []unix.Timespec{tspec, tspec} + err := filepath.Walk(root, func(path string, info fs.FileInfo, err error) error { + if path != root && info.IsDir() { + mp, err := mountinfo.Mounted(path) + if err != nil { + return fmt.Errorf("check mounted: %w", err) + } + + if mp { + logger.Debug("skipping mountpoint", zap.String("path", path)) + skipped++ + return fs.SkipDir + } + } + + if info.ModTime().Equal(epoch) { + unchanged++ + return nil + } + + changed++ + + logger.Debug("chtimes", + zap.String("path", path), + zap.Time("from", info.ModTime()), + zap.Time("to", epoch)) + + err = unix.UtimesNanoAt(unix.AT_FDCWD, path, targetTime, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + return fmt.Errorf("chtimes: %w", err) + } + + return nil + }) + if err != nil { + return err + } + + logger.Info("times normalized", + zap.Duration("took", time.Since(start)), + zap.Int("changed", changed), + zap.Int("unchanged", unchanged), + zap.Int("skipped", skipped), + ) + + return nil +} diff --git a/pkg/runtimes/shim/tls.go b/pkg/runtimes/shim/tls.go index 15a63435..b81bdc85 100644 --- a/pkg/runtimes/shim/tls.go +++ b/pkg/runtimes/shim/tls.go @@ -1,7 +1,3 @@ -// Copyright 2018 The mkcert Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - package main import ( @@ -14,11 +10,6 @@ import ( var ( BassCAFile = "/bass/ca.crt" - - SystemTrustFilename string - SystemTrustCommand []string - - SystemTrustFile string ) var trusts = map[string][]string{ @@ -43,12 +34,6 @@ var bundles = []string{ "/etc/ssl/certs/ca-bundle.crt", } -func init() { - if SystemTrustFilename != "" { - SystemTrustFile = fmt.Sprintf(SystemTrustFilename, "bass") - } -} - func pathExists(path string) bool { _, err := os.Stat(path) return err == nil diff --git a/pkg/runtimes/shim/unpack.go b/pkg/runtimes/shim/unpack.go new file mode 100644 index 00000000..2e732146 --- /dev/null +++ b/pkg/runtimes/shim/unpack.go @@ -0,0 +1,174 @@ +package main + +import ( + "archive/tar" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "path" + "strings" + + "github.com/opencontainers/go-digest" + ispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/opencontainers/umoci/oci/cas" + "github.com/opencontainers/umoci/oci/casext" + "github.com/opencontainers/umoci/oci/layer" +) + +func unpack(args []string) error { + ctx := context.Background() + + if len(args) != 3 { + return fmt.Errorf("usage: unpack ") + } + + archiveSrc := args[0] + fromName := args[1] + rootfsPath := args[2] + + layout, err := openTar(archiveSrc) + if err != nil { + return fmt.Errorf("create layout: %w", err) + } + + defer layout.Close() + + ext := casext.NewEngine(layout) + + mspec, err := loadManifest(ctx, ext, fromName) + if err != nil { + return err + } + + err = layer.UnpackRootfs(context.Background(), ext, rootfsPath, mspec, &layer.UnpackOptions{}) + if err != nil { + return fmt.Errorf("unpack rootfs: %w", err) + } + + return nil +} + +func openTar(tarPath string) (cas.Engine, error) { + archive, err := os.Open(tarPath) + if err != nil { + return nil, err + } + + return &tarEngine{archive}, nil +} + +// tarEngine implements a read-only cas.Engine backed by a .tar archive. +type tarEngine struct { + archive *os.File +} + +func (engine *tarEngine) PutBlob(ctx context.Context, reader io.Reader) (digest.Digest, int64, error) { + return "", 0, fmt.Errorf("PutBlob: %w", cas.ErrNotImplemented) +} + +func (engine *tarEngine) GetBlob(ctx context.Context, dig digest.Digest) (io.ReadCloser, error) { + r, err := engine.open(path.Join("blobs", dig.Algorithm().String(), dig.Encoded())) + if err != nil { + return nil, err + } + + return io.NopCloser(r), nil +} + +func (engine *tarEngine) StatBlob(ctx context.Context, dig digest.Digest) (bool, error) { + _, err := engine.open(path.Join("blobs", dig.Algorithm().String(), dig.Encoded())) + if err != nil { + if errors.Is(err, cas.ErrNotExist) { + return false, nil + } + + return false, err + } + + return true, nil +} + +func (engine *tarEngine) PutIndex(ctx context.Context, index ispec.Index) error { + return fmt.Errorf("PutIndex: %w", cas.ErrNotImplemented) +} + +func (engine *tarEngine) GetIndex(ctx context.Context) (ispec.Index, error) { + var idx ispec.Index + r, err := engine.open("index.json") + if err != nil { + return ispec.Index{}, err + } + + err = json.NewDecoder(r).Decode(&idx) + if err != nil { + return ispec.Index{}, err + } + + return idx, nil +} + +func (engine *tarEngine) open(p string) (io.Reader, error) { + _, err := engine.archive.Seek(0, 0) + if err != nil { + return nil, fmt.Errorf("seek: %w", err) + } + + tr := tar.NewReader(engine.archive) + + for { + hdr, err := tr.Next() + if err != nil { + if err == io.EOF { + return nil, fmt.Errorf("open %s: %w", p, cas.ErrNotExist) + } + + return nil, err + } + + if path.Clean(hdr.Name) == p { + return tr, nil + } + } +} + +func (engine *tarEngine) DeleteBlob(ctx context.Context, digest digest.Digest) (err error) { + return fmt.Errorf("DeleteBlob: %w", cas.ErrNotImplemented) +} + +func (engine *tarEngine) ListBlobs(ctx context.Context) ([]digest.Digest, error) { + _, err := engine.archive.Seek(0, 0) + if err != nil { + return nil, fmt.Errorf("seek: %w", err) + } + + tr := tar.NewReader(engine.archive) + + var digs []digest.Digest + for { + hdr, err := tr.Next() + if err != nil { + if err == io.EOF { + break + } + + return nil, fmt.Errorf("next: %w", err) + } + + if strings.HasPrefix(path.Clean(hdr.Name), "blobs/") { + dir, encoded := path.Split(hdr.Name) + _, alg := path.Split(dir) + digs = append(digs, digest.NewDigestFromEncoded(digest.Algorithm(alg), encoded)) + } + } + + return digs, nil +} + +func (engine *tarEngine) Clean(ctx context.Context) error { return nil } + +func (engine *tarEngine) Close() error { + return engine.archive.Close() +} From 8416f8f8046e19a758133e568dfebdbab62556d8 Mon Sep 17 00:00:00 2001 From: Alex Suraci Date: Mon, 29 Aug 2022 13:16:17 -0400 Subject: [PATCH 32/32] more v0.10.0 notes --- notes/v0.10.0.md | 91 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 18 deletions(-) diff --git a/notes/v0.10.0.md b/notes/v0.10.0.md index dbab8279..b871292c 100644 --- a/notes/v0.10.0.md +++ b/notes/v0.10.0.md @@ -1,37 +1,92 @@ This is a big release that overhauls the networking stack and adds a new kind of value: a *thunk addr*. -Thunks can now provide ports: -```clojure -(-> ($ python -m http.server 80) - (with-image (linux/python)) - (with-port :http 80)) -``` - -Ports can be referenced using a [thunk addr]. A thunk addr is a lot like a -[thunk path] except it represents to a TCP address instead of a filesystem -path. +## thunk ports & addrs +Thunks can now provide TCP ports using [`with-port`] which can be referenced +with [`addr`] to construct a [thunk addr]: ```clojure (def srv - (-> ($ python -m http.server 80) + (-> ($ python -m http.server "80") (with-image (linux/python)) (with-port :http 80))) (-> ($ wget (addr srv :http "http://$host:$port")) - (with-image (linux/ubuntu)) + (with-image (linux/alpine)) run) ``` -The server thunk runs lazily. The client thunk doesn't run until the server's -ports are listening. +A thunk addr is a lot like a [thunk path] except it represents to a TCP address +instead of a filesystem path. + +When using a thunk addr you don't need to worry about managing the lifecycle of +the service that the thunk represents. The service will be run lazily, +de-duplicated across multiple Bass runs, and stopped when all clients go away. + +The advantage of this approach over traditional service lifecycle management +parallels the advantages of using thunk paths instead of managing state in a +local filesystem. It allows thunks that depend on services provided by other +thunks to remain reproducible, just like thunks that depend on files created by +other thunks. -Thunks no longer run in the host network. Instead they run in a [bridge -network] to prevent port collisions. +[`with-port`]: https://bass-lang.org/stdlib.html#binding-with-port +[`addr`]: https://bass-lang.org/stdlib.html#binding-addr +[thunk path]: https://bass-lang.org/bassics.html#term-thunk%20path +[thunk addr]: https://bass-lang.org/bassics.html#term-thunk%20addr -Thunks use DNS to address each other in order to maximize caching. (Using IPs -would introduce a source of randomness!) + +## bridge networking & DNS + +To prevent port collisions, thunks no longer run in the host network. Instead +they run in a [bridge network] where each thunk has its own IP and reaches +other thunks using DNS. + +Using DNS is important because IPs are not reproducible. If thunks reached each +other using direct container IPs then caches would be busted every time a +service runs. + +Now that thunks run in their own network, you can't use Bass to run and expose +services to the host machine. This may be added in a future release via port +forwarding. Alternatively you could take the `path-name` (a bit of a misnomer) +of the thunk and reverse-proxy to its container port using the same DNS server +that thunks use. [bridge network]: https://www.cni.dev/plugins/current/main/bridge/ +[`path-name`]: https://bass-lang.org/stdlib.html#binding-path-name + + +## automatic TLS + +Thunks may also use TLS. A unique "bass" certificate authority is generated by +the runtime and automaticaly trusted by all thunks that it runs. + +To generate a certificate for a thunk, use [`with-tls`]: + +```clojure +(def registry-mirror + (let [config {:version "0.1" + :http {:addr "0.0.0.0:5000" + :tls {:certificate "/registry.crt" + :key "/registry.key"}} + :storage {:filesystem {:rootdirectory "/var/lib/registry"}} + :proxy {:remoteurl "https://registry-1.docker.io"}}] + (-> ($ registry serve (mkfile ./config.yml (json config))) + (with-image (linux/registry)) + (with-tls /registry.crt /registry.key) + (with-port :http 5000)))) + +(defn main [] + (-> (from (linux/alpine) + ($ apk add curl) + ($ curl (addr registry-mirror :http "https://$host:$port/v2/"))) + run)) +``` + +Generating TLS certs is a necessary part of the puzzle because thunks use their +own hash as their hostname and DNS entry. It would be impossible to generate a +cert ahead of time and pass it to the thunk because doing so would change the +hash! + +[`with-tls`]: https://bass-lang.org/stdlib.html#binding-with-tls