From 366a61f7d40d90087b38a717e2be42ecc2cb7afe Mon Sep 17 00:00:00 2001 From: Aniruddha Basak Date: Wed, 20 Mar 2024 16:14:04 +0530 Subject: [PATCH] Support new Cluster stack convention New cluster stack has multi stage cluster addon which has clusteraddon.yaml in their release assets Signed-off-by: Aniruddha Basak --- pkg/clusterstack/config.go | 22 ++-- pkg/clusterstack/metadata.go | 8 +- pkg/clusterstack/mode.go | 16 +-- pkg/cmd/create.go | 63 ++++++--- pkg/template/package.go | 87 ++++++++++++- .../valencia/cluster-addon/cni/Chart.yaml | 9 ++ .../cluster-addon/cni/templates/cni.yaml | 120 ++++++++++++++++++ .../valencia/cluster-addon/cni/values.yaml | 0 .../cluster-addon/metrics-server/.helmignore | 23 ++++ .../cluster-addon/metrics-server/Chart.lock | 6 + .../cluster-addon/metrics-server/Chart.yaml | 16 +++ .../charts/metrics-server-3.11.0.tgz | Bin 0 -> 8462 bytes .../metrics-server/overwrite.yaml | 5 + .../metrics-server/templates/ngnix.yaml | 101 +++++++++++++++ .../cluster-addon/metrics-server/values.yaml | 44 +++++++ .../docker/valencia/cluster-class/.helmignore | 23 ++++ .../docker/valencia/cluster-class/Chart.yaml | 11 ++ .../cluster-class/templates/_helpers.tpl | 62 +++++++++ .../templates/cluster-class.yaml | 101 +++++++++++++++ .../templates/docker-cluster-template.yaml | 8 ++ .../templates/docker-machine-template.yaml | 11 ++ ...kubeadm-config-template-worker-docker.yaml | 15 +++ .../kubeadm-control-plane-template.yaml | 29 +++++ .../docker/valencia/cluster-class/values.yaml | 5 + .../docker/valencia/clusteraddon.yaml | 24 ++++ .../cluster-stacks/docker/valencia/csctl.yaml | 7 + .../node-image/Dockerfile.controlplane | 3 + .../valencia/node-image/Dockerfile.worker | 3 + .../valencia/node-image/scripts/base.sh | 46 +++++++ .../docker/valencia/node-images.yaml | 4 + .../docker/valencia/topology-docker.yaml | 26 ++++ 31 files changed, 852 insertions(+), 46 deletions(-) create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/cni/Chart.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/cni/templates/cni.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/cni/values.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/.helmignore create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.lock create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/overwrite.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/templates/ngnix.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/values.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/.helmignore create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/Chart.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/templates/_helpers.tpl create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/templates/cluster-class.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-cluster-template.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-machine-template.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-config-template-worker-docker.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-control-plane-template.yaml create mode 100644 tests/cluster-stacks/docker/valencia/cluster-class/values.yaml create mode 100644 tests/cluster-stacks/docker/valencia/clusteraddon.yaml create mode 100644 tests/cluster-stacks/docker/valencia/csctl.yaml create mode 100644 tests/cluster-stacks/docker/valencia/node-image/Dockerfile.controlplane create mode 100644 tests/cluster-stacks/docker/valencia/node-image/Dockerfile.worker create mode 100755 tests/cluster-stacks/docker/valencia/node-image/scripts/base.sh create mode 100644 tests/cluster-stacks/docker/valencia/node-images.yaml create mode 100644 tests/cluster-stacks/docker/valencia/topology-docker.yaml diff --git a/pkg/clusterstack/config.go b/pkg/clusterstack/config.go index e3c45d14..56cb078f 100644 --- a/pkg/clusterstack/config.go +++ b/pkg/clusterstack/config.go @@ -45,45 +45,45 @@ type CsctlConfig struct { } // GetCsctlConfig returns CsctlConfig. -func GetCsctlConfig(path string) (CsctlConfig, error) { +func GetCsctlConfig(path string) (*CsctlConfig, error) { configPath := filepath.Join(path, "csctl.yaml") configFileData, err := os.ReadFile(filepath.Clean(configPath)) if err != nil { - return CsctlConfig{}, fmt.Errorf("failed to read csctl config: %w", err) + return nil, fmt.Errorf("failed to read csctl config: %w", err) } - cs := CsctlConfig{} + cs := &CsctlConfig{} if err := yaml.Unmarshal(configFileData, &cs); err != nil { - return CsctlConfig{}, fmt.Errorf("failed to unmarshal csctl yaml: %w", err) + return nil, fmt.Errorf("failed to unmarshal csctl yaml: %w", err) } if cs.Config.Provider.Type == "" { - return CsctlConfig{}, fmt.Errorf("provider type must not be empty") + return nil, fmt.Errorf("provider type must not be empty") } if len(cs.Config.Provider.Type) > 253 { - return CsctlConfig{}, fmt.Errorf("provider name must not be greater than 253") + return nil, fmt.Errorf("provider name must not be greater than 253") } match, err := regexp.MatchString(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`, cs.Config.Provider.Type) if err != nil { - return CsctlConfig{}, fmt.Errorf("failed to provider name match regex: %w", err) + return nil, fmt.Errorf("failed to provider name match regex: %w", err) } if !match { - return CsctlConfig{}, fmt.Errorf("invalid provider type: %q", cs.Config.Provider.Type) + return nil, fmt.Errorf("invalid provider type: %q", cs.Config.Provider.Type) } if cs.Config.ClusterStackName == "" { - return CsctlConfig{}, fmt.Errorf("cluster stack name must not be empty") + return nil, fmt.Errorf("cluster stack name must not be empty") } // Validate kubernetes version matched, err := regexp.MatchString(`^v\d+\.\d+\.\d+$`, cs.Config.KubernetesVersion) if err != nil { - return CsctlConfig{}, fmt.Errorf("failed to kubernetes match regex: %w", err) + return nil, fmt.Errorf("failed to kubernetes match regex: %w", err) } if !matched { - return CsctlConfig{}, fmt.Errorf("invalid kubernetes version: %q", cs.Config.KubernetesVersion) + return nil, fmt.Errorf("invalid kubernetes version: %q", cs.Config.KubernetesVersion) } return cs, nil diff --git a/pkg/clusterstack/metadata.go b/pkg/clusterstack/metadata.go index 8c02ab2a..0141f480 100644 --- a/pkg/clusterstack/metadata.go +++ b/pkg/clusterstack/metadata.go @@ -44,17 +44,17 @@ type MetaData struct { } // ParseMetaData parse the metadata file. -func ParseMetaData(path string) (MetaData, error) { +func ParseMetaData(path string) (*MetaData, error) { metadataPath := filepath.Join(path, "metadata.yaml") fileInfo, err := os.ReadFile(filepath.Clean(metadataPath)) if err != nil { - return MetaData{}, fmt.Errorf("failed to read metadata file: %w", err) + return nil, fmt.Errorf("failed to read metadata file: %w", err) } - metaData := MetaData{} + metaData := &MetaData{} if err := yaml.Unmarshal(fileInfo, &metaData); err != nil { - return MetaData{}, fmt.Errorf("failed to unmarshal metadata yaml: %w", err) + return nil, fmt.Errorf("failed to unmarshal metadata yaml: %w", err) } return metaData, nil diff --git a/pkg/clusterstack/mode.go b/pkg/clusterstack/mode.go index 84c27156..7e109cf7 100644 --- a/pkg/clusterstack/mode.go +++ b/pkg/clusterstack/mode.go @@ -24,22 +24,22 @@ import ( ) // HandleStableMode returns metadata for the stable mode. -func HandleStableMode(gitHubReleasePath string, currentReleaseHash, latestReleaseHash hash.ReleaseHash) (MetaData, error) { +func HandleStableMode(gitHubReleasePath string, currentReleaseHash, latestReleaseHash hash.ReleaseHash) (*MetaData, error) { metadata, err := ParseMetaData(gitHubReleasePath) if err != nil { - return MetaData{}, fmt.Errorf("failed to parse metadata: %w", err) + return nil, fmt.Errorf("failed to parse metadata: %w", err) } metadata.Versions.ClusterStack, err = BumpVersion(metadata.Versions.ClusterStack) if err != nil { - return MetaData{}, fmt.Errorf("failed to bump cluster stack: %w", err) + return nil, fmt.Errorf("failed to bump cluster stack: %w", err) } fmt.Printf("Bumped ClusterStack Version: %s\n", metadata.Versions.ClusterStack) if currentReleaseHash.ClusterAddonDir != latestReleaseHash.ClusterAddonDir || currentReleaseHash.ClusterAddonValues != latestReleaseHash.ClusterAddonValues { metadata.Versions.Components.ClusterAddon, err = BumpVersion(metadata.Versions.Components.ClusterAddon) if err != nil { - return MetaData{}, fmt.Errorf("failed to bump cluster addon: %w", err) + return nil, fmt.Errorf("failed to bump cluster addon: %w", err) } fmt.Printf("Bumped ClusterAddon Version: %s\n", metadata.Versions.Components.ClusterAddon) } else { @@ -49,7 +49,7 @@ func HandleStableMode(gitHubReleasePath string, currentReleaseHash, latestReleas if currentReleaseHash.NodeImageDir != latestReleaseHash.NodeImageDir { metadata.Versions.Components.NodeImage, err = BumpVersion(metadata.Versions.Components.NodeImage) if err != nil { - return MetaData{}, fmt.Errorf("failed to bump node image: %w", err) + return nil, fmt.Errorf("failed to bump node image: %w", err) } fmt.Printf("Bumped NodeImage Version: %s\n", metadata.Versions.Components.NodeImage) } else { @@ -64,15 +64,15 @@ func HandleStableMode(gitHubReleasePath string, currentReleaseHash, latestReleas } // HandleHashMode returns metadata of Hash mode. -func HandleHashMode(kubernetesVersion string) (MetaData, error) { +func HandleHashMode(kubernetesVersion string) (*MetaData, error) { commitHash, err := git.GetLatestGitCommit("./") if err != nil { - return MetaData{}, fmt.Errorf("failed to get latest commit hash: %w", err) + return nil, fmt.Errorf("failed to get latest commit hash: %w", err) } commitHash = fmt.Sprintf("v0-sha.%s", commitHash) - return MetaData{ + return &MetaData{ APIVersion: "metadata.clusterstack.x-k8s.io/v1alpha1", Versions: Versions{ Kubernetes: kubernetesVersion, diff --git a/pkg/cmd/create.go b/pkg/cmd/create.go index b0fa9649..aee5119f 100644 --- a/pkg/cmd/create.go +++ b/pkg/cmd/create.go @@ -58,13 +58,14 @@ var ( // CreateOptions contains config for creating a release. type CreateOptions struct { - ClusterStackPath string - ClusterStackReleaseDir string - Config clusterstack.CsctlConfig - Metadata clusterstack.MetaData - CurrentReleaseHash hash.ReleaseHash - LatestReleaseHash hash.ReleaseHash - NodeImageRegistry string + newClusterStackConvention bool + ClusterStackPath string + ClusterStackReleaseDir string + Config *clusterstack.CsctlConfig + Metadata *clusterstack.MetaData + CurrentReleaseHash hash.ReleaseHash + LatestReleaseHash hash.ReleaseHash + NodeImageRegistry string } // createCmd represents the create command. @@ -95,7 +96,17 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti createOption.ClusterStackPath = clusterStackPath createOption.Config = config - _, _, err = providerplugin.GetProviderExecutable(&config) + if _, err := os.Stat(filepath.Join(clusterStackPath, "clusteraddon.yaml")); err != nil { + // old if clusteraddon.yaml is not present. + if !os.IsNotExist(err) { + return nil, fmt.Errorf("failed to find clusteraddon.yaml: %w", err) + } + } else { + // new if clusteraddon.yaml is present. + createOption.newClusterStackConvention = true + } + + _, _, err = providerplugin.GetProviderExecutable(config) if err != nil { return createOption, fmt.Errorf("providerplugin.GetProviderExecutable(&config) failed: %w", err) } @@ -121,7 +132,7 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti // update the metadata kubernetes version with the csctl.yaml config createOption.Metadata.Versions.Kubernetes = config.Config.KubernetesVersion - latestRepoRelease, err := github.GetLatestReleaseFromRemoteRepository(ctx, mode, &config, gc) + latestRepoRelease, err := github.GetLatestReleaseFromRemoteRepository(ctx, mode, config, gc) if err != nil { return nil, fmt.Errorf("failed to get latest release form remote repository: %w", err) } @@ -144,7 +155,7 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti } } - releaseDirName, err := clusterstack.GetClusterStackReleaseDirectoryName(&createOption.Metadata, &createOption.Config) + releaseDirName, err := clusterstack.GetClusterStackReleaseDirectoryName(createOption.Metadata, createOption.Config) if err != nil { return nil, fmt.Errorf("failed to get cluster stack release directory name: %w", err) } @@ -222,7 +233,7 @@ func (c *CreateOptions) generateRelease() error { } // Build all the templated output and put it in a tmp directory - if err := template.GenerateOutputFromTemplate(c.ClusterStackPath, "./.tmp/", &c.Metadata); err != nil { + if err := template.GenerateOutputFromTemplate(c.ClusterStackPath, "./.tmp/", c.Metadata); err != nil { return fmt.Errorf("failed to generate tmp output: %w", err) } @@ -238,18 +249,30 @@ func (c *CreateOptions) generateRelease() error { } // Package Helm from the tmp directory to the release directory - if err := template.CreatePackage("./.tmp/", c.ClusterStackReleaseDir); err != nil { + if err := template.CreatePackage("./.tmp/", c.ClusterStackReleaseDir, c.newClusterStackConvention, c.Config, c.Metadata); err != nil { return fmt.Errorf("failed to create template package: %w", err) } - // Copy the cluster-addon-values.yaml config to release if old way - clusterAddonData, err := os.ReadFile(filepath.Join(c.ClusterStackPath, "cluster-addon-values.yaml")) - if err != nil { - return fmt.Errorf("failed to read cluster-addon-values.yaml: %w", err) - } + if c.newClusterStackConvention { + // Copy the clusteraddon.yaml config to release if new way + clusterAddonData, err := os.ReadFile(filepath.Join(c.ClusterStackPath, "clusteraddon.yaml")) + if err != nil { + return fmt.Errorf("failed to read clusteraddon.yaml: %w", err) + } + + if err := os.WriteFile(filepath.Join(c.ClusterStackReleaseDir, "clusteraddon.yaml"), clusterAddonData, os.FileMode(0o644)); err != nil { + return fmt.Errorf("failed to write clusteraddon.yaml: %w", err) + } + } else { + // Copy the cluster-addon-values.yaml config to release if old way + clusterAddonData, err := os.ReadFile(filepath.Join(c.ClusterStackPath, "cluster-addon-values.yaml")) + if err != nil { + return fmt.Errorf("failed to read cluster-addon-values.yaml: %w", err) + } - if err := os.WriteFile(filepath.Join(c.ClusterStackReleaseDir, "cluster-addon-values.yaml"), clusterAddonData, os.FileMode(0o644)); err != nil { - return fmt.Errorf("failed to write cluster-addon-values.yaml: %w", err) + if err := os.WriteFile(filepath.Join(c.ClusterStackReleaseDir, "cluster-addon-values.yaml"), clusterAddonData, os.FileMode(0o644)); err != nil { + return fmt.Errorf("failed to write cluster-addon-values.yaml: %w", err) + } } // Put the final metadata file into the output directory. @@ -268,7 +291,7 @@ func (c *CreateOptions) generateRelease() error { return fmt.Errorf("failed to write metadata: %w", err) } - err = providerplugin.CreateNodeImages(&c.Config, + err = providerplugin.CreateNodeImages(c.Config, c.ClusterStackPath, c.ClusterStackReleaseDir, c.NodeImageRegistry) diff --git a/pkg/template/package.go b/pkg/template/package.go index a0248cef..902a8209 100644 --- a/pkg/template/package.go +++ b/pkg/template/package.go @@ -17,20 +17,40 @@ limitations under the License. package template import ( + "archive/tar" + "compress/gzip" "fmt" + "io" + "io/fs" + "os" "path/filepath" + "github.com/SovereignCloudStack/csctl/pkg/clusterstack" "helm.sh/helm/v3/pkg/action" ) // CreatePackage creates the package for release. -func CreatePackage(src, dst string) error { +func CreatePackage(src, dst string, newType bool, config *clusterstack.CsctlConfig, metadata *clusterstack.MetaData) error { + fmt.Printf("path now: %q\n", filepath.Join(src, "cluster-class")) if err := createHelmPackage(filepath.Join(src, "cluster-class"), dst); err != nil { return fmt.Errorf("failed to create package for ClusterClass: %w", err) } - if err := createHelmPackage(filepath.Join(src, "cluster-addon"), dst); err != nil { - return fmt.Errorf("failed to create package for ClusterAddon: %w", err) + kubernetesVerion, err := config.ParseKubernetesVersion() + if err != nil { + return fmt.Errorf("failed to parse kubernetes version: %w", err) + } + + if newType { + clusterAddonDst := filepath.Join(dst, fmt.Sprintf("%s-%s-%s-cluster-addon-%s.tgz", config.Config.Provider.Type, config.Config.ClusterStackName, kubernetesVerion.String(), metadata.Versions.Components.ClusterAddon)) + if err := createTarPackage(filepath.Join(src, "cluster-addon"), clusterAddonDst); err != nil { + return fmt.Errorf("failed to create package for ClusterAddon: %w", err) + } + } else { + fmt.Printf("path now: %q\n", filepath.Join(src, "cluster-addon")) + if err := createHelmPackage(filepath.Join(src, "cluster-addon"), dst); err != nil { + return fmt.Errorf("failed to create helm package for ClusterAddon: %w", err) + } } return nil @@ -47,3 +67,64 @@ func createHelmPackage(src, dst string) error { return nil } + +func createTarPackage(src, dst string) error { + outFile, err := os.Create(filepath.Clean(dst)) + if err != nil { + return fmt.Errorf("failed to create tar output destination directory: %w", err) + } + defer outFile.Close() + + gw := gzip.NewWriter(outFile) + defer gw.Close() + + tw := tar.NewWriter(gw) + defer tw.Close() + + if err := filepath.Walk(src, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + + // Ignore the root folder itself + if path == src { + return nil + } + + relPath, err := filepath.Rel(src, path) + if err != nil { + return fmt.Errorf("failed to calculate relative path of source: %q and destination: %q directory: %w", src, dst, err) + } + + // Use filepath.ToSlash to convert path separators to '/' + relPath = filepath.ToSlash(relPath) + + header, err := tar.FileInfoHeader(info, relPath) + if err != nil { + return fmt.Errorf("failed to get the tar info header: %w", err) + } + header.Name = relPath + + if err := tw.WriteHeader(header); err != nil { + return fmt.Errorf("failed to set the write header: %w", err) + } + + if !info.IsDir() { + file, err := os.Open(filepath.Clean(path)) + if err != nil { + return fmt.Errorf("failed to open path: %w", err) + } + defer file.Close() + + if _, err := io.Copy(tw, file); err != nil { + return fmt.Errorf("failed to copy file: %w", err) + } + } + + return nil + }); err != nil { + return fmt.Errorf("failed to walk on the source directory: %w", err) + } + + return nil +} diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/cni/Chart.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/cni/Chart.yaml new file mode 100644 index 00000000..f04b67a8 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/cni/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +type: application +description: CNI chart for kind +name: CNI +version: '0' +maintainers: + - name: Syself + email: info@syself.com + url: https://github.com/syself diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/cni/templates/cni.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/cni/templates/cni.yaml new file mode 100644 index 00000000..fbe82f54 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/cni/templates/cni.yaml @@ -0,0 +1,120 @@ +# kindnetd networking manifest +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kindnet + name: kindnet + name: kindnet +rules: + - apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch + - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kindnet +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kindnet +subjects: + - kind: ServiceAccount + name: kindnet + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kindnet + namespace: kube-system +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kindnet + namespace: kube-system + labels: + tier: node + app: kindnet + k8s-app: kindnet +spec: + selector: + matchLabels: + app: kindnet + template: + metadata: + labels: + tier: node + app: kindnet + k8s-app: kindnet + spec: + hostNetwork: true + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: kindnet + containers: + - name: kindnet-cni + image: kindest/kindnetd:v20230511-dc714da8 + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + # We're using the dualstack CIDRs here. The order doesn't matter for kindnet as the loops are run concurrently. + # REF: https://github.com/kubernetes-sigs/kind/blob/3dbeb894e3092a336ab4278d3823e73a1d66aff7/images/kindnetd/cmd/kindnetd/main.go#L149-L175 + - name: POD_SUBNET + value: '${DOCKER_POD_CIDRS},${DOCKER_POD_IPV6_CIDRS}' + volumeMounts: + - name: cni-cfg + mountPath: /etc/cni/net.d + - name: xtables-lock + mountPath: /run/xtables.lock + readOnly: false + - name: lib-modules + mountPath: /lib/modules + readOnly: true + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: false + capabilities: + add: ["NET_RAW", "NET_ADMIN"] + volumes: + - name: cni-bin + hostPath: + path: /opt/cni/bin + type: DirectoryOrCreate + - name: cni-cfg + hostPath: + path: /etc/cni/net.d + type: DirectoryOrCreate + - name: xtables-lock + hostPath: + path: /run/xtables.lock + type: FileOrCreate + - name: lib-modules + hostPath: + path: /lib/modules diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/cni/values.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/cni/values.yaml new file mode 100644 index 00000000..e69de29b diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/.helmignore b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.lock b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.lock new file mode 100644 index 00000000..dcf1105c --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: metrics-server + repository: https://kubernetes-sigs.github.io/metrics-server/ + version: 3.11.0 +digest: sha256:d92caa34d06b047b0390aa33a6f5d15d4fe0566143625204ebbbc69085133c4e +generated: "2024-01-08T18:57:56.42493498+05:30" diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.yaml new file mode 100644 index 00000000..1079e6f1 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +type: application +description: | + This chart installs and configures: + * Docker Ferrol Cluster Class +name: docker-ferrol-1-27-cluster-addon +version: << .ClusterAddonVersion >> +maintainers: + - name: Syself + email: info@syself.com + url: https://github.com/syself +dependencies: + - name: "metrics-server" + version: "3.11.0" + repository: "https://kubernetes-sigs.github.io/metrics-server/" + alias: "metrics-server" diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8860457ec1efe286aefd1237d6a403256c933800 GIT binary patch literal 8462 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 literal 0 HcmV?d00001 diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/overwrite.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/overwrite.yaml new file mode 100644 index 00000000..e0033983 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/overwrite.yaml @@ -0,0 +1,5 @@ +values: | + metrics-server: + commonLabels: + domain: "{{ .Cluster.spec.controlPlaneEndpoint.host }}" + clusterAddonVersion: "v2" diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/templates/ngnix.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/templates/ngnix.yaml new file mode 100644 index 00000000..594cb5f6 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/templates/ngnix.yaml @@ -0,0 +1,101 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: release-name-ngnix-7777 + namespace: "kube-system" + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ngnix + app.kubernetes.io/version: 1.25.3 + helm.sh/chart: ngnix-15.10.1 +spec: + replicas: 1 + revisionHistoryLimit: 10 + strategy: + rollingUpdate: {} + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: ngnix + template: + metadata: + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ngnix + app.kubernetes.io/version: 1.25.3 + helm.sh/chart: ngnix-15.10.1 + annotations: + spec: + + shareProcessNamespace: false + serviceAccountName: release-name-ngnix + automountServiceAccountToken: false + affinity: + podAffinity: + + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: ngnix + topologyKey: kubernetes.io/hostname + weight: 1 + nodeAffinity: + + hostNetwork: false + hostIPC: false + securityContext: + fsGroup: 1001 + fsGroupChangePolicy: Always + supplementalGroups: [] + sysctls: [] + containers: + - name: nginx + image: docker.io/bitnami/nginx:1.25.3-debian-11-r6 + imagePullPolicy: "IfNotPresent" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 1001 + seccompProfile: + type: RuntimeDefault + env: + - name: BITNAMI_DEBUG + value: "false" + - name: NGINX_HTTP_PORT_NUMBER + value: "8080" + envFrom: + ports: + - name: http + containerPort: 8080 + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + tcpSocket: + port: http + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 3 + tcpSocket: + port: http + resources: + limits: {} + requests: {} + volumeMounts: + volumes: diff --git a/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/values.yaml b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/values.yaml new file mode 100644 index 00000000..17847d61 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-addon/metrics-server/values.yaml @@ -0,0 +1,44 @@ +metrics-server: + fullnameOverride: metrics-server + replicas: 1 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + + podDisruptionBudget: + apiVersion: policy/v1 + enabled: true + minAvailable: 1 + + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + - key: CriticalAddonsOnly + operator: Exists + + service: + labels: + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "metrics-server" + + defaultArgs: + - --cert-dir=/tmp + - --kubelet-preferred-address-types=ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + + args: + - --kubelet-insecure-tls + + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - metrics-server + topologyKey: "kubernetes.io/hostname" diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/.helmignore b/tests/cluster-stacks/docker/valencia/cluster-class/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/Chart.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/Chart.yaml new file mode 100644 index 00000000..233c1344 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +description: | + This chart installs and configures: + * Docker Ferrol Cluster Class +maintainers: + - name: Syself + email: info@syself.com + url: https://github.com/syself +name: docker-ferrol-1-27-cluster-class +type: application +version: << .ClusterAddonVersion >> diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/templates/_helpers.tpl b/tests/cluster-stacks/docker/valencia/cluster-class/templates/_helpers.tpl new file mode 100644 index 00000000..2339c125 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cluster-class.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "cluster-class.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cluster-class.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cluster-class.labels" -}} +helm.sh/chart: {{ include "cluster-class.chart" . }} +{{ include "cluster-class.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cluster-class.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cluster-class.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cluster-class.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "cluster-class.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/templates/cluster-class.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/templates/cluster-class.yaml new file mode 100644 index 00000000..3f6cb505 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/templates/cluster-class.yaml @@ -0,0 +1,101 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: ClusterClass +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }} + namespace: {{.Release.Namespace}} +spec: + controlPlane: + ref: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: KubeadmControlPlaneTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-control-plane + namespace: {{ .Release.Namespace }} + machineInfrastructure: + ref: + kind: DockerMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + name: {{ .Release.Name }}-{{ .Chart.Version }}-machinetemplate-docker + namespace: {{ .Release.Namespace }} + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerClusterTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-cluster + namespace: {{ .Release.Namespace }} + workers: + machineDeployments: + - class: workeramd64 + template: + bootstrap: + ref: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-worker-bootstraptemplate-docker + namespace: {{ .Release.Namespace }} + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-machinetemplate-docker + namespace: {{ .Release.Namespace }} + variables: + - name: imageRepository + required: true + schema: + openAPIV3Schema: + type: string + default: "" + example: "registry.k8s.io" + description: "imageRepository sets the container registry to pull images from. If empty, nothing will be set and the from of kubeadm will be used." + patches: + - name: imageRepository + description: "Sets the imageRepository used for the KubeadmControlPlane." + enabledIf: '{{ ne .imageRepository "" }}' + definitions: + - selector: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: KubeadmControlPlaneTemplate + matchResources: + controlPlane: true + jsonPatches: + - op: add + path: "/spec/template/spec/kubeadmConfigSpec/clusterConfiguration/imageRepository" + valueFrom: + variable: imageRepository + - name: customImage + description: "Sets the container image that is used for running dockerMachines for the controlplane and worker machineDeployments." + definitions: + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + matchResources: + machineDeploymentClass: + names: + - workeramd64 + jsonPatches: + - op: add + path: "/spec/template/spec/customImage" + value: {{ (index .Values.images.controlPlane 0).name }} + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + matchResources: + controlPlane: true + jsonPatches: + - op: add + path: "/spec/template/spec/customImage" + value: {{ (index .Values.images.controlPlane 0).name }} + - name: DockerMachineTemplateWorker + description: "Sets the container image that is used for running dockerMachines for the worker machineDeployments." + definitions: + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + matchResources: + machineDeploymentClass: + names: + - workeramd64 + jsonPatches: + - op: add + path: "/spec/template/spec/customImage" + value: {{ (index .Values.images.worker 0).name }} diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-cluster-template.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-cluster-template.yaml new file mode 100644 index 00000000..0bdf7120 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-cluster-template.yaml @@ -0,0 +1,8 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: DockerClusterTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-cluster + namespace: {{ .Release.Namespace }} +spec: + template: + spec: {} diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-machine-template.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-machine-template.yaml new file mode 100644 index 00000000..bc4c6cc6 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/templates/docker-machine-template.yaml @@ -0,0 +1,11 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: DockerMachineTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-machinetemplate-docker + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-config-template-worker-docker.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-config-template-worker-docker.yaml new file mode 100644 index 00000000..861ccec4 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-config-template-worker-docker.yaml @@ -0,0 +1,15 @@ +apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 +kind: KubeadmConfigTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-worker-bootstraptemplate-docker + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + # We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-control-plane-template.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-control-plane-template.yaml new file mode 100644 index 00000000..c76866e7 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/templates/kubeadm-control-plane-template.yaml @@ -0,0 +1,29 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta1 +kind: KubeadmControlPlaneTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-control-plane + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + kubeadmConfigSpec: + clusterConfiguration: + controllerManager: + extraArgs: { enable-hostpath-provisioner: 'true' } + apiServer: + # host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied. + certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal] + initConfiguration: + nodeRegistration: + # We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" + joinConfiguration: + nodeRegistration: + # We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" diff --git a/tests/cluster-stacks/docker/valencia/cluster-class/values.yaml b/tests/cluster-stacks/docker/valencia/cluster-class/values.yaml new file mode 100644 index 00000000..eb2bb411 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/cluster-class/values.yaml @@ -0,0 +1,5 @@ +images: + controlPlane: + - name: ghcr.io/sovereigncloudstack/docker-ferrol-1-27-controlplaneamd64:v1 + worker: + - name: ghcr.io/sovereigncloudstack/docker-ferrol-1-27-workeramd64:v1 diff --git a/tests/cluster-stacks/docker/valencia/clusteraddon.yaml b/tests/cluster-stacks/docker/valencia/clusteraddon.yaml new file mode 100644 index 00000000..73f52404 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/clusteraddon.yaml @@ -0,0 +1,24 @@ +apiVersion: clusteraddonconfig.x-k8s.io/v1alpha1 +clusterAddonVersion: clusteraddons.clusterstack.x-k8s.io/v1alpha1 +addonStages: + AfterControlPlaneInitialized: + - name: cni + action: apply + - name: metrics-server + action: apply + BeforeClusterUpgrade: + - name: ngnix + action: apply + waitForPostCondition: + objects: + - key: msdeployment + apiVersion: apps/v1 + kind: Deployment + name: metrics-server + namespace: kube-system + - key: ngnix + apiVersion: apps/v1 + kind: Deployment + name: cluster-addon-ngnix + namespace: kube-system + conditions: msdeployment.spec.replicas == ngnix.spec.replicas diff --git a/tests/cluster-stacks/docker/valencia/csctl.yaml b/tests/cluster-stacks/docker/valencia/csctl.yaml new file mode 100644 index 00000000..7558d624 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/csctl.yaml @@ -0,0 +1,7 @@ +apiVersion: csctl.clusterstack.x-k8s.io/v1alpha1 +config: + kubernetesVersion: v1.27.6 + clusterStackName: valencia + provider: + type: docker + apiVersion: docker.csctl.clusterstack.x-k8s.io/v1alpha1 diff --git a/tests/cluster-stacks/docker/valencia/node-image/Dockerfile.controlplane b/tests/cluster-stacks/docker/valencia/node-image/Dockerfile.controlplane new file mode 100644 index 00000000..58930156 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/node-image/Dockerfile.controlplane @@ -0,0 +1,3 @@ +FROM kindest/node:v1.27.3 AS base +# This is an example. For a real infrastructure provider, you +# would have some scripts to create a custom machine image. \ No newline at end of file diff --git a/tests/cluster-stacks/docker/valencia/node-image/Dockerfile.worker b/tests/cluster-stacks/docker/valencia/node-image/Dockerfile.worker new file mode 100644 index 00000000..d2ce96d6 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/node-image/Dockerfile.worker @@ -0,0 +1,3 @@ +FROM kindest/node:v1.27.3 AS base +# This is an example. For a real infrastructure provider, you +# would have some scripts to create a custom machine image. diff --git a/tests/cluster-stacks/docker/valencia/node-image/scripts/base.sh b/tests/cluster-stacks/docker/valencia/node-image/scripts/base.sh new file mode 100755 index 00000000..f7493257 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/node-image/scripts/base.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2024 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +echo '--> Starting Base Installation.' +# Set locale +# localectl set-locale LANG=en_US.UTF-8 +# localectl set-locale LANGUAGE=en_US.UTF-8 + +# Suppress "WARNING: apt does not have a stable CLI interface. Use with caution in scripts." +echo 'Binary::apt::Apt::Cmd::Disable-Script-Warning "true";' >/etc/apt/apt.conf.d/disable-script-warning +export DEBIAN_FRONTEND=noninteractive + +# update all packages +apt update -y && apt -y upgrade && apt -y dist-upgrade + +# install basic tooling +apt -y install \ + at jq unzip wget socat mtr logrotate apt-transport-https network-manager + +# Install yq +YQ_VERSION=v4.30.5 #https://github.com/mikefarah/yq +YQ_BINARY=yq_linux_amd64 +wget -q https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BINARY} -O /usr/bin/yq && + chmod +x /usr/bin/yq + +echo '--> Starting Base Configuration.' + +## disable swap +sed -i '/swap/d' /etc/fstab diff --git a/tests/cluster-stacks/docker/valencia/node-images.yaml b/tests/cluster-stacks/docker/valencia/node-images.yaml new file mode 100644 index 00000000..b19d1b71 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/node-images.yaml @@ -0,0 +1,4 @@ +apiVersion: docker.infrastructure.clusterstack.x-k8s.io/v1alpha1 +dockerImages: + - controlplaneamd64 + - workeramd64 diff --git a/tests/cluster-stacks/docker/valencia/topology-docker.yaml b/tests/cluster-stacks/docker/valencia/topology-docker.yaml new file mode 100644 index 00000000..14883841 --- /dev/null +++ b/tests/cluster-stacks/docker/valencia/topology-docker.yaml @@ -0,0 +1,26 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Cluster +metadata: + name: "${CLUSTER_NAME}" + namespace: "${NAMESPACE}" +spec: + clusterNetwork: + services: + cidrBlocks: ["10.128.0.0/12"] + pods: + cidrBlocks: ["192.168.0.0/16"] + serviceDomain: "cluster.local" + topology: + class: docker-ferrol-1-27-v2 + controlPlane: + metadata: {} + replicas: 1 + variables: + - name: imageRepository + value: "" + version: v1.27.3 + workers: + machineDeployments: + - class: workeramd64 + name: md-0 + replicas: 1