diff --git a/.conform.yaml b/.conform.yaml new file mode 100644 index 0000000..45a7d83 --- /dev/null +++ b/.conform.yaml @@ -0,0 +1,48 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2024-09-30T14:59:39Z by kres 8be5fa7. + +policies: + - type: commit + spec: + dco: true + gpg: + required: true + identity: + gitHubOrganization: siderolabs + spellcheck: + locale: US + maximumOfOneCommit: true + header: + length: 89 + imperative: true + case: lower + invalidLastCharacters: . + body: + required: true + conventional: + types: + - chore + - docs + - perf + - refactor + - style + - test + - release + scopes: + - .* + - type: license + spec: + root: . + skipPaths: + - .git/ + - testdata/ + includeSuffixes: + - .go + excludeSuffixes: + - .pb.go + - .pb.gw.go + header: | + // This Source Code Form is subject to the terms of the Mozilla Public + // License, v. 2.0. If a copy of the MPL was not distributed with this + // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 319d34d..dcd98ee 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-10-02T19:28:55Z by kres 34e72ac. +# Generated on 2024-10-18T16:18:03Z by kres 34e72ac. name: default concurrency: @@ -67,6 +67,12 @@ jobs: driver: remote endpoint: tcp://buildkit-amd64.ci.svc.cluster.local:1234 timeout-minutes: 10 + - name: Mask secrets + run: | + echo "$(sops -d .secrets.yaml | yq -e '.secrets | to_entries[] | "::add-mask::" + .value')" + - name: Set secrets for job + run: | + sops -d .secrets.yaml | yq -e '.secrets | to_entries[] | .key + "=" + .value' >> "$GITHUB_ENV" - name: base run: | make base @@ -104,6 +110,29 @@ jobs: PUSH: "true" run: | make image-omni-infra-provider-kubevirt IMAGE_TAG=latest + - name: run-integration-test + run: | + sudo -E make run-integration-test + - name: Generate executable list + run: | + find _out -type f -executable > _out/executable-artifacts + - name: save-artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts + path: |- + _out + !_out/omni/ + retention-days: "5" + - name: save-talos-logs-artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: talos-logs + path: |- + ~/.talos/clusters/**/*.log + !~/.talos/clusters/**/swtpm.log + retention-days: "5" - name: Generate Checksums if: startsWith(github.ref, 'refs/tags/') run: | diff --git a/.kres.yaml b/.kres.yaml new file mode 100644 index 0000000..80173b7 --- /dev/null +++ b/.kres.yaml @@ -0,0 +1,135 @@ +--- +kind: common.Build +spec: + ignoredPaths: + - "hack/compose/docker-compose.override.yml" +--- +kind: service.CodeCov +spec: + # the tool should be tested by Omni integration tests + enabled: false +--- +kind: golang.Generate +spec: + baseSpecPath: /api + vtProtobufEnabled: true + specs: + - source: api/specs/specs.proto + subdirectory: specs +--- +kind: auto.CustomSteps +spec: + steps: + - name: docker-compose-up + toplevel: true + - name: docker-compose-down + toplevel: true + - name: run-integration-test + toplevel: true +--- +kind: custom.Step +name: docker-compose-up +spec: + makefile: + enabled: true + phony: true + script: + - >- + ARTIFACTS="$(ARTIFACTS)" + SHA="$(SHA)" + TAG="$(TAG)" + USERNAME="$(USERNAME)" + REGISTRY="$(REGISTRY)" + PROTOBUF_TS_VERSION="$(PROTOBUF_TS_VERSION)" + NODE_BUILD_ARGS="$(NODE_BUILD_ARGS)" + TOOLCHAIN="$(TOOLCHAIN)" + CGO_ENABLED="$(CGO_ENABLED)" + GO_BUILDFLAGS="$(GO_BUILDFLAGS)" + GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" + GOFUMPT_VERSION="$(GOFUMPT_VERSION)" + GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" + PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" + GRPC_GO_VERSION="$(GRPC_GO_VERSION)" + GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" + VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" + DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" + TESTPKGS="$(TESTPKGS)" + COMPOSE_DOCKER_CLI_BUILD=1 + DOCKER_BUILDKIT=1 + GO_LDFLAGS="$(GO_LDFLAGS)" + docker compose -p talemu --file ./hack/compose/docker-compose.yml --file ./hack/compose/docker-compose.override.yml up --build +--- +kind: custom.Step +name: docker-compose-down +spec: + makefile: + enabled: true + phony: true + variables: + - name: REMOVE_VOLUMES + defaultValue: false + script: + - >- + ARTIFACTS="$(ARTIFACTS)" + SHA="$(SHA)" + TAG="$(TAG)" + USERNAME="$(USERNAME)" + REGISTRY="$(REGISTRY)" + PROTOBUF_TS_VERSION="$(PROTOBUF_TS_VERSION)" + NODE_BUILD_ARGS="$(NODE_BUILD_ARGS)" + TOOLCHAIN="$(TOOLCHAIN)" + CGO_ENABLED="$(CGO_ENABLED)" + GO_BUILDFLAGS="$(GO_BUILDFLAGS)" + GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" + GOFUMPT_VERSION="$(GOFUMPT_VERSION)" + GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" + PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" + GRPC_GO_VERSION="$(GRPC_GO_VERSION)" + GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" + VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" + DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" + TESTPKGS="$(TESTPKGS)" + COMPOSE_DOCKER_CLI_BUILD=1 + DOCKER_BUILDKIT=1 + GO_LDFLAGS="$(GO_LDFLAGS)" + docker compose -p talemu --file ./hack/compose/docker-compose.yml --file ./hack/compose/docker-compose.override.yml down --rmi local --remove-orphans --volumes=$(REMOVE_VOLUMES) +--- +kind: custom.Step +name: run-integration-test +spec: + sudoInCI: true + makefile: + enabled: true + depends: + - omni-infra-provider-kubevirt + script: + - >- + @hack/test/integration.sh + ghaction: + enabled: true + sops: true + artifacts: + enabled: true + extraPaths: + - "!_out/omni/" + additional: + - name: talos-logs + always: true + continueOnError: true + paths: + - "~/.talos/clusters/**/*.log" + - "!~/.talos/clusters/**/swtpm.log" +--- +kind: common.SOPS +spec: + enabled: true + config: |- + creation_rules: + - age: age1xrpa9ujxxcj2u2gzfrzv8mxak4rts94a6y60ypurv6rs5cpr4e4sg95f0k + # order: Andrey, Noel, Artem, Utku, Dmitriy + pgp: >- + 15D5721F5F5BAF121495363EFE042E3D4085A811, + CC51116A94490FA6FB3C18EB2401FCAE863A06CA, + 4919F560F0D35F80CF382D76E084A2DF1143C14D, + 966BC282A680D8BB3E8363E865933E76F0549B0D, + AA5213AF261C1977AF38B03A94B473337258BFD5 diff --git a/.license-header.go.txt b/.license-header.go.txt new file mode 100644 index 0000000..66e0819 --- /dev/null +++ b/.license-header.go.txt @@ -0,0 +1,3 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/.secrets.yaml b/.secrets.yaml new file mode 100644 index 0000000..04141f3 --- /dev/null +++ b/.secrets.yaml @@ -0,0 +1,84 @@ +secrets: + AUTH0_TEST_USERNAME: ENC[AES256_GCM,data:lPddHbDVfWxaEW7ujLDnWdhIBMFj2hcp,iv:oG3Ebn8ym7g/Z7L3A3BTHRHIk+zzblZKvzMKYMPSfWI=,tag:wV7xJWbnLrj/UWj0fGGQCw==,type:str] + AUTH0_TEST_PASSWORD: ENC[AES256_GCM,data:3tgQjqv5ktdnnGUQw5Lpuw==,iv:F8zYxqk5P0tV1Pvt6QBlho8H0wuX+K91pgwLzF+4kC8=,tag:HJ4s14d/u2KyP780wFDk/w==,type:str] + AUTH0_CLIENT_ID: ENC[AES256_GCM,data:HevA8uFKCOPF8W/FRjSo/pyUFN66eXwvAxaqT5LdnT0=,iv:qpWNjsRSZ28lWQJGfMoGQvLY8KRKWv1dhR07vCgIvIU=,tag:x5BS26iacdBMv2ZkdCdr3A==,type:str] + AUTH0_DOMAIN: ENC[AES256_GCM,data:2vv9ay+hC1kN46MG8E0v1Z3G7Dm0hMmLx1/AWg==,iv:9thZflFQ1yhf0jH3u6Om7RV7Y/qYzrTf82hoYrDvyG0=,tag:BUNuHJobt/NoR5FFQBIbIQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1xrpa9ujxxcj2u2gzfrzv8mxak4rts94a6y60ypurv6rs5cpr4e4sg95f0k + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrUExvc1oyUzdVNmgrbHh3 + cDllQ2VGSzZLQWV5MkN0VU1qTjVqblFvekJZCkdyREg2RUhVSXQwM1lpcjBkb0dG + b0krdTI1MVQxcE4zSElsd0liS0xrYncKLS0tIG1nSmhVa2Z1YkhjdHpnQmg5b1lL + NXI3VkxLU0htQUZ0Ry8rYUpLTnNXYlkKzfLUus7SkKBEj+oG3f7NBe+6UVidpxRd + OvOSqsACIUJJnRdfs8/X5Jbvruz38Zt3dYR436NFo2IHtYUdHIHO3Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-05-06T09:52:57Z" + mac: ENC[AES256_GCM,data:4qmhG/liKJdnEBxvvnxnpb9xJpS8GGjCAHGUVM4dGtYY5+TkfgnSQyvVdg88Ag16nMDTBEeRJO6VfOYD/Wx/PfIYnajhxRm3ZYuPPSJ5t0LGqRryUtR9vJTtHuTew5gjX8FCTvjiGJzqcfTiq11HhN3Xyu7VNwwan50QUvz5oKY=,iv:Rc0/1kH74ahBkNygwFrOZymWMnPj3VCQZ7wBi1d7Rzc=,tag:Cgdjhlc24S2gklSKYe5mPw==,type:str] + pgp: + - created_at: "2024-04-18T18:21:00Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4D/dYBJRlWfQISAQdAVAV7d4BdulmFD+opnoDgxoIcDlIGn2n7c2aWbeF1qjYw + eHfSb/A/1Anwi+uA7fXAqAayhlfTFTr9xdKr9zp+rDQt09/QN9EKG2F9gBq0LPCl + 0lwBAxelOP0EUjXZtpsVk8FVZcBeuYt+U+DrAVr8yT3TUiyFvavzpxxCqUYFBjvy + z5DUSCs+YUDLpQ/Gde0qBW8LU6HO2LAGkIvfO/HAd35jVHT5EvXivMlaRb+qBg== + =hdU9 + -----END PGP MESSAGE----- + fp: 15D5721F5F5BAF121495363EFE042E3D4085A811 + - created_at: "2024-04-18T18:21:00Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4D+EORkHurkvgSAQdAOxZd1WYD0pC25Y7bBmPhlz9+udxy+RiwaxL2RXs2/xYw + cIvqsTY4wokWKD3s1nFmqHDXU3GQ7+V+pCS1PXTs7YH3uwXLBaT86AUgp+JoLJmN + 0lwBuFrV4rSBQ5NvY1lGmOz6zaZlf3oBvVX510bvLPG6RfUqxE5WkMl+XgYtoKNa + eK2uknJ5UhMKYJpYwi0Jcj6Ip3s0Bzt2ZR4SMYvw7QzXPvJ1W3GKboOjJAxqoQ== + =YydP + -----END PGP MESSAGE----- + fp: CC51116A94490FA6FB3C18EB2401FCAE863A06CA + - created_at: "2024-04-18T18:21:00Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4DCsA/BhMt3V4SAQdAtLfcBQyS/chcBtMAz6cJ/q/jZihioun7AZssYBzGdFIw + jwXCKTbTFAG7ebentk4dDLYWxRRwY/lHsWyAS1kDSSfQVZNfK+ZoTrGIG1J6MYDD + 0lwBazJw7Xh+MBXt9nz/Pdor4Jlnerl1PvO3BsDvql5ESbWZS/OOSFGTvuq9ZUG0 + RRlvN38NSNz+R1D79U+iwsJDJ7s8qUPCNckAoU3RWkqa7Sv1rpnwLPBqZ4t6bA== + =JQty + -----END PGP MESSAGE----- + fp: 4919F560F0D35F80CF382D76E084A2DF1143C14D + - created_at: "2024-04-18T18:21:00Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQEMAxQwM84t19oOAQf/TQnaKyseOPFTpIMXoZAHsJ71jVGTdevAhOK9Vrq4ULwk + Mb/QIyjLssrxBKU2AeXPXHM3SfiboqRsfoUKLuTmBI+BZyq6xXSA5HPElS+VcodE + sLTce4en+YeWvcJ5vioNCqj0P6GTEdZfB5bXRzhJArQMyyEGvAaQG/5SKI8lJ4gW + q0jXhwWy3qZRGj+X35y+vjlorwIEjPDrrh3lddnt+I1uVO2SKO4irbO3OiLAHRUM + bTyeIdqsVJN9tWdlotPIA5+IQK+Bd+G6Tu4rGnKxsEo2wTfomcR99HTBLYIVkVSm + iswaGDffJ3DAIWEBUDdOZD1zOOAb0xESkkEfIbfcxdJcAesPBVc/jkL9cd17oHCU + sSEDeQnkFcwwfa3Lvo91CqrXx/I9Np/D6Ir/BsdYl4IUrcOtpYjVRQh3V9MfXpuY + RST6NbjIziAMOPbJaxXKOZbT+inksnFvblo39HE= + =5g11 + -----END PGP MESSAGE----- + fp: 966BC282A680D8BB3E8363E865933E76F0549B0D + - created_at: "2024-04-18T18:21:00Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4DzfZC0UNQ1VgSAQdABhWHHlBVw7gq430dMuRHIzJ4u6f5oVh8jXBbMGG8tXow + lBUy2Qo9sGgN/2Nu9/W+efxs31oceerrw4DMSalC/KWvq3teVWc8TYeHYNAd/4ci + 0lwB/UsGhZio7njWdmt7chOHJgM76JUEb4eaEZCVhQCCBDTIaFffMF2b0gpgyG9p + orZob5tXAl1RsYS9ZDAlGWpuicfZ8CUxQvdSKzwBzBrBJhs+CvNVk/NFWXNS3Q== + =N/JL + -----END PGP MESSAGE----- + fp: AA5213AF261C1977AF38B03A94B473337258BFD5 + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..54d08e4 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,13 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2024-04-18T18:20:58Z by kres 92eef68-dirty. + +creation_rules: + - age: age1xrpa9ujxxcj2u2gzfrzv8mxak4rts94a6y60ypurv6rs5cpr4e4sg95f0k + # order: Andrey, Noel, Artem, Utku, Dmitriy + pgp: >- + 15D5721F5F5BAF121495363EFE042E3D4085A811, + CC51116A94490FA6FB3C18EB2401FCAE863A06CA, + 4919F560F0D35F80CF382D76E084A2DF1143C14D, + 966BC282A680D8BB3E8363E865933E76F0549B0D, + AA5213AF261C1977AF38B03A94B473337258BFD5 \ No newline at end of file diff --git a/Makefile b/Makefile index 40f74bb..c0eb0b6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-10-02T19:28:55Z by kres 34e72ac. +# Generated on 2024-10-03T14:26:39Z by kres 34e72ac. # common variables @@ -135,7 +135,7 @@ else GO_LDFLAGS += -s endif -all: unit-tests omni-infra-provider-kubevirt image-omni-infra-provider-kubevirt docker-compose-up docker-compose-down lint +all: unit-tests omni-infra-provider-kubevirt image-omni-infra-provider-kubevirt docker-compose-up docker-compose-down run-integration-test lint $(ARTIFACTS): ## Creates artifacts directory. @mkdir -p $(ARTIFACTS) @@ -211,6 +211,9 @@ docker-compose-up: docker-compose-down: ARTIFACTS="$(ARTIFACTS)" SHA="$(SHA)" TAG="$(TAG)" USERNAME="$(USERNAME)" REGISTRY="$(REGISTRY)" PROTOBUF_TS_VERSION="$(PROTOBUF_TS_VERSION)" NODE_BUILD_ARGS="$(NODE_BUILD_ARGS)" TOOLCHAIN="$(TOOLCHAIN)" CGO_ENABLED="$(CGO_ENABLED)" GO_BUILDFLAGS="$(GO_BUILDFLAGS)" GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" GOFUMPT_VERSION="$(GOFUMPT_VERSION)" GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" GRPC_GO_VERSION="$(GRPC_GO_VERSION)" GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" TESTPKGS="$(TESTPKGS)" COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 GO_LDFLAGS="$(GO_LDFLAGS)" docker compose -p talemu --file ./hack/compose/docker-compose.yml --file ./hack/compose/docker-compose.override.yml down --rmi local --remove-orphans --volumes=$(REMOVE_VOLUMES) +run-integration-test: omni-infra-provider-kubevirt + @hack/test/integration.sh + .PHONY: rekres rekres: @docker pull $(KRES_IMAGE) diff --git a/cmd/omni-infra-provider-kubevirt/data/schema.json b/cmd/omni-infra-provider-kubevirt/data/schema.json index 82e9c18..b566b7e 100644 --- a/cmd/omni-infra-provider-kubevirt/data/schema.json +++ b/cmd/omni-infra-provider-kubevirt/data/schema.json @@ -21,6 +21,7 @@ "required": [ "cores", "memory", - "architecture" + "architecture", + "disk_size" ] } diff --git a/cmd/omni-infra-provider-kubevirt/main.go b/cmd/omni-infra-provider-kubevirt/main.go index 581b2f3..be2fb66 100644 --- a/cmd/omni-infra-provider-kubevirt/main.go +++ b/cmd/omni-infra-provider-kubevirt/main.go @@ -12,6 +12,7 @@ import ( "fmt" "os" "os/signal" + "slices" "syscall" "github.com/siderolabs/omni/client/pkg/client" @@ -19,6 +20,7 @@ import ( "github.com/spf13/cobra" "go.uber.org/zap" "go.uber.org/zap/zapcore" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/clientcmd" kvv1 "kubevirt.io/api/core/v1" @@ -75,7 +77,20 @@ var rootCmd = &cobra.Command{ return err } - provisioner := provider.NewProvisioner(k8sClient, cfg.namespace) + if cfg.omniAPIEndpoint == "" { + return fmt.Errorf("omni-api-endpoint flag is not set") + } + + volumeOpts := []v1.PersistentVolumeMode{ + v1.PersistentVolumeBlock, + v1.PersistentVolumeFilesystem, + } + + if cfg.dataVolumeMode != "" && slices.Index(volumeOpts, v1.PersistentVolumeMode(cfg.dataVolumeMode)) == -1 { + return fmt.Errorf("data-volume-mode flags should be one of %s", volumeOpts) + } + + provisioner := provider.NewProvisioner(k8sClient, cfg.namespace, cfg.dataVolumeMode) ip, err := infra.NewProvider(meta.ProviderID, provisioner, infra.ProviderConfig{ Name: cfg.providerName, @@ -89,9 +104,16 @@ var rootCmd = &cobra.Command{ logger.Info("starting infra provider") - return ip.Run(cmd.Context(), logger, infra.WithOmniEndpoint(cfg.omniAPIEndpoint), infra.WithClientOptions( - client.WithServiceAccount(cfg.serviceAccountKey), + clientOptions := []client.Option{ client.WithInsecureSkipTLSVerify(cfg.insecureSkipVerify), + } + + if cfg.serviceAccountKey != "" { + clientOptions = append(clientOptions, client.WithServiceAccount(cfg.serviceAccountKey)) + } + + return ip.Run(cmd.Context(), logger, infra.WithOmniEndpoint(cfg.omniAPIEndpoint), infra.WithClientOptions( + clientOptions..., )) }, } @@ -103,6 +125,7 @@ var cfg struct { providerDescription string kubeconfigFile string namespace string + dataVolumeMode string insecureSkipVerify bool } @@ -123,10 +146,11 @@ func init() { rootCmd.Flags().StringVar(&cfg.omniAPIEndpoint, "omni-api-endpoint", os.Getenv("OMNI_ENDPOINT"), "the endpoint of the Omni API, if not set, defaults to OMNI_ENDPOINT env var.") rootCmd.Flags().StringVar(&meta.ProviderID, "id", meta.ProviderID, "the id of the infra provider, it is used to match the resources with the infra provider label.") - rootCmd.Flags().StringVar(&cfg.serviceAccountKey, "key", os.Getenv("OMNI_SERVICE_ACCOUNT_KEY"), "Omni service account key, if not set, defaults to OMNI_SERVICE_ACCOUNT_KEY.") + rootCmd.Flags().StringVar(&cfg.serviceAccountKey, "omni-service-account-key", os.Getenv("OMNI_SERVICE_ACCOUNT_KEY"), "Omni service account key, if not set, defaults to OMNI_SERVICE_ACCOUNT_KEY.") rootCmd.Flags().StringVar(&cfg.providerName, "provider-name", "KubeVirt", "provider name as it appears in Omni") rootCmd.Flags().StringVar(&cfg.providerDescription, "provider-description", "KubeVirt infrastructure provider", "Provider description as it appears in Omni") rootCmd.Flags().StringVar(&cfg.kubeconfigFile, "kubeconfig-file", "~/.kube/config", "Kubeconfig file to use to connect to the cluster where KubeVirt is running") rootCmd.Flags().StringVar(&cfg.namespace, "namespace", "default", "Kubernetes namespace to use for the resources created by the provider") + rootCmd.Flags().StringVar(&cfg.dataVolumeMode, "data-volume-mode", "", "DataVolume PVC type to use (Block|Filesystem)") rootCmd.Flags().BoolVar(&cfg.insecureSkipVerify, "insecure-skip-verify", false, "ignores untrusted certs on Omni side") } diff --git a/go.mod b/go.mod index 8a32f97..4f37dac 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,9 @@ replace gopkg.in/yaml.v3 => github.com/unix4ever/yaml v0.0.0-20220527175918-f17b require ( github.com/cosi-project/runtime v0.6.4 github.com/google/uuid v1.6.0 - github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 + github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 github.com/siderolabs/go-pointer v1.0.0 - github.com/siderolabs/omni/client v0.0.0-20241002200003-8334c59482d3 + github.com/siderolabs/omni/client v0.0.0-20241018142957-c754cdc0d76b github.com/spf13/cobra v1.8.1 go.uber.org/zap v1.27.0 google.golang.org/protobuf v1.34.2 @@ -80,6 +80,7 @@ require ( github.com/siderolabs/go-blockdevice/v2 v2.0.2 // indirect github.com/siderolabs/image-factory v0.5.0 // indirect github.com/siderolabs/net v0.4.0 // indirect + github.com/siderolabs/proto-codec v0.1.1 // indirect github.com/siderolabs/protoenc v0.2.1 // indirect github.com/siderolabs/talos/pkg/machinery v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -91,13 +92,13 @@ require ( golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.66.2 // indirect + google.golang.org/grpc v1.67.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 092c914..8dbfae5 100644 --- a/go.sum +++ b/go.sum @@ -226,8 +226,8 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmd github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 h1:xzZOeCMQLA/W198ZkdVdt4EKFKJtS26B773zNU377ZY= +github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -257,8 +257,10 @@ github.com/siderolabs/image-factory v0.5.0 h1:v1FXZLCcV6xu+6QpgvhDEICxVF7o2VxMjf github.com/siderolabs/image-factory v0.5.0/go.mod h1:npJwHOBsI+h+gKdezCyrs7ZHDmkgRnrAK2Cjk1nzv8A= github.com/siderolabs/net v0.4.0 h1:1bOgVay/ijPkJz4qct98nHsiB/ysLQU0KLoBC4qLm7I= github.com/siderolabs/net v0.4.0/go.mod h1:/ibG+Hm9HU27agp5r9Q3eZicEfjquzNzQNux5uEk0kM= -github.com/siderolabs/omni/client v0.0.0-20241002200003-8334c59482d3 h1:/lYriXeZPY7rFzNH8NJ9/GCzYfP8beFUNhDlSTZ9++w= -github.com/siderolabs/omni/client v0.0.0-20241002200003-8334c59482d3/go.mod h1:W/hf1Febrmn/P7ROrSTRzfjOEkTMkD4clMrgSWisqTw= +github.com/siderolabs/omni/client v0.0.0-20241018142957-c754cdc0d76b h1:d4RdUR3rX7PPCVxqurC6EhJG2UOX1JyU8iO4sPwMBHc= +github.com/siderolabs/omni/client v0.0.0-20241018142957-c754cdc0d76b/go.mod h1:Fl1XD50BMgvCZKYKDbLIyaj1GG7c2yDgmXVMMw+vI2o= +github.com/siderolabs/proto-codec v0.1.1 h1:4jiUwW/vaXTZ+YNgZDs37B4aj/1mzV/erIkzUUCRY9g= +github.com/siderolabs/proto-codec v0.1.1/go.mod h1:rIvmhKJG8+JwSCGPX+cQljpOMDmuHhLKPkt6KaFwEaU= github.com/siderolabs/protoenc v0.2.1 h1:BqxEmeWQeMpNP3R6WrPqDatX8sM/r4t97OP8mFmg6GA= github.com/siderolabs/protoenc v0.2.1/go.mod h1:StTHxjet1g11GpNAWiATgc8K0HMKiFSEVVFOa/H0otc= github.com/siderolabs/talos/pkg/machinery v1.8.0 h1:azhBj+Nm9oTgaFgcNaHU8TPS9Oi5OdV1ELNgFAVder8= @@ -390,8 +392,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.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.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -446,8 +448,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go. google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= -google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/hack/certs/key.private b/hack/certs/key.private new file mode 100644 index 0000000..1fefbc9 --- /dev/null +++ b/hack/certs/key.private @@ -0,0 +1,106 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +hp/KSDr6GKR6H5ggj1v1tBWE95A= +=pdI2 +-----END PGP PRIVATE KEY BLOCK----- diff --git a/hack/certs/key.public b/hack/certs/key.public new file mode 100644 index 0000000..dd080ac --- /dev/null +++ b/hack/certs/key.public @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +2lEebIgAF9oRsC9BU9vSsg== +=f37X +-----END PGP PUBLIC KEY BLOCK----- diff --git a/hack/certs/localhost-key.pem b/hack/certs/localhost-key.pem new file mode 100644 index 0000000..a265878 --- /dev/null +++ b/hack/certs/localhost-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC4ilhEy8jLTsSm +YW+hTenFrh8qvNYYYpo9PkQ/pscd4wyPi90BxKPoAIAWRsT5HE3cmJhD8cDtCly7 +9N4JOSH8rLoU1OSUQTtL4U84kQ9+rNrOexR9O+URBSLyu338KRdlpvUs25z7an/S +Hwf6CqMGx+pgqIp+6ucwjYXvTgWw56POimVf/u1Xs5xsy/saHhQUzQwlpVBGHOtB +wFVigQzUpCsefLzUGpVZc5J2FVRoRp+k76imHObZXQqMdAIW2DzIRJ6WUB4MHnkK +sO25EdLHlRdGS9r0Bf+CXqPJ6ePYLKXDRA3/KSLlnenShHp0NR2DQMhiG4oDi4Sb +1TQYFlXpAgMBAAECggEBAKPnPD7eQJlSfJbKM7uw19EbtdLfpchCy3tZsoRWPMPu +xVk5gDHx1SJaT2l5sbkPypgDcDnontHqQjMuaYcHl4g0YZHfBKYoyeG7XAGB1aFN +JYn/B1OzvuA/D6tHm747QOyoPVp6NBOZo62cohkTGXkMVr9C8r+HI4+cIzlIswVL +NW4+vCMZ9WQ5z98NpJX3isK6BDemWyfi702oTLG7XIwzn7GQWL0jQX+zOmYkmo+K +InGSnrHl7pILs2InDIA/3AMI4K/w/mqu11h2+VKKmHUyOKi47lBUdtpZp9KLMA6W +kJ3mwQX2RU8mAWpuGE+Bo23WApdcwRV+UYGtU+mE3YECgYEA0Q8OhvtF2/MWyLWp +Q0hNJ4PK7+Htnx/xzxzEOadLwTio19cO51J83zlAqQ6dCE4HUsQmZVlMl7kq6zfL +z7kn1x9H87YcBYnfxUFOQUKco5N/GibhJi85t0tjuReDU3GxZS7MsA7vsOn/uIdC +W91FS01QxgAl1bEnCK2gbNWNYlsCgYEA4fnxDoRuprj83Jz4MxbLSpqOrQE+S1V2 +3XGVHSo2x9i1d7T+CzVaug2r1Jqz02cRn15fE24B2KkoYz7eCNEJ7A0HfOLwwq2s +m9RMyAFY/RoktIZb09SwYneleuX3pvIQJ7hkX0oxg7EeVK/1H93lCrgBz4SVeUXe +nNzmkxY8FAsCgYEAt5MNIqJKudU/0IcUVqyKc4RbE0HEstION9v+wtGQx97FBKMn +xyC73hgcG1dltQEvlRIA1UYQ57oFYf7gzUq9HT2upObovERRZpjt6ohfm5PNLF2v +nyQg/j8JFmL7Qq63Iy5xNrgm6abQkmzTbG9khbcikntWvcqNiCVOlcMAH7kCgYEA +pXg02JGGyNSKbC0Q3bAiOkXEldBkQhuZx3tlWg7QQDRiZP6GS8TM45IhMbP6W6GM +WOtsqTiTZ4guR8YAJeqT3mKICh3PeG5eB1lEw+ugsu0S1ZHQ6eNDKUc9SCne10NH +Kx6teM1GRo1KjW6vCp+cGOY2hTMrlLrh0HE88ZWFdpMCgYEAigbuLOfVlSbIQ8vg +UJHf6JM5Lrc6oG6LW6fRUabnJibQ/TboNeV7PYd594swBrSwzJ/yRch8d6UIRVSB +cftPlut2YvHcoMlOhqS0oOOFNJx1JFNj8s0SMfQBd7MXG8r+OSL4pWPL7EhVmsS2 +WMXSd3FqGMORF7NKqrtXGb203mk= +-----END PRIVATE KEY----- diff --git a/hack/certs/localhost.pem b/hack/certs/localhost.pem new file mode 100644 index 0000000..e65a5f6 --- /dev/null +++ b/hack/certs/localhost.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEVzCCAr+gAwIBAgIRAIfOe7RuXJAXhuacBA29W9EwDQYJKoZIhvcNAQELBQAw +WTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMRcwFQYDVQQLDA51dGt1 +QHUtaG9tZS1wYzEeMBwGA1UEAwwVbWtjZXJ0IHV0a3VAdS1ob21lLXBjMB4XDTI0 +MDgxNjA4MTkwM1oXDTI2MTExNjA5MTkwM1owVjEnMCUGA1UEChMebWtjZXJ0IGRl +dmVsb3BtZW50IGNlcnRpZmljYXRlMSswKQYDVQQLDCJ1dGt1QHUtd29yay1zaWRl +cm8gKFV0a3Ugw5Z6ZGVtaXIpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuIpYRMvIy07EpmFvoU3pxa4fKrzWGGKaPT5EP6bHHeMMj4vdAcSj6ACAFkbE ++RxN3JiYQ/HA7Qpcu/TeCTkh/Ky6FNTklEE7S+FPOJEPfqzaznsUfTvlEQUi8rt9 +/CkXZab1LNuc+2p/0h8H+gqjBsfqYKiKfurnMI2F704FsOejzoplX/7tV7OcbMv7 +Gh4UFM0MJaVQRhzrQcBVYoEM1KQrHny81BqVWXOSdhVUaEafpO+ophzm2V0KjHQC +Ftg8yESellAeDB55CrDtuRHSx5UXRkva9AX/gl6jyenj2Cylw0QN/yki5Z3p0oR6 +dDUdg0DIYhuKA4uEm9U0GBZV6QIDAQABo4GcMIGZMA4GA1UdDwEB/wQEAwIFoDAT +BgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBSUwQKJ6xTCiIbTU/iD3Wgy +OE1oFjBRBgNVHREESjBIgglsb2NhbGhvc3SCCyoubG9jYWxob3N0ghVteS1pbnN0 +YW5jZS5sb2NhbGhvc3SCFyoubXktaW5zdGFuY2UubG9jYWxob3N0MA0GCSqGSIb3 +DQEBCwUAA4IBgQAcK6EcBER1ExJ+jaLRLvyvkw0Z9JhB5AVVpgKuE9XJiJHrQCuJ +4nFeCZ2Nse8VkPtLdUCzup9ycbBFGzEp6XzjoeBpvC+uTJ6AhjNG/vPhSzgwX++a +69BzLGZVvrsh1BOwVy676gif99E5s19slzYHFm4kq/cXhkE8zMww0gFa3Xb9FGJv +hOfPA5yyJAC30bbUU0cKamGMRmS75jnWWlCrIwez+PEzEbLc7jELXfBtfX+zc8Ek +IIpK4S/IgbXNM0dXVNHdhGE56hRB/kBZSjHNy7QSB/mPStInM9YSDz4HKYXCLhQ4 +NNXZYst3YFhmgJ8cuVAyP0AZ8gNtbzLhwZXW00UE0q8t+xpgEQ87v4vIqXLCwqOK +iw+G5aGQpsZF6oHmPpPcQ5J7kHLIMvk+VVHVAivn4PRZqRkzbYxVennCcDqPStd4 +5Y9cKB4iWIHjfmdwGOGKJEfLlUHpG7R/8NoXJ8Ga9NU0UvgpTXg4yn7ChV/Cj4H6 +hCLKZcW/DPjnWiI= +-----END CERTIFICATE----- diff --git a/hack/test/configpatch.yaml b/hack/test/configpatch.yaml new file mode 100644 index 0000000..3ad4ac2 --- /dev/null +++ b/hack/test/configpatch.yaml @@ -0,0 +1,8 @@ +cluster: + network: + podSubnets: + - 10.10.0.0/17 + serviceSubnets: + - 10.10.128.0/17 + apiServer: + disablePodSecurityPolicy: true diff --git a/hack/test/integration.sh b/hack/test/integration.sh new file mode 100755 index 0000000..dcd7242 --- /dev/null +++ b/hack/test/integration.sh @@ -0,0 +1,191 @@ +#!/bin/bash + +set -eoux pipefail + +TMP="/tmp/kubevirt-e2e" +mkdir -p "${TMP}" + +# Settings. + +TALOS_VERSION=1.8.1 +OMNI_VERSION=${OMNI_VERSION:-latest} +K8S_VERSION="${K8S_VERSION:-v1.30.1}" + +ARTIFACTS=_out +JOIN_TOKEN=testonly +RUN_DIR=$(pwd) +PLATFORM=$(uname -s | tr "[:upper:]" "[:lower:]") + +export KUBECONFIG=${TMP}/kubeconfig + +# Download required artifacts. + +mkdir -p ${ARTIFACTS} + +[ -f ${ARTIFACTS}/talosctl ] || (crane export ghcr.io/siderolabs/talosctl:latest | tar x -C ${ARTIFACTS}) + +# Schematic without any customizations +SCHEMATIC_ID="376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba" + +TALOSCTL="${ARTIFACTS}/talosctl" +KUBECTL="${TMP}/kubectl" + +curl -Lo ${KUBECTL} "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/${PLATFORM}/amd64/kubectl" +chmod +x ${KUBECTL} + +curl -Lo ${ARTIFACTS}/integration-test-linux-amd64 https://github.com/siderolabs/omni/releases/download/${OMNI_VERSION}/integration-test-linux-amd64 +chmod +x ${ARTIFACTS}/integration-test-linux-amd64 + +# Build registry mirror args. + +if [[ "${CI:-false}" == "true" ]]; then + REGISTRY_MIRROR_FLAGS=() + + for registry in docker.io k8s.gcr.io quay.io gcr.io ghcr.io registry.k8s.io factory.talos.dev; do + service="registry-${registry//./-}.ci.svc" + addr=$(python3 -c "import socket; print(socket.gethostbyname('${service}'))") + + REGISTRY_MIRROR_FLAGS+=("--registry-mirror=${registry}=http://${addr}:5000") + done +else + # use the value from the environment, if present + REGISTRY_MIRROR_FLAGS=("${REGISTRY_MIRROR_FLAGS:-}") +fi + +CREATED_CLUSTER="kubevirt-test-$(echo $RANDOM | md5sum | head -c 10)" + +function cleanup() { + # gather container logs + if [[ ! -z ${KUBECONFIG} ]]; then + ${KUBECTL} get vm -A || true + ${KUBECTL} get vmi -A || true + ${KUBECTL} get datavolume -A || true + fi + + rm -rf ${TMP} + + if [[ ! -z ${CREATED_CLUSTER} ]]; then + echo "destroying created cluster" + ${TALOSCTL} cluster destroy --name=${CREATED_CLUSTER} --provisioner=qemu || true + rm -rf ~/.talos/clusters/${CREATED_CLUSTER} + fi + + docker rm -f omni-integration vault-dev + + rm -rf _out/omni/ +} + +trap cleanup EXIT SIGINT + +# Start Vault. + +docker run --rm -d --cap-add=IPC_LOCK -p 8200:8200 -e 'VAULT_DEV_ROOT_TOKEN_ID=dev-o-token' --name vault-dev hashicorp/vault:1.15 + +sleep 10 + +# Load key into Vault. + +docker cp hack/certs/key.private vault-dev:/tmp/key.private +docker exec -e VAULT_ADDR='http://0.0.0.0:8200' -e VAULT_TOKEN=dev-o-token vault-dev \ + vault kv put -mount=secret omni-private-key \ + private-key=@/tmp/key.private + +sleep 5 + +# Launch Omni in the background. + +export BASE_URL=https://localhost:8099/ +export AUTH_USERNAME="${AUTH0_TEST_USERNAME}" +export AUTH0_CLIENT_ID="${AUTH0_CLIENT_ID}" +export AUTH0_DOMAIN="${AUTH0_DOMAIN}" + +mkdir -p _out/omni/ + +docker run -it -d --network host -v ./hack/certs:/certs \ + -v $(pwd)/_out/omni:/_out \ + --cap-add=NET_ADMIN \ + --device=/dev/net/tun \ + -e SIDEROLINK_DEV_JOIN_TOKEN="${JOIN_TOKEN}" \ + -e VAULT_TOKEN=dev-o-token \ + -e VAULT_ADDR='http://127.0.0.1:8200' \ + ghcr.io/siderolabs/omni:${OMNI_VERSION} \ + omni-integration \ + --siderolink-wireguard-advertised-addr 10.11.0.1:50180 \ + --siderolink-api-advertised-url "grpc://10.11.0.1:8090" \ + --machine-api-bind-addr 0.0.0.0:8090 \ + --siderolink-wireguard-bind-addr 0.0.0.0:50180 \ + --event-sink-port 8091 \ + --auth-auth0-enabled true \ + --advertised-api-url "${BASE_URL}" \ + --auth-auth0-client-id "${AUTH0_CLIENT_ID}" \ + --auth-auth0-domain "${AUTH0_DOMAIN}" \ + --initial-users "${AUTH_USERNAME}" \ + --private-key-source "vault://secret/omni-private-key" \ + --public-key-files "/certs/key.public" \ + --bind-addr 0.0.0.0:8099 \ + --key /certs/localhost-key.pem \ + --cert /certs/localhost.pem \ + --etcd-embedded-unsafe-fsync=true \ + --create-initial-service-account \ + --initial-service-account-key-path=/_out/key \ + "${REGISTRY_MIRROR_FLAGS[@]}" \ + & + +echo "creating cluster ${CREATED_CLUSTER}" +TAG="v${TALOS_VERSION}" ${TALOSCTL} cluster create \ + --name=${CREATED_CLUSTER} \ + --kubernetes-version=${K8S_VERSION} \ + ${REGISTRY_MIRROR_FLAGS} \ + --provisioner=qemu \ + --crashdump \ + --cidr 10.11.0.0/24 \ + --vmlinuz-path="https://factory.talos.dev/image/${SCHEMATIC_ID}/v${TALOS_VERSION}/kernel-amd64" \ + --initrd-path="https://factory.talos.dev/image/${SCHEMATIC_ID}/v${TALOS_VERSION}/initramfs-amd64.xz" \ + --controlplanes=3 \ + --workers=1 \ + --cpus-workers 16.0 \ + --memory 4096 \ + --memory-workers=32768 \ + --mtu 1430 \ + --config-patch @hack/test/configpatch.yaml \ + --disk=65536 + +${TALOSCTL} config nodes 10.11.0.2 +${TALOSCTL} kubeconfig -f ${TMP}/kubeconfig + +# install kubevirt + +export RELEASE=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt) + +${KUBECTL} apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml + +${KUBECTL} apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml + +${KUBECTL} apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.60.1/cdi-operator.yaml +${KUBECTL} apply -f hack/test/manifests/cdi-cr.yaml +${KUBECTL} apply -f hack/test/manifests/local-path-storage.yaml + +${KUBECTL} patch kubevirt -n kubevirt kubevirt --type='json' -p='[{"op": "replace", "path": "/spec/configuration", "value": {"developerConfiguration": {"featureGates": ["ExpandDisks"]}}}]' + +${KUBECTL} -n kubevirt wait kv kubevirt --for condition=Available --timeout=10m + +# Launch infra provider in the background + +nice -n 10 ${ARTIFACTS}/omni-infra-provider-kubevirt-linux-amd64 \ + --kubeconfig-file=${KUBECONFIG} \ + --omni-api-endpoint http://localhost:8081 \ + --data-volume-mode Filesystem \ + --insecure-skip-verify& + +docker run \ + -v $(pwd)/hack/certs:/etc/ssl/certs \ + -e SSL_CERT_DIR=/etc/ssl/certs \ + -e OMNI_SERVICE_ACCOUNT_KEY=$(cat _out/omni/key) \ + --network host \ + ghcr.io/siderolabs/omni-integration-test:${OMNI_VERSION} \ + --endpoint https://localhost:8099 \ + --talos-version=${TALOS_VERSION} \ + --test.run "ScaleUpAndDownAutoProvisionMachineSets" \ + --infra-provider=kubevirt \ + --scale-timeout 5m \ + --provider-data='{disk_size: 8, cores: 4, memory: 4096, architecture: amd64}' diff --git a/hack/test/manifests/cdi-cr.yaml b/hack/test/manifests/cdi-cr.yaml new file mode 100644 index 0000000..76cd20d --- /dev/null +++ b/hack/test/manifests/cdi-cr.yaml @@ -0,0 +1,18 @@ +apiVersion: cdi.kubevirt.io/v1beta1 +kind: CDI +metadata: + name: cdi +spec: + config: + featureGates: + - HonorWaitForFirstConsumer + imagePullPolicy: IfNotPresent + infra: + nodeSelector: + kubernetes.io/os: linux + tolerations: + - key: CriticalAddonsOnly + operator: Exists + workload: + nodeSelector: + kubernetes.io/os: linux diff --git a/hack/test/manifests/local-path-storage.yaml b/hack/test/manifests/local-path-storage.yaml new file mode 100644 index 0000000..14d180f --- /dev/null +++ b/hack/test/manifests/local-path-storage.yaml @@ -0,0 +1,165 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: local-path-storage + labels: + pod-security.kubernetes.io/enforce: privileged +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: local-path-provisioner-service-account + namespace: local-path-storage + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: local-path-provisioner-role + namespace: local-path-storage +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "patch", "update", "delete"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: local-path-provisioner-role +rules: + - apiGroups: [""] + resources: + ["nodes", "persistentvolumeclaims", "configmaps", "pods", "pods/log"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "patch", "update", "delete"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: local-path-provisioner-bind + namespace: local-path-storage +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: local-path-provisioner-role +subjects: + - kind: ServiceAccount + name: local-path-provisioner-service-account + namespace: local-path-storage + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: local-path-provisioner-bind +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: local-path-provisioner-role +subjects: + - kind: ServiceAccount + name: local-path-provisioner-service-account + namespace: local-path-storage + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: local-path-provisioner + namespace: local-path-storage +spec: + replicas: 1 + selector: + matchLabels: + app: local-path-provisioner + template: + metadata: + labels: + app: local-path-provisioner + spec: + serviceAccountName: local-path-provisioner-service-account + containers: + - name: local-path-provisioner + image: rancher/local-path-provisioner:v0.0.30 + imagePullPolicy: IfNotPresent + command: + - local-path-provisioner + - --debug + - start + - --config + - /etc/config/config.json + volumeMounts: + - name: config-volume + mountPath: /etc/config/ + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CONFIG_MOUNT_PATH + value: /etc/config/ + volumes: + - name: config-volume + configMap: + name: local-path-config + +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-path + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: rancher.io/local-path +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: Delete + +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: local-path-config + namespace: local-path-storage +data: + config.json: |- + { + "nodePathMap":[ + { + "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES", + "paths":["/var/local-path-provisioner"] + } + ] + } + setup: |- + #!/bin/sh + set -eu + mkdir -m 0777 -p "$VOL_DIR" + teardown: |- + #!/bin/sh + set -eu + rm -rf "$VOL_DIR" + helperPod.yaml: |- + apiVersion: v1 + kind: Pod + metadata: + name: helper-pod + spec: + priorityClassName: system-node-critical + tolerations: + - key: node.kubernetes.io/disk-pressure + operator: Exists + effect: NoSchedule + containers: + - name: helper-pod + image: busybox + imagePullPolicy: IfNotPresent diff --git a/internal/pkg/provider/provision.go b/internal/pkg/provider/provision.go index 9c99f7a..4072d9d 100644 --- a/internal/pkg/provider/provision.go +++ b/internal/pkg/provider/provision.go @@ -33,30 +33,46 @@ import ( // Provisioner implements Talos emulator infra provider. type Provisioner struct { - k8sClient client.Client - namespace string + k8sClient client.Client + namespace string + volumeMode v1.PersistentVolumeMode } // NewProvisioner creates a new provisioner. -func NewProvisioner(k8sClient client.Client, namespace string) *Provisioner { +func NewProvisioner(k8sClient client.Client, namespace, volumeMode string) *Provisioner { return &Provisioner{ - k8sClient: k8sClient, - namespace: namespace, + k8sClient: k8sClient, + namespace: namespace, + volumeMode: v1.PersistentVolumeMode(volumeMode), } } // ProvisionSteps implements infra.Provisioner. // -//nolint:gocognit,gocyclo,cyclop +//nolint:gocognit,gocyclo,cyclop,maintidx func (p *Provisioner) ProvisionSteps() []provision.Step[*resources.Machine] { return []provision.Step[*resources.Machine]{ - provision.NewStep("ensureVolume", func(ctx context.Context, logger *zap.Logger, pctx provision.Context[*resources.Machine]) error { - schematic, err := pctx.GenerateSchematicID(ctx, logger, provision.WithExtraKernelArgs("console=ttyS0,38400n8")) + provision.NewStep("validateRequest", func(_ context.Context, _ *zap.Logger, pctx provision.Context[*resources.Machine]) error { + if len(pctx.GetRequestID()) > 62 { + return fmt.Errorf("the machine request name can not be longer than 63 characters") + } + + return nil + }), + provision.NewStep("createSchematic", func(ctx context.Context, logger *zap.Logger, pctx provision.Context[*resources.Machine]) error { + schematic, err := pctx.GenerateSchematicID(ctx, logger, + provision.WithExtraKernelArgs("console=ttyS0,38400n8"), + provision.WithoutConnectionParams(), + ) if err != nil { return err } pctx.State.TypedSpec().Value.Schematic = schematic + + return nil + }), + provision.NewStep("ensureVolume", func(ctx context.Context, _ *zap.Logger, pctx provision.Context[*resources.Machine]) error { pctx.State.TypedSpec().Value.TalosVersion = pctx.GetTalosVersion() url, err := url.Parse(constants.ImageFactoryBaseURL) @@ -71,7 +87,11 @@ func (p *Provisioner) ProvisionSteps() []provision.Step[*resources.Machine] { return err } - url = url.JoinPath("image", schematic, pctx.GetTalosVersion(), fmt.Sprintf("metal-%s.raw", data.Architecture)) + url = url.JoinPath("image", + pctx.State.TypedSpec().Value.Schematic, + pctx.GetTalosVersion(), + fmt.Sprintf("nocloud-%s.qcow2", data.Architecture), + ) hash := sha256.New() @@ -91,7 +111,6 @@ func (p *Provisioner) ProvisionSteps() []provision.Step[*resources.Machine] { }, }, PVC: &v1.PersistentVolumeClaimSpec{ - VolumeMode: pointer.To(v1.PersistentVolumeBlock), AccessModes: []v1.PersistentVolumeAccessMode{ v1.ReadWriteOnce, }, @@ -104,6 +123,16 @@ func (p *Provisioner) ProvisionSteps() []provision.Step[*resources.Machine] { }, } + if p.volumeMode != "" { + volume.Spec.PVC.VolumeMode = &p.volumeMode + } + + if volume.Annotations == nil { + volume.Annotations = map[string]string{} + } + + volume.Annotations["cdi.kubevirt.io/storage.bind.immediate.requested"] = "true" + vol := &cdiv1.DataVolume{} err = p.k8sClient.Get(ctx, client.ObjectKey{ @@ -211,35 +240,49 @@ func (p *Provisioner) ProvisionSteps() []provision.Step[*resources.Machine] { }, }, }, - } - - vm.Spec.DataVolumeTemplates = []kvv1.DataVolumeTemplateSpec{ { - ObjectMeta: metav1.ObjectMeta{ - Name: pctx.GetRequestID(), + Name: "cloudinitdisk", + VolumeSource: kvv1.VolumeSource{ + CloudInitNoCloud: &kvv1.CloudInitNoCloudSource{ + UserData: pctx.ConnectionParams.JoinConfig, + NetworkData: `version: 1`, + }, }, - Spec: cdiv1.DataVolumeSpec{ - PVC: &v1.PersistentVolumeClaimSpec{ - VolumeMode: pointer.To(v1.PersistentVolumeBlock), - AccessModes: []v1.PersistentVolumeAccessMode{ - v1.ReadWriteOnce, - }, - Resources: v1.VolumeResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceStorage: resource.MustParse(fmt.Sprintf("%dGi", data.DiskSize)), - }, - }, + }, + } + + volumeTemplate := kvv1.DataVolumeTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: pctx.GetRequestID(), + }, + Spec: cdiv1.DataVolumeSpec{ + PVC: &v1.PersistentVolumeClaimSpec{ + AccessModes: []v1.PersistentVolumeAccessMode{ + v1.ReadWriteOnce, }, - Source: &cdiv1.DataVolumeSource{ - PVC: &cdiv1.DataVolumeSourcePVC{ - Name: pctx.State.TypedSpec().Value.VolumeId, - Namespace: p.namespace, + Resources: v1.VolumeResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceStorage: resource.MustParse(fmt.Sprintf("%dGi", data.DiskSize)), }, }, }, + Source: &cdiv1.DataVolumeSource{ + PVC: &cdiv1.DataVolumeSourcePVC{ + Name: pctx.State.TypedSpec().Value.VolumeId, + Namespace: p.namespace, + }, + }, }, } + if p.volumeMode != "" { + volumeTemplate.Spec.PVC.VolumeMode = &p.volumeMode + } + + vm.Spec.DataVolumeTemplates = []kvv1.DataVolumeTemplateSpec{ + volumeTemplate, + } + if vm.Name == "" { vm.Name = pctx.GetRequestID() vm.Namespace = p.namespace