diff --git a/pkg/clusterstack/mode.go b/pkg/clusterstack/mode.go index 84c27156..d3b9402b 100644 --- a/pkg/clusterstack/mode.go +++ b/pkg/clusterstack/mode.go @@ -19,6 +19,7 @@ package clusterstack import ( "fmt" + "github.com/SovereignCloudStack/cluster-stack-operator/pkg/version" "github.com/SovereignCloudStack/csctl/pkg/git" "github.com/SovereignCloudStack/csctl/pkg/hash" ) @@ -84,3 +85,28 @@ func HandleHashMode(kubernetesVersion string) (MetaData, error) { }, }, nil } + +// HandleCustomMode handles custom mode with version for all components. +func HandleCustomMode(kubernetesVersion, clusterStackVersion, clusterAddonVersion, nodeImageVersion string) (MetaData, error) { + if _, err := version.New(clusterStackVersion); err != nil { + return MetaData{}, fmt.Errorf("failed to verify custom version for cluster stack: %q: %w", clusterStackVersion, err) + } + if _, err := version.New(clusterAddonVersion); err != nil { + return MetaData{}, fmt.Errorf("failed to verify custom version for cluster addon: %q: %w", clusterAddonVersion, err) + } + if _, err := version.New(nodeImageVersion); err != nil { + return MetaData{}, fmt.Errorf("failed to verify custom version for node image: %q: %w", nodeImageVersion, err) + } + + return MetaData{ + APIVersion: "metadata.clusterstack.x-k8s.io/v1alpha1", + Versions: Versions{ + Kubernetes: kubernetesVersion, + ClusterStack: clusterStackVersion, + Components: Component{ + ClusterAddon: clusterAddonVersion, + NodeImage: nodeImageVersion, + }, + }, + }, nil +} diff --git a/pkg/cmd/create.go b/pkg/cmd/create.go index b0fa9649..c63eba5d 100644 --- a/pkg/cmd/create.go +++ b/pkg/cmd/create.go @@ -36,6 +36,7 @@ import ( const ( stableMode = "stable" hashMode = "hash" + customMode = "custom" ) var ( @@ -51,9 +52,12 @@ var ( ) var ( - mode string - outputDirectory string - nodeImageRegistry string + mode string + outputDirectory string + nodeImageRegistry string + clusterStackVersion string + clusterAddonVersion string + nodeImageVersion string ) // CreateOptions contains config for creating a release. @@ -81,6 +85,9 @@ func init() { createCmd.Flags().StringVarP(&mode, "mode", "m", "stable", "It defines the mode of the cluster stack manager") createCmd.Flags().StringVarP(&outputDirectory, "output", "o", "./.release", "It defines the output directory in which the release artifacts will be generated") createCmd.Flags().StringVarP(&nodeImageRegistry, "node-image-registry", "r", "", "It defines the node image registry. For example oci://ghcr.io/foo/bar/node-images/staging/") + createCmd.Flags().StringVar(&clusterStackVersion, "cluster-stack-version", "", "It is used to specify the semver version for the cluster stack in the custom mode") + createCmd.Flags().StringVar(&clusterAddonVersion, "cluster-addon-version", "", "It is used to specify the semver version for the cluster addon in the custom mode") + createCmd.Flags().StringVar(&nodeImageVersion, "node-image-version", "", "It is used to specify the semver version for the node images in the custom mode") } // GetCreateOptions create a Create Option for create command. @@ -142,6 +149,21 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti return nil, fmt.Errorf("failed to handle stable mode: %w", err) } } + case customMode: + if clusterStackVersion == "" { + return nil, fmt.Errorf("please specify a semver for custom version with --cluster-stack-version flag") + } + if clusterAddonVersion == "" { + return nil, fmt.Errorf("please specify a semver for custom version with --cluster-addon-version flag") + } + if nodeImageVersion == "" { + return nil, fmt.Errorf("please specify a semver for custom version with --node-image-version flag") + } + + createOption.Metadata, err = clusterstack.HandleCustomMode(createOption.Config.Config.KubernetesVersion, clusterStackVersion, clusterAddonVersion, nodeImageVersion) + if err != nil { + return nil, fmt.Errorf("failed to handle custom mode: %w", err) + } } releaseDirName, err := clusterstack.GetClusterStackReleaseDirectoryName(&createOption.Metadata, &createOption.Config) @@ -164,9 +186,8 @@ func createAction(cmd *cobra.Command, args []string) error { } clusterStackPath := args[0] - if mode != stableMode && mode != hashMode { - fmt.Println("The mode is ", mode) - return fmt.Errorf("mode is not supported please choose from - stable, hash") + if mode != stableMode && mode != hashMode && mode != customMode { + return fmt.Errorf("mode %q is not supported please choose from - stable, hash or custom", mode) } createOpts, err := GetCreateOptions(cmd.Context(), clusterStackPath)