diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..03c48ef --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..54fde2d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: ci + +on: + push: + branches: + - "*" + tags: + - 'v*' + +jobs: + ci: + runs-on: ubuntu-latest + env: + GH_USERNAME: ${{ github.actor }} + GH_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: docker/setup-qemu-action@v2 + + - run: curl -sSLf https://raw.githubusercontent.com/octohelm/wagon/main/install.sh | sudo sh + + - run: make ship + diff --git a/Makefile b/Makefile index fe1f136..95b9da6 100644 --- a/Makefile +++ b/Makefile @@ -2,34 +2,57 @@ ifneq ( ,$(wildcard .secrets/local.mk)) include .secrets/local.mk endif +WAGON = wagon -p wagon.cue + +DEBUG = 0 +ifeq ($(DEBUG),1) + WAGON := $(WAGON) --log-level=debug +endif + UNIFS = go run ./cmd/unifs +gen: + go run ./tool/internal/cmd/tool gen ./cmd/kubepkg + +ship: + $(WAGON) do go ship pushx + +manifests: + $(WAGON) do export manifests --output .tmp/ + +fmt: + cue fmt -s ./cuepkg/... + cue fmt -s ./cuedevpkg/... + goimports -w ./pkg + goimports -w ./cmd + dep: go get -u ./pkg/... test: go test -v ./pkg/... +install: + go install ./cmd/unifs + test.fuse: TEST_FUSE=1 \ go test -v -failfast ./pkg/fuse/... -mount.fs: - UNIFS_ENDPOINT=file:///tmp/data \ - $(UNIFS) mount /tmp/mnt +mount.fs: install + unifs mount --delegate \ + --backend=file:///tmp/data /tmp/mnt mount.webdav: - UNIFS_ENDPOINT=$(UNIFS_WEBDAV_ENDPOINT) \ - $(UNIFS) mount /tmp/mnt + $(UNIFS) mount \ + --backend=$(UNIFS_WEBDAV_ENDPOINT) /tmp/mnt mount.s3: - UNIFS_ENDPOINT=$(UNIFS_S3_ENDPOINT) \ - $(UNIFS) mount /tmp/mnt - -serve.webdav: - UNIFS_ENDPOINT=file:///tmp/data \ - $(UNIFS) webdav + $(UNIFS) mount \ + --backend=$(UNIFS_S3_ENDPOINT) /tmp/mnt +serve.webdav: install + unifs webdav --backend=file:///tmp/data test.remote.s3: TEST_S3_ENDPOINT=$(UNIFS_S3_ENDPOINT) \ @@ -38,3 +61,6 @@ test.remote.s3: test.remote.webdav: TEST_WEBDAV_ENDPOINT=$(UNIFS_WEBDAV_ENDPOINT) \ go test -v -failfast ./pkg/filesystem/webdav/... + +debug.apply: + KUBECONFIG=${HOME}/.kube_config/config--infra-staging.yaml kubectl apply -f .tmp/manifests/unifs.yaml \ No newline at end of file diff --git a/README.md b/README.md index 6fc15b2..a65f1ac 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # UniFS ```mermaid -flowchart TB +flowchart TB s3_fs[S3 FS] local_fs[Local FS] webdav_fs[WebDAV FS] @@ -17,4 +17,81 @@ flowchart TB fsi -->|serve| webdav_server fsi -->|mount| fuse_fs fsi -->|direct| go_code -``` \ No newline at end of file +``` + +### Supported Backends + +``` +webdav://:@[][?insecure=true] + +s3://:@/[][?insecure=true] + +file:// +``` + +### CSI + +### Create StorageClass + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: unifs +provisioner: csi-driver.unifs.octohelm.tech +parameters: + csi.storage.k8s.io/provisioner-secret-name: "${pvc.name}" + csi.storage.k8s.io/provisioner-secret-namespace: "${pvc.namespace}" + csi.storage.k8s.io/node-publish-secret-name: "${pvc.name}" + csi.storage.k8s.io/node-publish-secret-namespace: "${pvc.namespace}" +reclaimPolicy: Delete +``` + +### Create Secret && PersistentVolumeClaim +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: fuse-file + namespace: storage-system--unifs +type: Opaque +stringData: + backend: file:///data/unifs +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: fuse-file + namespace: storage-system--unifs +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: unifs + volumeMode: Filesystem +--- +apiVersion: v1 +kind: Pod +metadata: + name: task-pv-pod + namespace: storage-system--unifs +spec: + volumes: + - name: pv-storage + persistentVolumeClaim: + claimName: fuse-file + containers: + - name: web + image: nginx + ports: + - containerPort: 80 + name: "http" + volumeMounts: + - mountPath: "/usr/share/nginx/html" + name: pv-storage + +``` + diff --git a/cmd/unifs/csidriver.go b/cmd/unifs/csidriver.go new file mode 100644 index 0000000..f64162b --- /dev/null +++ b/cmd/unifs/csidriver.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/innoai-tech/infra/pkg/cli" + "github.com/innoai-tech/infra/pkg/otel" + + "github.com/octohelm/unifs/pkg/csidriver" +) + +func init() { + cli.AddTo(App, &CSIDriver{}) +} + +// Serve CSIDriver +type CSIDriver struct { + cli.C + Otel otel.Otel + + csidriver.Driver +} diff --git a/cmd/unifs/mount.go b/cmd/unifs/mount.go index 95cb848..ca10e5f 100644 --- a/cmd/unifs/mount.go +++ b/cmd/unifs/mount.go @@ -3,29 +3,25 @@ package main import ( "context" "fmt" + "github.com/octohelm/unifs/pkg/csidriver/mounter" + "os" + "github.com/go-courier/logr" "github.com/hanwen/go-fuse/v2/fs" fusefuse "github.com/hanwen/go-fuse/v2/fuse" "github.com/innoai-tech/infra/pkg/cli" "github.com/innoai-tech/infra/pkg/configuration" "github.com/innoai-tech/infra/pkg/otel" - "github.com/octohelm/unifs/pkg/filesystem" - "github.com/octohelm/unifs/pkg/filesystem/local" - "github.com/octohelm/unifs/pkg/filesystem/s3" - "github.com/octohelm/unifs/pkg/filesystem/webdav" + "github.com/octohelm/unifs/pkg/filesystem/api" "github.com/octohelm/unifs/pkg/fuse" "github.com/octohelm/unifs/pkg/strfmt" - "github.com/pkg/errors" - "os" - "time" + daemon "github.com/sevlyar/go-daemon" ) func init() { cli.AddTo(App, &Mount{}) } -var _ configuration.Server = &Mounter{} - // Mount as fuse fs type Mount struct { cli.C @@ -34,93 +30,72 @@ type Mount struct { Mounter } -type Mounter struct { - MountPoint string `arg:""` - // Source Endpoint - Endpoint strfmt.Endpoint `flag:"endpoint"` +var _ configuration.Runner = &Mounter{} - fsi filesystem.FileSystem `flag:"-"` - state *fusefuse.Server `flag:"-"` +type Mounter struct { + MountPoint string `arg:""` + Backend strfmt.Endpoint `flag:"backend"` + Foreground bool `flag:"foreground,omitempty"` + Delegate bool `flag:"delegate,omitempty"` } -func (m *Mounter) Init(ctx context.Context) error { - switch m.Endpoint.Scheme { - case "s3": - conf := &s3.Config{Endpoint: m.Endpoint} - c, err := conf.Client(ctx) +func (m *Mounter) Run(ctx context.Context) error { + if m.Delegate { + m2, err := mounter.NewMounter(ctx, m.Backend.String()) if err != nil { return err } - m.fsi = s3.NewS3FS(c, conf.Bucket(), conf.Prefix()) - case "webdav": - conf := &webdav.Config{Endpoint: m.Endpoint} - c, err := conf.Client(ctx) + return m2.Mount(m.MountPoint) + } + + if !m.Foreground { + dctx := &daemon.Context{} + p, err := dctx.Reborn() if err != nil { return err } - m.fsi = webdav.NewWebdavFS(c) - case "file": - m.fsi = local.NewLocalFS(m.Endpoint.Path) - default: - return errors.Errorf("unsupported endpoint %s", m.Endpoint) - } - return nil -} + if p != nil { + return nil + } + + defer dctx.Release() + } -func (m *Mounter) Serve(ctx context.Context) error { if err := os.MkdirAll(m.MountPoint, os.ModePerm); err != nil { return err } + b := &api.FileSystemBackend{} + b.Backend = m.Backend + + if err := b.Init(ctx); err != nil { + return err + } + options := &fs.Options{} - options.Name = fmt.Sprintf("%s.fs", m.Endpoint.Scheme) + options.Name = fmt.Sprintf("%s.fs", b.Backend.Scheme) //options.Debug = true - rawFS := fs.NewNodeFS(fuse.FS(m.fsi), options) + rawFS := fs.NewNodeFS(fuse.FS(b.FileSystem()), options) state, err := fusefuse.NewServer(rawFS, m.MountPoint, &options.MountOptions) if err != nil { return err } - m.state = state logr.FromContext(ctx). WithValues( - "fsi", m.Endpoint.Scheme, + "fsi", m.Backend.Scheme, "on", m.MountPoint, ). Info("mounted") - state.Serve() - return nil -} - -func (m *Mounter) Shutdown(ctx context.Context) error { - if m.state == nil { - return nil + if !m.Foreground { + go state.Serve() + return daemon.ServeSignals() } - errCh := make(chan error) - - go func() { - for i := 0; i < 5; i++ { - err := m.state.Unmount() - if err == nil { - errCh <- err - return - } - logr.FromContext(ctx).Warn(errors.Wrap(err, "unmount failed")) - time.Sleep(time.Second) - logr.FromContext(ctx).Info("retrying...") - } - errCh <- m.state.Unmount() - }() - - select { - case <-ctx.Done(): - return ctx.Err() - case err := <-errCh: - return err - } + state.Serve() + return nil } diff --git a/cmd/unifs/webdav.go b/cmd/unifs/webdav.go index e28bc90..58ec1e5 100644 --- a/cmd/unifs/webdav.go +++ b/cmd/unifs/webdav.go @@ -2,20 +2,15 @@ package main import ( "context" + "net/http" + "runtime" + "github.com/go-courier/logr" "github.com/innoai-tech/infra/pkg/cli" "github.com/innoai-tech/infra/pkg/configuration" "github.com/innoai-tech/infra/pkg/otel" - "github.com/pkg/errors" + "github.com/octohelm/unifs/pkg/filesystem/api" netwebdav "golang.org/x/net/webdav" - "net/http" - "runtime" - - "github.com/octohelm/unifs/pkg/filesystem" - "github.com/octohelm/unifs/pkg/filesystem/local" - "github.com/octohelm/unifs/pkg/filesystem/s3" - "github.com/octohelm/unifs/pkg/filesystem/webdav" - "github.com/octohelm/unifs/pkg/strfmt" ) func init() { @@ -33,13 +28,11 @@ type WebDAV struct { } type WebDAVServer struct { - // Source Endpoint - Endpoint strfmt.Endpoint `flag:"endpoint"` - Addr string `flag:"addr,omitempty"` - fsi filesystem.FileSystem `flag:"-"` - svc *http.Server `flag:"-"` + api.FileSystemBackend + + svc *http.Server `flag:"-"` } func (s *WebDAVServer) SetDefaults() { @@ -48,33 +41,9 @@ func (s *WebDAVServer) SetDefaults() { } } -func (s *WebDAVServer) Init(ctx context.Context) error { - switch s.Endpoint.Scheme { - case "s3": - conf := &s3.Config{Endpoint: s.Endpoint} - c, err := conf.Client(ctx) - if err != nil { - return err - } - s.fsi = s3.NewS3FS(c, conf.Bucket(), conf.Prefix()) - case "webdav": - conf := &webdav.Config{Endpoint: s.Endpoint} - c, err := conf.Client(ctx) - if err != nil { - return err - } - s.fsi = webdav.NewWebdavFS(c) - case "file": - s.fsi = local.NewLocalFS(s.Endpoint.Path) - default: - return errors.Errorf("unsupported endpoint %s", s.Endpoint) - } - return nil -} - func (s *WebDAVServer) Serve(ctx context.Context) error { h := &netwebdav.Handler{ - FileSystem: s.fsi, + FileSystem: s.FileSystem(), LockSystem: netwebdav.NewMemLS(), } diff --git a/cue.mod/.gitignore b/cue.mod/.gitignore new file mode 100755 index 0000000..f5d0b6d --- /dev/null +++ b/cue.mod/.gitignore @@ -0,0 +1,3 @@ +gen/ +pkg/ +module.sum \ No newline at end of file diff --git a/cue.mod/module.cue b/cue.mod/module.cue new file mode 100755 index 0000000..bbf8554 --- /dev/null +++ b/cue.mod/module.cue @@ -0,0 +1,7 @@ +module: "github.com/octohelm/unifs" + +require: { + "github.com/innoai-tech/runtime": "v0.0.0-20230807071635-a566ade1c374" + "github.com/octohelm/kubepkg": "v0.5.3" + "wagon.octohelm.tech": "v0.0.0-20200202235959-ed2bb31d4b08" +} diff --git a/cuedevpkg/tool/kubepkg_export.cue b/cuedevpkg/tool/kubepkg_export.cue new file mode 100644 index 0000000..e8aec22 --- /dev/null +++ b/cuedevpkg/tool/kubepkg_export.cue @@ -0,0 +1,156 @@ +package tool + +import ( + "path" + "strings" + "encoding/json" + + "wagon.octohelm.tech/core" + + spec "github.com/octohelm/kubepkg/cuepkg/kubepkg" +) + +#Export: { + name: string + namespace: string + + platforms: [...string] | *["linux/amd64", "linux/arm64"] + + kubepkg: spec.#KubePkg | spec.#KubePkgList + + _files: "/src/kubepkg.json": core.#WriteFile & { + contents: json.Marshal([ + + if (kubepkg & spec.#KubePkg) != _|_ { + kubepkg & { + metadata: "namespace": "\(namespace)" + } + }, + + if (kubepkg & spec.#KubePkgList) != _|_ { + spec.#KubePkgList & { + items: [ + for k in kubepkg.items { + k & { + metadata: "namespace": "\(namespace)" + } + }, + ] + } + }, + {}, + ][0]) + path: "kubepkg.json" + } + + airgap: { + _env: core.#ClientEnv & { + KUBEPKG_REMOTE_REGISTRY_ENDPOINT: _ | *"" + KUBEPKG_REMOTE_REGISTRY_USERNAME: _ | *"" + KUBEPKG_REMOTE_REGISTRY_PASSWORD: core.#Secret + } + + _airgap: { + for p in platforms { + "\(p)": { + _image: #Image & { + platform: "\(p)" + } + + _run: #Run & { + input: _image.output + mounts: { + for p, f in _files { + "\(p)": core.#Mount & { + dest: p + source: f.path + contents: f.output + } + } + + "kubepkg-storage": core.#Mount & { + dest: "/etc/kubepkg" + contents: core.#CacheDir & { + id: "kubepkg-storage" + } + } + } + env: { + KUBEPKG_REMOTE_REGISTRY_ENDPOINT: _env.KUBEPKG_REMOTE_REGISTRY_ENDPOINT + KUBEPKG_REMOTE_REGISTRY_USERNAME: _env.KUBEPKG_REMOTE_REGISTRY_USERNAME + KUBEPKG_REMOTE_REGISTRY_PASSWORD: _env.KUBEPKG_REMOTE_REGISTRY_PASSWORD + } + command: { + "name": "export" + args: [ + "--storage-root=/etc/kubepkg", + "--output-oci=/build/images/\(p)/\(name).airgap.tar", + "--platform=\(p)", + "/src/kubepkg.json", + ] + } + } + + _copy: core.#Copy & { + contents: _run.output.rootfs + source: "/build" + dest: "/" + } + + output: _copy.output + } + } + } + + _merge: core.#Merge & { + inputs: [ + for p in platforms { + _airgap["\(p)"].output + }, + ] + } + + output: _merge.output + } + + manifests: { + _image: #Image & {} + + _run: #Run & { + input: _image.output + mounts: { + for p, f in _files { + "\(p)": core.#Mount & { + dest: p + source: f.path + contents: f.output + } + } + } + command: { + "name": "export" + args: [ + "--platform=\(strings.Join(platforms, ","))", + "--output-manifests=/build/manifests/\(path.Base(name)).yaml", + "--output-dir-external-config=/build/external-configs/", + "/src/kubepkg.json", + ] + } + } + + _copy: core.#Copy & { + contents: _run.output.rootfs + source: "/build" + dest: "/" + } + + output: _copy.output + } + + all: core.#Merge & { + inputs: [ + airgap.output, + manifests.output, + ] + } +} diff --git a/cuedevpkg/tool/kubepkg_run.cue b/cuedevpkg/tool/kubepkg_run.cue new file mode 100644 index 0000000..2230762 --- /dev/null +++ b/cuedevpkg/tool/kubepkg_run.cue @@ -0,0 +1,23 @@ +package tool + +import ( + "wagon.octohelm.tech/docker" +) + +#DefaultTag: "v0.5.4-0.20230801041258-e2b3c1b81449" + +#Run: { + tag: string | *#DefaultTag + + docker.#Run & { + workdir: "/build" + } +} + +#Image: { + tag: string | *#DefaultTag + + docker.#Pull & { + source: _ | *"ghcr.io/octohelm/kubepkg:\(tag)" + } +} diff --git a/cuepkg/csidriver/c_attacher.cue b/cuepkg/csidriver/c_attacher.cue new file mode 100644 index 0000000..9135720 --- /dev/null +++ b/cuepkg/csidriver/c_attacher.cue @@ -0,0 +1,138 @@ +package csidriver + +import ( + kubepkgspec "github.com/octohelm/kubepkg/cuepkg/kubepkg" +) + +#Attacher: { + #values: kubelet: root: string | *"/var/lib/k0s/kubelet" + + kubepkgspec.#KubePkg & { + metadata: name: "csi-attacher-unifs" + + spec: { + version: _ | *"1.0.0" + + deploy: { + kind: "StatefulSet" + spec: serviceName: "csi-attacher-unifs" + + spec: template: spec: tolerations: [ + { + key: "node-role.kubernetes.io/master" + operator: "Exists" + }, + ] + } + + containers: "csi-attacher": { + image: { + name: _ | *"registry.k8s.io/sig-storage/csi-attacher" + tag: _ | *"v4.3.0" + } + + args: [ + "--csi-address=$(ADDRESS)", + ] + + env: ADDRESS: "\(#values.kubelet.root)/plugins/\(#DriverName)/csi.sock" + } + + volumes: "socket-dir": { + type: "HostPath" + mountPath: "\(#values.kubelet.root)/plugins/\(#DriverName)" + opt: { + path: "\(#values.kubelet.root)/plugins/\(#DriverName)" + type: "DirectoryOrCreate" + } + } + + serviceAccount: #AttacherServiceAccount + } + } +} + +#AttacherServiceAccount: kubepkgspec.#ServiceAccount & { + scope: "Cluster" + rules: [ + { + apiGroups: [ + "", + ] + resources: [ + "secrets", + ] + verbs: [ + "get", + "list", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "events", + ] + verbs: [ + "get", + "list", + "watch", + "update", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "persistentvolumes", + ] + verbs: [ + "get", + "list", + "watch", + "update", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "nodes", + ] + verbs: [ + "get", + "list", + "watch", + ] + }, + { + apiGroups: [ + "storage.k8s.io", + ] + resources: [ + "volumeattachments", + ] + verbs: [ + "get", + "list", + "watch", + "update", + "patch", + ] + }, + { + apiGroups: [ + "storage.k8s.io", + ] + resources: [ + "volumeattachments/status", + ] + verbs: [ + "patch", + ] + }, + ] +} diff --git a/cuepkg/csidriver/c_driver.cue b/cuepkg/csidriver/c_driver.cue new file mode 100644 index 0000000..5f84376 --- /dev/null +++ b/cuepkg/csidriver/c_driver.cue @@ -0,0 +1,180 @@ +package csidriver + +import ( + kubepkgspec "github.com/octohelm/kubepkg/cuepkg/kubepkg" +) + +#Driver: { + #values: { + kubelet: root: string | *"/var/lib/k0s/kubelet" + pods: root: string | *"/data/k0s/kubelet/pods" + } + + kubepkgspec.#KubePkg & { + metadata: name: "csi-driver-unifs" + + spec: { + version: _ | *"1.0.0" + + deploy: { + kind: "DaemonSet" + spec: template: spec: { + hostNetwork: true + dnsPolicy: "ClusterFirstWithHostNet" + } + } + + containers: { + "driver-registrar": { + image: { + // https://kubernetes-csi.github.io/docs/node-driver-registrar.html + name: _ | *"registry.k8s.io/sig-storage/csi-node-driver-registrar" + tag: _ | *"v2.8.0" + } + + args: [ + "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)", + "--csi-address=$(ADDRESS)", + ] + + env: { + ADDRESS: "/csi/csi.sock" + DRIVER_REG_SOCK_PATH: "\(#values.kubelet.root)/plugins/\(#DriverName)/csi.sock" + KUBE_NODE_NAME: "@field/spec.nodeName" + } + + securityContext: { + privileged: true + capabilities: add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + } + } + "csi-driver": { + image: { + name: _ | *"ghcr.io/octohelm/unifs" + tag: _ | *"\(spec.version)" + } + args: [ + "csidriver", + "--endpoint=$(CSI_ENDPOINT)", + "--nodeid=$(NODE_ID)", + ] + env: { + CSI_ENDPOINT: "unix:///csi/csi.sock" + NODE_ID: "@field/spec.nodeName" + } + securityContext: { + privileged: true + capabilities: add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + } + } + } + + volumes: { + "registration-dir": { + mountPath: "/registration/" + type: "HostPath" + opt: path: "\(#values.kubelet.root)/plugins_registry/" + } + + "plugin-dir": { + mountPath: "/csi" + type: "HostPath" + opt: path: "\(#values.kubelet.root)/plugins/\(#DriverName)" + } + + "pods-dir": { + mountPath: "\(#values.pods.root)" + mountPropagation: "Bidirectional" + type: "HostPath" + opt: path: "\(#values.pods.root)" + } + + "fuse-device": { + type: "HostPath" + mountPath: "/dev/fuse" + opt: path: "/dev/fuse" + } + data: { + mountPath: "/data" + type: "HostPath" + opt: path: "/data" + } + } + + serviceAccount: #DriverServiceAccount + } + } +} + +#DriverServiceAccount: kubepkgspec.#ServiceAccount & { + scope: "Cluster" + rules: [ + { + apiGroups: [ + "", + ] + resources: [ + "secrets", + ] + verbs: [ + "get", + "list", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "nodes", + ] + verbs: [ + "get", + "list", + "update", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "namespaces", + ] + verbs: [ + "get", + "list", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "persistentvolumes", + ] + verbs: [ + "get", + "list", + "watch", + "update", + ] + }, + { + apiGroups: [ + "storage.k8s.io", + ] + resources: [ + "volumeattachments", + ] + verbs: [ + "get", + "list", + "watch", + "update", + ] + }, + ] +} diff --git a/cuepkg/csidriver/c_provisioner.cue b/cuepkg/csidriver/c_provisioner.cue new file mode 100644 index 0000000..67eb9a4 --- /dev/null +++ b/cuepkg/csidriver/c_provisioner.cue @@ -0,0 +1,142 @@ +package csidriver + +import ( + kubepkgspec "github.com/octohelm/kubepkg/cuepkg/kubepkg" +) + +#Provisioner: { + #values: kubelet: root: string | *"/var/lib/k0s/kubelet" + + kubepkgspec.#KubePkg & { + metadata: name: "csi-provisioner-unifs" + + spec: { + version: _ | *"1.0.0" + + deploy: { + kind: "StatefulSet" + spec: serviceName: "csi-provisioner" + + spec: template: spec: tolerations: [ + { + key: "node-role.kubernetes.io/master" + operator: "Exists" + }, + ] + } + + containers: { + "csi-provisioner": { + image: { + name: _ | *"registry.k8s.io/sig-storage/csi-provisioner" + tag: _ | *"v3.5.0" + } + + args: [ + "--v=4", + "--csi-address=$(ADDRESS)", + ] + + env: ADDRESS: "\(#values.kubelet.root)/plugins/\(#DriverName)/csi.sock" + } + "csi-driver": { + image: { + name: _ | *"ghcr.io/octohelm/unifs" + tag: _ | *"\(spec.version)" + } + args: [ + "csidriver", + "--endpoint=$(CSI_ENDPOINT)", + "--nodeid=$(NODE_ID)", + ] + env: { + CSI_ENDPOINT: "unix://\(#values.kubelet.root)/plugins/\(#DriverName)/csi.sock" + NODE_ID: "@field/spec.nodeName" + } + } + } + + volumes: "socket-dir": { + type: "EmptyDir" + mountPath: "\(#values.kubelet.root)/plugins/\(#DriverName)" + } + + serviceAccount: #ProvisionerServiceAccount + } + } +} + +#ProvisionerServiceAccount: kubepkgspec.#ServiceAccount & { + scope: "Cluster" + rules: [ + { + apiGroups: [ + "", + ] + resources: [ + "secrets", + ] + verbs: [ + "get", + "list", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "persistentvolumes", + ] + verbs: [ + "get", + "list", + "watch", + "create", + "delete", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "persistentvolumeclaims", + ] + verbs: [ + "get", + "list", + "watch", + "update", + ] + }, + { + apiGroups: [ + "storage.k8s.io", + ] + resources: [ + "storageclasses", + ] + verbs: [ + "get", + "list", + "watch", + ] + }, + { + apiGroups: [ + "", + ] + resources: [ + "events", + ] + verbs: [ + "list", + "watch", + "create", + "update", + "patch", + ] + }, + ] +} diff --git a/cuepkg/csidriver/common.cue b/cuepkg/csidriver/common.cue new file mode 100644 index 0000000..1927d7e --- /dev/null +++ b/cuepkg/csidriver/common.cue @@ -0,0 +1,3 @@ +package csidriver + +#DriverName: "csi-driver.unifs.octohelm.tech" diff --git a/cuepkg/csidriver/entry.cue b/cuepkg/csidriver/entry.cue new file mode 100644 index 0000000..728e632 --- /dev/null +++ b/cuepkg/csidriver/entry.cue @@ -0,0 +1,29 @@ +package csidriver + +import ( + kubepkgspec "github.com/octohelm/kubepkg/cuepkg/kubepkg" +) + +#Provider: { + #values: { + version: string | *"v1.0.0" + + provisioner: #Provisioner & { + spec: "version": version + } + driver: #Driver & { + spec: "version": version + } + attacher: #Attacher & { + spec: "version": version + } + } + + kubepkgspec.#KubePkgList & { + items: [ + #values.provisioner, + #values.driver, + #values.attacher, + ] + } +} diff --git a/go.mod b/go.mod index d7024b8..ab6483c 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,24 @@ module github.com/octohelm/unifs go 1.21 require ( + github.com/container-storage-interface/spec v1.8.0 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/go-courier/logr v0.3.0 + github.com/golang/protobuf v1.5.3 github.com/hanwen/go-fuse/v2 v2.3.0 github.com/innoai-tech/infra v0.0.0-20230809024609-b28415b90502 github.com/johannesboyne/gofakes3 v0.0.0-20230506070712-04da935ef877 + github.com/kubernetes-csi/csi-test/v5 v5.0.0 github.com/minio/minio-go/v7 v7.0.61 + github.com/mitchellh/go-ps v1.0.0 + github.com/octohelm/gengo v0.0.0-20230809023313-1339e47458a4 github.com/octohelm/x v0.0.0-20230809025256-29102caf446f github.com/pkg/errors v0.9.1 + github.com/sevlyar/go-daemon v0.1.6 golang.org/x/net v0.14.0 golang.org/x/sync v0.3.0 + google.golang.org/grpc v1.57.0 + k8s.io/utils v0.0.0-20230711102312-30195339c3c7 ) require ( @@ -34,10 +42,14 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/uuid v1.3.0 // indirect github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 // indirect @@ -45,9 +57,13 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/julienschmidt/httprouter v1.3.0 // indirect + github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -55,10 +71,9 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/octohelm/gengo v0.0.0-20230809023313-1339e47458a4 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/onsi/gomega v1.27.10 // indirect - github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.16.0 // indirect @@ -97,11 +112,10 @@ require ( golang.org/x/tools v0.12.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230807174057-1744710a1577 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect - google.golang.org/grpc v1.57.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230814215434-ca7cfce7776a // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/kube-openapi v0.0.0-20230606174411-725288a7abf1 // indirect + k8s.io/klog/v2 v2.100.1 // indirect ) diff --git a/go.sum b/go.sum index 7a5af46..000e42b 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -91,10 +92,18 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +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-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/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd/v3 v3.2.0 h1:79kHCn4tO0VGu3W0WujYrMjBDk8a2H4KEUYcXf7whcg= github.com/cockroachdb/apd/v3 v3.2.0/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= +github.com/container-storage-interface/spec v1.6.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s= +github.com/container-storage-interface/spec v1.8.0 h1:D0vhF3PLIZwlwZEf2eNbpujGCNwspwTYf2idJRJx4xI= +github.com/container-storage-interface/spec v1.8.0/go.mod h1:ROLik+GhPslwwWRNFF1KasPzroNARibH2rfz1rkg4H0= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -125,6 +134,8 @@ github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -132,8 +143,11 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBF github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-courier/logr v0.3.0 h1:0VEQB1b53EmYQ+ZehrIgD8l2IO+WX7TY+CqzlykIFmo= github.com/go-courier/logr v0.3.0/go.mod h1:OI7f/JCFZ1ZMD5qG3bIJr5WMNnGzd24+II1D9D9w5x4= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -149,6 +163,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -165,6 +180,7 @@ github.com/go-quicktest/qt v1.100.0/go.mod h1:leyLsQ4jksGmF1KaQEyabnqGIiJTbOU5S4 github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= @@ -177,8 +193,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -189,6 +205,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -204,6 +221,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -223,6 +241,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -239,9 +259,11 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +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= @@ -252,6 +274,7 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 h1:dygLcbEBA+t/P7ck6a8AkXv6juQ4cK0RHBoh32jxhHM= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2/go.mod h1:Ap9RLCIJVtgQg1/BBgVEfypOAySvvlcpcVQkSzJCH4Y= github.com/hanwen/go-fuse/v2 v2.3.0 h1:t5ivNIH2PK+zw4OBul/iJjsoG9K6kXo4nMDoBpciC8A= @@ -284,7 +307,9 @@ github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hetznercloud/hcloud-go/v2 v2.0.0 h1:Sg1DJ+MAKvbYAqaBaq9tPbwXBS2ckPIaMtVdUjKu+4g= github.com/hetznercloud/hcloud-go/v2 v2.0.0/go.mod h1:4iUG2NG8b61IAwNx6UsMWQ6IfIf/i1RsG0BbsKAyR5Q= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -311,7 +336,10 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= 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.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= @@ -331,6 +359,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kubernetes-csi/csi-test/v5 v5.0.0 h1:GJ0M+ppcKgWhafXH3B2Ssfw1Egzly9GlMx3JOQApekM= +github.com/kubernetes-csi/csi-test/v5 v5.0.0/go.mod h1:jVEIqf8Nv1roo/4zhl/r6Tc68MAgRX/OQSQK0azTHyo= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= @@ -342,6 +372,7 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -357,6 +388,8 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= 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.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -377,14 +410,32 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/octohelm/courier v0.0.0-20230809023744-57fc047576ed h1:1KD96DdeenVneridbsO2aqsMkOg7MFg3zLmejBcOzWc= +github.com/octohelm/courier v0.0.0-20230809023744-57fc047576ed/go.mod h1:KpswGpveCA40rhieNtbGMm95iqxzbsv9Ir7gcgIb09E= github.com/octohelm/gengo v0.0.0-20230809023313-1339e47458a4 h1:wmmT8Xn6kUwKhzJva3JlFRPVnCTMrdSyVZTp6K0NAtg= github.com/octohelm/gengo v0.0.0-20230809023313-1339e47458a4/go.mod h1:FmonJDnRb/0KoFSDB/OgptioHK/RBm820MJ7cjeIMaE= +github.com/octohelm/kubepkg v0.5.3 h1:Zwk6ve1Hgn5BncaMruk5Gu4/hoQTSoDGlzqMVFwNgQc= +github.com/octohelm/kubepkg v0.5.3/go.mod h1:gOfU662T2q2YupTwgQ7MDGHZ8BN3uBbuHMQXEfVX9T0= +github.com/octohelm/storage v0.0.0-20230809023612-f4199ff2c708 h1:WDFBhyHy1uhyX2EfDzG5mC43/oKhCbGr5/AMLQGeRs0= +github.com/octohelm/storage v0.0.0-20230809023612-f4199ff2c708/go.mod h1:xwnVwo/peOIW7nAWY/kW5YBbmA/DQPF60OMzcQeboPk= github.com/octohelm/x v0.0.0-20230809025256-29102caf446f h1:UlyE6liyF7eYKTV05GPSSzBrrMvIeOvLIbv4BNy+AdE= github.com/octohelm/x v0.0.0-20230809025256-29102caf446f/go.mod h1:/Ma+XQLA4p63sGnwQpcSzxYPQifAe76gDrHji2DhDUw= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -432,6 +483,7 @@ github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73 github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4= github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4= github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -442,6 +494,8 @@ github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.19 h1:+1H+N9QFl2Sfvia0FBYfMrHYHYhmpZxhSE0wpPL2lYs= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.19/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs= +github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 h1:WnNuhiq+FOY3jNj6JXFT+eLN3CQ/oPIsDPRanvwsmbI= github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500/go.mod h1:+njLrG5wSeoG4Ds61rFgEzKvenR2UHbjMoDHsczxly0= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -462,6 +516,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -471,6 +526,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -500,6 +557,7 @@ go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh4 go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -547,6 +605,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -554,6 +614,7 @@ golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -576,6 +637,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -583,8 +645,14 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= @@ -608,12 +676,14 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -624,7 +694,10 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/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-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -645,16 +718,28 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -724,7 +809,10 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= @@ -781,18 +869,20 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201209185603-f92720507ed4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= google.golang.org/genproto/googleapis/api v0.0.0-20230807174057-1744710a1577 h1:xv8KoglAClYGkprUSmDTKaILtzfD8XzG9NYVXMprjKo= google.golang.org/genproto/googleapis/api v0.0.0-20230807174057-1744710a1577/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230814215434-ca7cfce7776a h1:5rTPHLf5eLPfqGvw3fLpEmUpko2Ky91ft14LxGs5BZc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230814215434-ca7cfce7776a/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= 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.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -805,6 +895,9 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -819,6 +912,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -828,13 +923,16 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -857,7 +955,7 @@ k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8= k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230606174411-725288a7abf1 h1:+cCtos65A2ydaMUSnO+IXcIYvhn1H+VxclLQuXYp63g= diff --git a/pkg/csidriver/driver.go b/pkg/csidriver/driver.go new file mode 100644 index 0000000..7f3132e --- /dev/null +++ b/pkg/csidriver/driver.go @@ -0,0 +1,192 @@ +package csidriver + +import ( + "context" + "fmt" + "net" + "strings" + + "github.com/octohelm/unifs/pkg/strfmt" + "github.com/pkg/errors" + + "github.com/container-storage-interface/spec/lib/go/csi" + "github.com/go-courier/logr" + "github.com/innoai-tech/infra/pkg/configuration" + "google.golang.org/grpc" + + "github.com/octohelm/unifs/internal/version" +) + +const ( + DefaultDriverName = "csi-driver.unifs.octohelm.tech" + backend = "backend" +) + +var _ configuration.Server = &Driver{} + +type Driver struct { + Endpoint string `flag:"endpoint"` + NodeID string `flag:"nodeid"` + + dctx DriverContext + svc *grpc.Server +} + +func (d *Driver) Init(ctx context.Context) error { + logErr := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + resp, err := handler(ctx, req) + if err != nil { + logr.FromContext(ctx).Error(err) + } + return resp, err + } + + opts := []grpc.ServerOption{ + grpc.UnaryInterceptor(logErr), + } + + d.dctx = DriverContext{ + Name: DefaultDriverName, + VendorVersion: version.Version(), + NodeID: d.NodeID, + } + + d.dctx.AddControllerServiceCapabilities(csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) + + d.dctx.AddVolumeCapabilityAccessModes(csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER) + + d.svc = grpc.NewServer(opts...) + + csi.RegisterIdentityServer(d.svc, &identityServer{ + DriverContext: d.dctx, + l: logr.FromContext(ctx).WithValues("server", "identity"), + }) + + csi.RegisterControllerServer(d.svc, &controllerServer{ + DriverContext: d.dctx, + l: logr.FromContext(ctx).WithValues("server", "controller"), + }) + + csi.RegisterNodeServer(d.svc, &nodeServer{ + DriverContext: d.dctx, + l: logr.FromContext(ctx).WithValues("server", "node"), + }) + + return nil +} + +func (d *Driver) Serve(ctx context.Context) error { + scheme, addr, err := ParseEndpoint(d.Endpoint) + if err != nil { + return err + } + + listener, err := net.Listen(scheme, addr) + if err != nil { + return err + } + + logr.FromContext(ctx).Info(fmt.Sprintf("Listening for connections on address: %s", listener.Addr())) + + return d.svc.Serve(listener) +} + +func (d *Driver) Shutdown(ctx context.Context) error { + done := make(chan error) + + go func() { + d.svc.GracefulStop() + done <- nil + }() + + select { + case <-ctx.Done(): + d.svc.Stop() + case <-done: + return nil + } + + return nil +} + +type DriverContext struct { + Name string + VendorVersion string + NodeID string + + ControllerServiceCapabilities []*csi.ControllerServiceCapability + VolumeCapabilityAccessModes []*csi.VolumeCapability_AccessMode + + ns *nodeServer +} + +func (n *DriverContext) AddControllerServiceCapabilities(cl ...csi.ControllerServiceCapability_RPC_Type) { + var csc []*csi.ControllerServiceCapability + for _, c := range cl { + csc = append(csc, NewControllerServiceCapability(c)) + } + n.ControllerServiceCapabilities = csc +} + +func (n *DriverContext) AddVolumeCapabilityAccessModes(nl ...csi.VolumeCapability_AccessMode_Mode) { + var nac []*csi.VolumeCapability_AccessMode + for _, n := range nl { + nac = append(nac, NewVolumeCapabilityAccessMode(n)) + } + n.VolumeCapabilityAccessModes = nac +} + +func newVolume(name string, size int64, secrets map[string]string, params map[string]string) (*volume, error) { + vol := &volume{} + vol.size = size + + vol.uuid = name + + for k, v := range secrets { + switch k { + case backend: + e, err := strfmt.ParseEndpoint(v) + if err != nil { + return nil, err + } + + vol.scheme = e.Scheme + vol.host = e.Host() + vol.base = strings.Trim(e.Path, "/") + } + } + + vol.id = strings.Join([]string{ + vol.scheme, + vol.host, + vol.base, + vol.uuid, + }, "#") + + return vol, nil +} + +type volume struct { + id string + uuid string + scheme string + host string + base string + size int64 +} + +func volumeFromID(id string) (*volume, error) { + segments := strings.Split(id, "#") + + if len(segments) != 4 { + return nil, errors.Errorf("invalid id %s", id) + } + + return &volume{ + id: id, + scheme: segments[0], + host: segments[1], + base: segments[2], + uuid: segments[3], + }, nil +} diff --git a/pkg/csidriver/driver_test.go b/pkg/csidriver/driver_test.go new file mode 100644 index 0000000..0783b8d --- /dev/null +++ b/pkg/csidriver/driver_test.go @@ -0,0 +1,47 @@ +package csidriver + +import ( + "context" + "path/filepath" + "testing" + + "github.com/go-courier/logr" + "github.com/go-courier/logr/slog" + + "github.com/kubernetes-csi/csi-test/v5/pkg/sanity" +) + +func TestDriver(t *testing.T) { + t.Skip() + + driver := newDriver(t) + + sanityCfg := sanity.NewTestConfig() + sanityCfg.Address = driver.Endpoint + sanityCfg.TargetPath = filepath.Join(t.TempDir(), "target") + sanityCfg.StagingPath = filepath.Join(t.TempDir(), "staging") + + sanityCfg.SecretsFile = "testdata/secrets.yaml" + + sanity.Test(t, sanityCfg) +} + +func newDriver(t *testing.T) *Driver { + ctx := logr.WithLogger(context.Background(), slog.Logger(slog.Default())) + + socket := filepath.Join(t.TempDir(), "csi-driver.sock") + + driver := &Driver{} + driver.Endpoint = "unix://" + socket + driver.NodeID = "test-node" + if err := driver.Init(ctx); err != nil { + t.Fatal(err) + } + go func() { + _ = driver.Serve(ctx) + }() + t.Cleanup(func() { + _ = driver.Shutdown(ctx) + }) + return driver +} diff --git a/pkg/csidriver/mounter/mounter.go b/pkg/csidriver/mounter/mounter.go new file mode 100644 index 0000000..eea30d1 --- /dev/null +++ b/pkg/csidriver/mounter/mounter.go @@ -0,0 +1,140 @@ +package mounter + +import ( + "context" + "fmt" + "os" + "os/exec" + "strings" + "time" + + "github.com/pkg/errors" + + "github.com/mitchellh/go-ps" + "github.com/octohelm/unifs/pkg/filesystem/api" + "github.com/octohelm/unifs/pkg/strfmt" + "k8s.io/utils/mount" +) + +type Mounter interface { + Mount(mountPoint string) error +} + +func NewMounter(ctx context.Context, backendStr string) (Mounter, error) { + backend, err := strfmt.ParseEndpoint(backendStr) + if err != nil { + return nil, err + } + + b := api.FileSystemBackend{} + b.Backend = *backend + + // just for param check + if err := b.Init(ctx); err != nil { + return nil, err + } + + return &mounter{ + Backend: b.Backend, + }, nil +} + +type mounter struct { + Backend strfmt.Endpoint +} + +func (m *mounter) Mount(mountPoint string) error { + if err := os.MkdirAll(mountPoint, os.ModePerm); err != nil { + return err + } + + p, err := os.Executable() + if err != nil { + return err + } + + args := []string{ + "mount", + "--backend", m.Backend.String(), + mountPoint, + } + + cmd := exec.Command(p, args...) + cmd.Env = os.Environ() + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "FuseMount: %s\n", append([]string{p}, args...)) + } + + return waitForMount(mountPoint, 10*time.Second) +} + +func FuseUnmount(path string) error { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + + m := mount.New("") + + notMount, err := m.IsLikelyNotMountPoint(path) + if err != nil { + return err + } + + if notMount { + return nil + } + + if err := m.Unmount(path); err != nil { + return err + } + return nil +} + +func waitForMount(path string, timeout time.Duration) error { + var elapsed time.Duration + var interval = 10 * time.Millisecond + for { + notMount, err := mount.New("").IsLikelyNotMountPoint(path) + if err != nil { + return err + } + if !notMount { + return nil + } + time.Sleep(interval) + elapsed = elapsed + interval + if elapsed >= timeout { + return errors.New("Timeout waiting for mount") + } + } +} + +func FindFuseMountProcess(path string) (*os.Process, error) { + processes, err := ps.Processes() + if err != nil { + return nil, err + } + for _, p := range processes { + cmdLine, err := getCmdLine(p.Pid()) + if err != nil { + continue + } + if strings.Contains(cmdLine, path) { + return os.FindProcess(p.Pid()) + } + } + return nil, nil +} + +func getCmdLine(pid int) (string, error) { + cmdLineFile := fmt.Sprintf("/proc/%v/cmdline", pid) + cmdLine, err := os.ReadFile(cmdLineFile) + if err != nil { + return "", err + } + return string(cmdLine), nil +} diff --git a/pkg/csidriver/server_controller.go b/pkg/csidriver/server_controller.go new file mode 100644 index 0000000..02b42e7 --- /dev/null +++ b/pkg/csidriver/server_controller.go @@ -0,0 +1,120 @@ +package csidriver + +import ( + "context" + + "github.com/container-storage-interface/spec/lib/go/csi" + "github.com/go-courier/logr" + "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type controllerServer struct { + DriverContext + + l logr.Logger +} + +func (c *controllerServer) ControllerGetCapabilities(ctx context.Context, request *csi.ControllerGetCapabilitiesRequest) (*csi.ControllerGetCapabilitiesResponse, error) { + return &csi.ControllerGetCapabilitiesResponse{ + Capabilities: c.ControllerServiceCapabilities, + }, nil +} + +func (c *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (resp *csi.CreateVolumeResponse, err error) { + l := c.l.WithValues("volume", req.GetName()) + + defer func() { + if err != nil { + l.Error(err) + return + } + }() + + name := req.GetName() + if len(name) == 0 { + return nil, status.Error(codes.InvalidArgument, "CreateVolume name must be provided") + } + + if err := isValidVolumeCapabilities(req.GetVolumeCapabilities()); err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + parameters := req.GetParameters() + if parameters == nil { + parameters = make(map[string]string) + } + + v, err := newVolume(name, req.GetCapacityRange().GetRequiredBytes(), req.GetSecrets(), parameters) + if err != nil { + return nil, err + } + + return &csi.CreateVolumeResponse{ + Volume: &csi.Volume{ + VolumeId: v.id, + CapacityBytes: v.size, + VolumeContext: req.GetParameters(), + }, + }, nil +} + +func (c *controllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) { + return &csi.DeleteVolumeResponse{}, nil +} + +func isValidVolumeCapabilities(volCaps []*csi.VolumeCapability) error { + if len(volCaps) == 0 { + return errors.New("volume capabilities missing in request") + } + + for _, c := range volCaps { + if c.GetBlock() != nil { + return errors.New("block volume capability not supported") + } + } + + return nil +} + +func (c *controllerServer) ControllerPublishVolume(ctx context.Context, request *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) ControllerUnpublishVolume(ctx context.Context, request *csi.ControllerUnpublishVolumeRequest) (*csi.ControllerUnpublishVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) ValidateVolumeCapabilities(ctx context.Context, request *csi.ValidateVolumeCapabilitiesRequest) (*csi.ValidateVolumeCapabilitiesResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) ControllerGetVolume(ctx context.Context, request *csi.ControllerGetVolumeRequest) (*csi.ControllerGetVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) GetCapacity(ctx context.Context, req *csi.GetCapacityRequest) (*csi.GetCapacityResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +// ListVolumes return all available volumes +func (c *controllerServer) ListVolumes(ctx context.Context, req *csi.ListVolumesRequest) (*csi.ListVolumesResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) ControllerExpandVolume(ctx context.Context, req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (c *controllerServer) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} diff --git a/pkg/csidriver/server_controller_test.go b/pkg/csidriver/server_controller_test.go new file mode 100644 index 0000000..9f89de4 --- /dev/null +++ b/pkg/csidriver/server_controller_test.go @@ -0,0 +1,79 @@ +package csidriver + +import ( + "context" + "reflect" + "testing" + + "github.com/container-storage-interface/spec/lib/go/csi" + + "github.com/go-courier/logr/slog" +) + +func TestController(t *testing.T) { + t.Run("CreateVolume", func(t *testing.T) { + cases := []struct { + name string + req *csi.CreateVolumeRequest + resp *csi.CreateVolumeResponse + expectErr bool + }{ + { + name: "valid defaults", + req: &csi.CreateVolumeRequest{ + Name: "volume-name", + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER, + }, + }, + }, + Secrets: map[string]string{ + backend: "file:///tmp/local", + }, + Parameters: map[string]string{}, + }, + resp: &csi.CreateVolumeResponse{ + Volume: &csi.Volume{ + VolumeId: "file##tmp/local#volume-name", + VolumeContext: map[string]string{}, + }, + }, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + // Setup + cs := newFakeControllerServer(t) + // Run + resp, err := cs.CreateVolume(context.Background(), c.req) + + if !c.expectErr && err != nil { + t.Errorf("c %q failed: %v", c.name, err) + } + if c.expectErr && err == nil { + t.Errorf("c %q failed; got success", c.name) + } + + if !reflect.DeepEqual(resp, c.resp) { + t.Errorf("c %q failed: got resp %+v, expected %+v", c.name, resp, c.resp) + } + + }) + } + }) +} + +func newFakeControllerServer(t *testing.T) *controllerServer { + dctx := newFakeDriverContext(t) + + return &controllerServer{ + DriverContext: dctx, + l: slog.Logger(slog.Default()), + } +} diff --git a/pkg/csidriver/server_identity.go b/pkg/csidriver/server_identity.go new file mode 100644 index 0000000..c660a60 --- /dev/null +++ b/pkg/csidriver/server_identity.go @@ -0,0 +1,40 @@ +package csidriver + +import ( + "context" + + "github.com/container-storage-interface/spec/lib/go/csi" + "github.com/go-courier/logr" + "github.com/golang/protobuf/ptypes/wrappers" +) + +type identityServer struct { + DriverContext + + l logr.Logger +} + +func (i *identityServer) GetPluginInfo(ctx context.Context, request *csi.GetPluginInfoRequest) (*csi.GetPluginInfoResponse, error) { + return &csi.GetPluginInfoResponse{ + Name: i.Name, + VendorVersion: i.VendorVersion, + }, nil +} + +func (i *identityServer) GetPluginCapabilities(ctx context.Context, request *csi.GetPluginCapabilitiesRequest) (*csi.GetPluginCapabilitiesResponse, error) { + return &csi.GetPluginCapabilitiesResponse{ + Capabilities: []*csi.PluginCapability{ + { + Type: &csi.PluginCapability_Service_{ + Service: &csi.PluginCapability_Service{ + Type: csi.PluginCapability_Service_CONTROLLER_SERVICE, + }, + }, + }, + }, + }, nil +} + +func (i *identityServer) Probe(ctx context.Context, request *csi.ProbeRequest) (*csi.ProbeResponse, error) { + return &csi.ProbeResponse{Ready: &wrappers.BoolValue{Value: true}}, nil +} diff --git a/pkg/csidriver/server_node.go b/pkg/csidriver/server_node.go new file mode 100644 index 0000000..ec06921 --- /dev/null +++ b/pkg/csidriver/server_node.go @@ -0,0 +1,121 @@ +package csidriver + +import ( + "context" + "github.com/container-storage-interface/spec/lib/go/csi" + "github.com/go-courier/logr" + "github.com/octohelm/unifs/pkg/csidriver/mounter" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type nodeServer struct { + DriverContext + + l logr.Logger +} + +func (n *nodeServer) NodeGetCapabilities(ctx context.Context, req *csi.NodeGetCapabilitiesRequest) (*csi.NodeGetCapabilitiesResponse, error) { + return &csi.NodeGetCapabilitiesResponse{ + Capabilities: []*csi.NodeServiceCapability{ + { + Type: &csi.NodeServiceCapability_Rpc{ + Rpc: &csi.NodeServiceCapability_RPC{ + Type: csi.NodeServiceCapability_RPC_UNKNOWN, + }, + }, + }, + }, + }, nil +} + +func (n *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (resp *csi.NodePublishVolumeResponse, err error) { + l := n.l.WithValues("NodePublishVolume", req.GetVolumeId()) + defer func() { + if err != nil { + l.Error(err) + } else { + l.Info("mounted") + } + }() + + volCap := req.GetVolumeCapability() + if volCap == nil { + return nil, status.Error(codes.InvalidArgument, "Volume capability missing in request") + } + volumeID := req.GetVolumeId() + if len(volumeID) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request") + } + targetPath := req.GetTargetPath() + if len(targetPath) == 0 { + return nil, status.Error(codes.InvalidArgument, "Target path missing in request") + } + + secrets := req.GetSecrets() + if secrets == nil { + secrets = make(map[string]string) + } + + b, ok := secrets[backend] + if !ok { + return nil, status.Error(codes.InvalidArgument, "Missing backend in secret") + } + + m, err := mounter.NewMounter(ctx, b) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + if err := m.Mount(targetPath); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &csi.NodePublishVolumeResponse{}, nil +} + +func (n *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublishVolumeRequest) (resp *csi.NodeUnpublishVolumeResponse, err error) { + l := n.l.WithValues("NodeUnpublishVolume", req.GetVolumeId()) + defer func() { + if err != nil { + l.Error(err) + } else { + l.Info("unmounted") + } + }() + + volumeID := req.GetVolumeId() + targetPath := req.GetTargetPath() + if len(volumeID) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request") + } + if len(targetPath) == 0 { + return nil, status.Error(codes.InvalidArgument, "Target path missing in request") + } + + if err := mounter.FuseUnmount(targetPath); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &csi.NodeUnpublishVolumeResponse{}, nil +} + +func (n *nodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (n *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstageVolumeRequest) (*csi.NodeUnstageVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (n *nodeServer) NodeExpandVolume(ctx context.Context, request *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) { + return nil, status.Error(codes.Unimplemented, "") +} + +func (n *nodeServer) NodeGetVolumeStats(ctx context.Context, request *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) { + return &csi.NodeGetVolumeStatsResponse{}, nil +} + +func (n *nodeServer) NodeGetInfo(ctx context.Context, request *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) { + return &csi.NodeGetInfoResponse{NodeId: n.NodeID}, nil +} diff --git a/pkg/csidriver/testdata/secrets.yaml b/pkg/csidriver/testdata/secrets.yaml new file mode 100644 index 0000000..8561c34 --- /dev/null +++ b/pkg/csidriver/testdata/secrets.yaml @@ -0,0 +1,5 @@ +CreateVolumeSecret: + backend: "file:///tmp/unifs/data" + +NodePublishVolumeSecret: + backend: "file:///tmp/unifs/data" \ No newline at end of file diff --git a/pkg/csidriver/util.go b/pkg/csidriver/util.go new file mode 100644 index 0000000..675f6a8 --- /dev/null +++ b/pkg/csidriver/util.go @@ -0,0 +1,32 @@ +package csidriver + +import ( + "fmt" + "strings" + + "github.com/container-storage-interface/spec/lib/go/csi" +) + +func NewControllerServiceCapability(cap csi.ControllerServiceCapability_RPC_Type) *csi.ControllerServiceCapability { + return &csi.ControllerServiceCapability{ + Type: &csi.ControllerServiceCapability_Rpc{ + Rpc: &csi.ControllerServiceCapability_RPC{ + Type: cap, + }, + }, + } +} + +func NewVolumeCapabilityAccessMode(mode csi.VolumeCapability_AccessMode_Mode) *csi.VolumeCapability_AccessMode { + return &csi.VolumeCapability_AccessMode{Mode: mode} +} + +func ParseEndpoint(ep string) (string, string, error) { + if strings.HasPrefix(strings.ToLower(ep), "unix://") || strings.HasPrefix(strings.ToLower(ep), "tcp://") { + s := strings.SplitN(ep, "://", 2) + if s[1] != "" { + return s[0], s[1], nil + } + } + return "", "", fmt.Errorf("Invalid endpoint: %v", ep) +} diff --git a/pkg/csidriver/util_test.go b/pkg/csidriver/util_test.go new file mode 100644 index 0000000..0022dd4 --- /dev/null +++ b/pkg/csidriver/util_test.go @@ -0,0 +1,25 @@ +package csidriver + +import ( + "testing" + + "github.com/container-storage-interface/spec/lib/go/csi" +) + +func newFakeDriverContext(t *testing.T) DriverContext { + dctx := DriverContext{ + Name: DefaultDriverName, + VendorVersion: "v0.1.0", + NodeID: "test-node", + } + + dctx.AddControllerServiceCapabilities( + csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME, + ) + + dctx.AddVolumeCapabilityAccessModes( + csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + ) + + return dctx +} diff --git a/pkg/filesystem/api/backend.go b/pkg/filesystem/api/backend.go new file mode 100644 index 0000000..92b016a --- /dev/null +++ b/pkg/filesystem/api/backend.go @@ -0,0 +1,46 @@ +package api + +import ( + "context" + + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/octohelm/unifs/pkg/filesystem/local" + "github.com/octohelm/unifs/pkg/filesystem/s3" + "github.com/octohelm/unifs/pkg/filesystem/webdav" + "github.com/octohelm/unifs/pkg/strfmt" + "github.com/pkg/errors" +) + +type FileSystemBackend struct { + Backend strfmt.Endpoint `flag:"backend"` + + fsi filesystem.FileSystem `flag:"-"` +} + +func (m *FileSystemBackend) FileSystem() filesystem.FileSystem { + return m.fsi +} + +func (m *FileSystemBackend) Init(ctx context.Context) error { + switch m.Backend.Scheme { + case "s3": + conf := &s3.Config{Endpoint: m.Backend} + c, err := conf.Client(ctx) + if err != nil { + return err + } + m.fsi = s3.NewS3FS(c, conf.Bucket(), conf.Prefix()) + case "webdav": + conf := &webdav.Config{Endpoint: m.Backend} + c, err := conf.Client(ctx) + if err != nil { + return err + } + m.fsi = webdav.NewWebdavFS(c) + case "file": + m.fsi = local.NewLocalFS(m.Backend.Path) + default: + return errors.Errorf("unsupported %s", m.Backend) + } + return nil +} diff --git a/pkg/filesystem/fs.go b/pkg/filesystem/fs.go index 6139d30..36b489d 100644 --- a/pkg/filesystem/fs.go +++ b/pkg/filesystem/fs.go @@ -1,8 +1,9 @@ package filesystem import ( - "golang.org/x/net/webdav" "os" + + "golang.org/x/net/webdav" ) type FileSystem = webdav.FileSystem diff --git a/pkg/filesystem/local/local_fs_test.go b/pkg/filesystem/local/local_fs_test.go index 70f127d..436432f 100644 --- a/pkg/filesystem/local/local_fs_test.go +++ b/pkg/filesystem/local/local_fs_test.go @@ -1,8 +1,9 @@ package local import ( - "github.com/octohelm/unifs/pkg/filesystem/testutil" "testing" + + "github.com/octohelm/unifs/pkg/filesystem/testutil" ) func TestLocalFS(t *testing.T) { diff --git a/pkg/filesystem/s3/config.go b/pkg/filesystem/s3/config.go index 5ee9c61..26808c1 100644 --- a/pkg/filesystem/s3/config.go +++ b/pkg/filesystem/s3/config.go @@ -3,10 +3,11 @@ package s3 import ( "context" "fmt" + "net/http" + "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/octohelm/unifs/pkg/strfmt" - "net/http" ) type Config struct { diff --git a/pkg/filesystem/s3/s3_fs_test.go b/pkg/filesystem/s3/s3_fs_test.go index 50b9dae..8f8164f 100644 --- a/pkg/filesystem/s3/s3_fs_test.go +++ b/pkg/filesystem/s3/s3_fs_test.go @@ -3,16 +3,17 @@ package s3 import ( "context" "fmt" - "github.com/johannesboyne/gofakes3" - "github.com/johannesboyne/gofakes3/backend/s3mem" - "github.com/octohelm/unifs/pkg/filesystem" - "github.com/octohelm/unifs/pkg/filesystem/testutil" - "github.com/octohelm/unifs/pkg/strfmt" "net/http/httptest" "os" "path/filepath" "testing" "time" + + "github.com/johannesboyne/gofakes3" + "github.com/johannesboyne/gofakes3/backend/s3mem" + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/octohelm/unifs/pkg/filesystem/testutil" + "github.com/octohelm/unifs/pkg/strfmt" ) func TestS3Fs(t *testing.T) { diff --git a/pkg/filesystem/testutil/bench.go b/pkg/filesystem/testutil/bench.go index e7ec3c0..14be412 100644 --- a/pkg/filesystem/testutil/bench.go +++ b/pkg/filesystem/testutil/bench.go @@ -4,13 +4,14 @@ import ( "bytes" "context" "fmt" - "github.com/pkg/errors" "io" "os" "path/filepath" "testing" "time" + "github.com/pkg/errors" + "github.com/octohelm/unifs/pkg/filesystem" ) diff --git a/pkg/filesystem/testutil/test_simple_fs.go b/pkg/filesystem/testutil/test_simple_fs.go index 111bac4..12ec342 100644 --- a/pkg/filesystem/testutil/test_simple_fs.go +++ b/pkg/filesystem/testutil/test_simple_fs.go @@ -3,12 +3,13 @@ package testutil import ( "context" "encoding/json" - "github.com/octohelm/unifs/pkg/filesystem" - "github.com/octohelm/x/slices" - testingx "github.com/octohelm/x/testing" "io" "os" "testing" + + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/octohelm/x/slices" + testingx "github.com/octohelm/x/testing" ) func TestSimpleFS(t *testing.T, fs filesystem.FileSystem) { diff --git a/pkg/filesystem/webdav/client/file.go b/pkg/filesystem/webdav/client/file.go index 198d8c9..a2e6453 100644 --- a/pkg/filesystem/webdav/client/file.go +++ b/pkg/filesystem/webdav/client/file.go @@ -1,10 +1,11 @@ package client import ( - "golang.org/x/sync/errgroup" "io" "os" "sync" + + "golang.org/x/sync/errgroup" ) type File interface { diff --git a/pkg/filesystem/webdav/config.go b/pkg/filesystem/webdav/config.go index c562c68..594451c 100644 --- a/pkg/filesystem/webdav/config.go +++ b/pkg/filesystem/webdav/config.go @@ -2,9 +2,10 @@ package webdav import ( "context" - "github.com/pkg/errors" "net/url" + "github.com/pkg/errors" + "github.com/octohelm/unifs/pkg/filesystem/webdav/client" "github.com/octohelm/unifs/pkg/strfmt" ) diff --git a/pkg/filesystem/webdav/file.go b/pkg/filesystem/webdav/file.go index 0514e19..0cc93c0 100644 --- a/pkg/filesystem/webdav/file.go +++ b/pkg/filesystem/webdav/file.go @@ -2,12 +2,13 @@ package webdav import ( "context" - "github.com/octohelm/unifs/pkg/filesystem" - "github.com/octohelm/unifs/pkg/filesystem/webdav/client" - "golang.org/x/sync/errgroup" "io" "os" "strings" + + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/octohelm/unifs/pkg/filesystem/webdav/client" + "golang.org/x/sync/errgroup" ) type file struct { diff --git a/pkg/filesystem/webdav/webdav_fs.go b/pkg/filesystem/webdav/webdav_fs.go index f33c400..c658e4f 100644 --- a/pkg/filesystem/webdav/webdav_fs.go +++ b/pkg/filesystem/webdav/webdav_fs.go @@ -3,12 +3,13 @@ package webdav import ( "context" "fmt" - "github.com/pkg/errors" "os" "path" "path/filepath" "strings" + "github.com/pkg/errors" + "golang.org/x/net/webdav" "github.com/octohelm/unifs/pkg/filesystem" diff --git a/pkg/filesystem/webdav/webdav_fs_test.go b/pkg/filesystem/webdav/webdav_fs_test.go index c4ad01f..7ad60f7 100644 --- a/pkg/filesystem/webdav/webdav_fs_test.go +++ b/pkg/filesystem/webdav/webdav_fs_test.go @@ -3,17 +3,19 @@ package webdav import ( "context" "fmt" - "github.com/octohelm/unifs/pkg/filesystem" - "github.com/octohelm/unifs/pkg/filesystem/testutil" - "github.com/octohelm/unifs/pkg/strfmt" "net/http" "os" "path/filepath" "testing" "time" - "golang.org/x/net/webdav" + "github.com/octohelm/unifs/pkg/filesystem" + "github.com/octohelm/unifs/pkg/filesystem/testutil" + "github.com/octohelm/unifs/pkg/strfmt" + "net/http/httptest" + + "golang.org/x/net/webdav" ) func TestWebdavFs(t *testing.T) { diff --git a/pkg/fuse/file.go b/pkg/fuse/file.go index 499b4d9..b1d113a 100644 --- a/pkg/fuse/file.go +++ b/pkg/fuse/file.go @@ -2,16 +2,16 @@ package fuse import ( "context" + "io" + "syscall" + "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" "github.com/octohelm/unifs/pkg/filesystem" - "io" - "syscall" ) type File interface { fs.FileHandle - fs.FileReader fs.FileWriter fs.FileReleaser diff --git a/pkg/fuse/node.go b/pkg/fuse/node.go index d1efe0c..4805723 100644 --- a/pkg/fuse/node.go +++ b/pkg/fuse/node.go @@ -2,10 +2,11 @@ package fuse import ( "context" - "github.com/davecgh/go-spew/spew" "os" "syscall" + "github.com/davecgh/go-spew/spew" + "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" diff --git a/pkg/fuse/root.go b/pkg/fuse/root.go index f98c1b3..7c3dbc3 100644 --- a/pkg/fuse/root.go +++ b/pkg/fuse/root.go @@ -1,13 +1,14 @@ package fuse import ( - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - "github.com/octohelm/unifs/pkg/filesystem" "os" "path/filepath" "syscall" "time" + + "github.com/hanwen/go-fuse/v2/fs" + "github.com/hanwen/go-fuse/v2/fuse" + "github.com/octohelm/unifs/pkg/filesystem" ) func FS(fsi filesystem.FileSystem) fs.InodeEmbedder { diff --git a/pkg/fuse/root_test.go b/pkg/fuse/root_test.go index 393e18b..e667152 100644 --- a/pkg/fuse/root_test.go +++ b/pkg/fuse/root_test.go @@ -1,13 +1,14 @@ package fuse import ( + "os" + "testing" + "time" + "github.com/hanwen/go-fuse/v2/fs" "github.com/octohelm/unifs/pkg/filesystem" "github.com/octohelm/unifs/pkg/filesystem/local" "github.com/octohelm/unifs/pkg/filesystem/testutil" - "os" - "testing" - "time" ) func TestFuse(t *testing.T) { diff --git a/tool/internal/cmd/tool/main.go b/tool/internal/cmd/tool/main.go new file mode 100644 index 0000000..2b13563 --- /dev/null +++ b/tool/internal/cmd/tool/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "context" + "os" + + "github.com/innoai-tech/infra/devpkg/gengo" + "github.com/innoai-tech/infra/pkg/cli" + "github.com/innoai-tech/infra/pkg/otel" + + _ "github.com/octohelm/gengo/devpkg/deepcopygen" + _ "github.com/octohelm/gengo/devpkg/runtimedocgen" +) + +var App = cli.NewApp("gengo", "dev") + +func init() { + cli.AddTo(App, &struct { + cli.C `name:"gen"` + otel.Otel + gengo.Gengo + }{}) +} + +func main() { + if err := cli.Execute(context.Background(), App, os.Args[1:]); err != nil { + panic(err) + } +} diff --git a/wagon.cue b/wagon.cue new file mode 100644 index 0000000..be0d78c --- /dev/null +++ b/wagon.cue @@ -0,0 +1,77 @@ +package main + +import ( + "strings" + + "wagon.octohelm.tech/core" + "github.com/innoai-tech/runtime/cuepkg/debian" + "github.com/innoai-tech/runtime/cuepkg/golang" + + "github.com/octohelm/unifs/cuepkg/csidriver" + "github.com/octohelm/unifs/cuedevpkg/tool" +) + +pkg: version: core.#Version & { +} + +actions: go: golang.#Project & { + source: { + path: "." + include: [ + "cmd/", + "internal/", + "pkg/", + "go.mod", + "go.sum", + ] + } + + version: pkg.version.output + + goos: ["linux"] + goarch: ["amd64", "arm64"] + main: "./cmd/unifs" + ldflags: [ + "-s -w", + "-X \(go.module)/internal/version.version=\(go.version)", + ] + + build: pre: [ + "go mod download", + ] + + ship: { + name: "\(strings.Replace(go.module, "github.com/", "ghcr.io/", -1))" + tag: pkg.version.output + from: "docker.io/library/debian:bookworm-slim" + + steps: [ + debian.#InstallPackage & { + packages: "fuse3": _ + }, + ] + config: cmd: ["csidriver"] + } +} + +actions: export: tool.#Export & { + name: "unifs" + namespace: "storage-system--unifs" + kubepkg: csidriver.#Provider & { + #values: version: pkg.version.output + } +} + +setting: { + _env: core.#ClientEnv & { + GH_USERNAME: string | *"" + GH_PASSWORD: core.#Secret + } + + setup: core.#Setting & { + registry: "ghcr.io": auth: { + username: _env.GH_USERNAME + secret: _env.GH_PASSWORD + } + } +}