diff --git a/pkg/cmd/gtctl/cluster/create/create.go b/pkg/cmd/gtctl/cluster/create/create.go index b3f9b778..a226cb04 100644 --- a/pkg/cmd/gtctl/cluster/create/create.go +++ b/pkg/cmd/gtctl/cluster/create/create.go @@ -64,6 +64,10 @@ type ClusterCliOptions struct { Timeout int DryRun bool Set configValues + + // If UseGreptimeCNArtifacts is true, the creation will download the artifacts(charts and binaries) from 'downloads.greptime.cn'. + // Also, it will use ACR registry for charts images. + UseGreptimeCNArtifacts bool } func NewCreateClusterCommand(l logger.Logger) *cobra.Command { @@ -102,6 +106,7 @@ func NewCreateClusterCommand(l logger.Logger) *cobra.Command { cmd.Flags().StringVar(&options.Config, "config", "", "Configuration to deploy the greptimedb cluster on bare-metal environment.") cmd.Flags().BoolVar(&options.AlwaysDownload, "always-download", false, "If true, always download the binary.") cmd.Flags().BoolVar(&options.RetainLogs, "retain-logs", true, "If true, always retain the logs of binary.") + cmd.Flags().BoolVar(&options.UseGreptimeCNArtifacts, "use-greptime-cn-artifacts", false, "If true, use greptime-cn artifacts(charts and binaries).") return cmd } @@ -234,6 +239,7 @@ func deployGreptimeDBOperator(ctx context.Context, l logger.Logger, options *Clu GreptimeDBOperatorChartVersion: options.GreptimeDBOperatorChartVersion, ImageRegistry: options.ImageRegistry, ConfigValues: options.Set.operatorConfig, + UseGreptimeCNArtifacts: options.UseGreptimeCNArtifacts, } name := types.NamespacedName{Namespace: options.OperatorNamespace, Name: "greptimedb-operator"}.String() @@ -257,12 +263,13 @@ func deployEtcdCluster(ctx context.Context, l logger.Logger, options *ClusterCli } createEtcdClusterOptions := &deployer.CreateEtcdClusterOptions{ - ImageRegistry: options.ImageRegistry, - EtcdChartVersion: options.EtcdChartVersion, - EtcdStorageClassName: options.EtcdStorageClassName, - EtcdStorageSize: options.EtcdStorageSize, - EtcdClusterSize: options.EtcdClusterSize, - ConfigValues: options.Set.etcdConfig, + ImageRegistry: options.ImageRegistry, + EtcdChartVersion: options.EtcdChartVersion, + EtcdStorageClassName: options.EtcdStorageClassName, + EtcdStorageSize: options.EtcdStorageSize, + EtcdClusterSize: options.EtcdClusterSize, + ConfigValues: options.Set.etcdConfig, + UseGreptimeCNArtifacts: options.UseGreptimeCNArtifacts, } var name string @@ -300,6 +307,7 @@ func deployGreptimeDBCluster(ctx context.Context, l logger.Logger, options *Clus DatanodeStorageRetainPolicy: options.StorageRetainPolicy, EtcdEndPoint: fmt.Sprintf("%s.%s:2379", common.EtcdClusterName(clusterName), options.EtcdNamespace), ConfigValues: options.Set.clusterConfig, + UseGreptimeCNArtifacts: options.UseGreptimeCNArtifacts, } var name string diff --git a/pkg/deployer/k8s/deployer.go b/pkg/deployer/k8s/deployer.go index 371cc295..17710646 100644 --- a/pkg/deployer/k8s/deployer.go +++ b/pkg/deployer/k8s/deployer.go @@ -36,6 +36,10 @@ type deployer struct { dryRun bool } +const ( + AliCloudRegistry = "greptime-registry.cn-hangzhou.cr.aliyuncs.com" +) + var _ Interface = &deployer{} type Option func(*deployer) @@ -118,7 +122,11 @@ func (d *deployer) CreateGreptimeDBCluster(ctx context.Context, name string, opt return err } - manifests, err := d.helmManager.LoadAndRenderChart(ctx, resourceName, resourceNamespace, helm.GreptimeDBChartName, options.GreptimeDBChartVersion, *options) + if options.UseGreptimeCNArtifacts && options.ImageRegistry == "" { + options.ConfigValues += fmt.Sprintf("image.registry=%s,initializer.registry=%s,", AliCloudRegistry, AliCloudRegistry) + } + + manifests, err := d.helmManager.LoadAndRenderChart(ctx, resourceName, resourceNamespace, helm.GreptimeDBChartName, options.GreptimeDBChartVersion, options.UseGreptimeCNArtifacts, *options) if err != nil { return err } @@ -169,11 +177,15 @@ func (d *deployer) CreateEtcdCluster(ctx context.Context, name string, options * // TODO(zyy17): Maybe we can set this in the top level configures. const ( - disableRBACConfig = "auth.rbac.create=false,auth.rbac.token.enabled=false" + disableRBACConfig = "auth.rbac.create=false,auth.rbac.token.enabled=false," ) options.ConfigValues += disableRBACConfig - manifests, err := d.helmManager.LoadAndRenderChart(ctx, resourceName, resourceNamespace, helm.EtcdBitnamiOCIRegistry, helm.DefaultEtcdChartVersion, *options) + if options.UseGreptimeCNArtifacts && options.ImageRegistry == "" { + options.ConfigValues += fmt.Sprintf("image.registry=%s,", AliCloudRegistry) + } + + manifests, err := d.helmManager.LoadAndRenderChart(ctx, resourceName, resourceNamespace, helm.EtcdBitnamiOCIRegistry, helm.DefaultEtcdChartVersion, options.UseGreptimeCNArtifacts, *options) if err != nil { return fmt.Errorf("error while loading helm chart: %v", err) } @@ -205,7 +217,11 @@ func (d *deployer) CreateGreptimeDBOperator(ctx context.Context, name string, op return err } - manifests, err := d.helmManager.LoadAndRenderChart(ctx, resourceName, resourceNamespace, helm.GreptimeDBOperatorChartName, options.GreptimeDBOperatorChartVersion, *options) + if options.UseGreptimeCNArtifacts && options.ImageRegistry == "" { + options.ConfigValues += fmt.Sprintf("image.registry=%s,", AliCloudRegistry) + } + + manifests, err := d.helmManager.LoadAndRenderChart(ctx, resourceName, resourceNamespace, helm.GreptimeDBOperatorChartName, options.GreptimeDBOperatorChartVersion, options.UseGreptimeCNArtifacts, *options) if err != nil { return err } diff --git a/pkg/deployer/types.go b/pkg/deployer/types.go index 8120b159..e190b16f 100644 --- a/pkg/deployer/types.go +++ b/pkg/deployer/types.go @@ -69,6 +69,7 @@ type ListGreptimeDBClustersOptions struct{} // CreateGreptimeDBClusterOptions is the options to create a GreptimeDB cluster. type CreateGreptimeDBClusterOptions struct { GreptimeDBChartVersion string + UseGreptimeCNArtifacts bool ImageRegistry string `helm:"image.registry"` InitializerImageRegistry string `helm:"initializer.registry"` @@ -89,7 +90,8 @@ type DeleteGreptimeDBClusterOption struct{} // CreateEtcdClusterOptions is the options to create an etcd cluster. type CreateEtcdClusterOptions struct { - EtcdChartVersion string + EtcdChartVersion string + UseGreptimeCNArtifacts bool // The parameters reference: https://artifacthub.io/packages/helm/bitnami/etcd. EtcdClusterSize string `helm:"replicaCount"` @@ -105,6 +107,7 @@ type DeleteEtcdClusterOption struct{} // CreateGreptimeDBOperatorOptions is the options to create a GreptimeDB operator. type CreateGreptimeDBOperatorOptions struct { GreptimeDBOperatorChartVersion string + UseGreptimeCNArtifacts bool ImageRegistry string `helm:"image.registry"` ConfigValues string `helm:"*"` diff --git a/pkg/helm/constants.go b/pkg/helm/constants.go index 461336f5..a4b676b3 100644 --- a/pkg/helm/constants.go +++ b/pkg/helm/constants.go @@ -19,6 +19,7 @@ const ( GreptimeChartIndexURL = "https://raw.githubusercontent.com/GreptimeTeam/helm-charts/gh-pages/index.yaml" GreptimeChartReleaseDownloadURL = "https://github.com/GreptimeTeam/helm-charts/releases/download" + GreptimeCNCharts = "https://downloads.greptime.cn/releases/charts" GreptimeDBChartName = "greptimedb" GreptimeDBOperatorChartName = "greptimedb-operator" diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go index 78cc3b0c..ad6734e2 100644 --- a/pkg/helm/helm.go +++ b/pkg/helm/helm.go @@ -90,7 +90,7 @@ func WithChartsCacheDir(chartsCacheDir string) func(*Manager) { } // LoadAndRenderChart loads the chart from the remote charts and render the manifests with the values. -func (r *Manager) LoadAndRenderChart(ctx context.Context, name, namespace, chartName, chartVersion string, options interface{}) ([]byte, error) { +func (r *Manager) LoadAndRenderChart(ctx context.Context, name, namespace, chartName, chartVersion string, useGreptimeCNArtifacts bool, options interface{}) ([]byte, error) { values, err := r.generateHelmValues(options) if err != nil { return nil, err @@ -104,11 +104,17 @@ func (r *Manager) LoadAndRenderChart(ctx context.Context, name, namespace, chart return nil, err } } else { - downloadURL, err := r.getChartDownloadURL(ctx, chartName, chartVersion) + downloadURL, err := r.getChartDownloadURL(ctx, chartName, chartVersion, useGreptimeCNArtifacts) if err != nil { return nil, err } - helmChart, err = r.loadChartFromRemoteCharts(ctx, downloadURL) + + alwaysDownload := false + if chartVersion == "" { // always download the latest version. + alwaysDownload = true + } + + helmChart, err = r.loadChartFromRemoteCharts(ctx, downloadURL, alwaysDownload) if err != nil { return nil, err } @@ -123,7 +129,7 @@ func (r *Manager) LoadAndRenderChart(ctx context.Context, name, namespace, chart return manifests, nil } -func (r *Manager) loadChartFromRemoteCharts(ctx context.Context, downloadURL string) (*chart.Chart, error) { +func (r *Manager) loadChartFromRemoteCharts(ctx context.Context, downloadURL string, alwaysDownload bool) (*chart.Chart, error) { parsedURL, err := url.Parse(downloadURL) if err != nil { return nil, err @@ -134,7 +140,7 @@ func (r *Manager) loadChartFromRemoteCharts(ctx context.Context, downloadURL str cachePath = filepath.Join(r.chartsCacheDir, packageName) ) - if r.isInChartsCache(packageName) { + if !alwaysDownload && r.isInChartsCache(packageName) { data, err := os.ReadFile(cachePath) if err != nil { return nil, err @@ -323,29 +329,42 @@ func (r *Manager) newHelmClient(releaseName, namespace string) (*action.Install, return helmClient, nil } -func (r *Manager) getChartDownloadURL(ctx context.Context, chartName, version string) (string, error) { - indexFile, err := r.getIndexFile(ctx, GreptimeChartIndexURL) - if err != nil { - return "", err - } +func (r *Manager) getChartDownloadURL(ctx context.Context, chartName, version string, useGreptimeCNArtifacts bool) (string, error) { + // Get the latest version from index file of GitHub repo. + if !useGreptimeCNArtifacts && version == "" { + indexFile, err := r.getIndexFile(ctx, GreptimeChartIndexURL) + if err != nil { + return "", err + } - var downloadURL string - if version == "" { chartVersion, err := r.getLatestChart(indexFile, chartName) if err != nil { return "", err } - downloadURL = chartVersion.URLs[0] + + downloadURL := chartVersion.URLs[0] r.logger.V(3).Infof("get latest chart '%s', version '%s', url: '%s'", chartName, chartVersion.Version, downloadURL) - } else { - // The download URL example: 'https://github.com/GreptimeTeam/helm-charts/releases/download/greptimedb-0.1.1-alpha.3/greptimedb-0.1.1-alpha.3.tgz'. - chartName := chartName + "-" + version - downloadURL = fmt.Sprintf("%s/%s/%s.tgz", GreptimeChartReleaseDownloadURL, chartName, chartName) + return downloadURL, nil + } + + if useGreptimeCNArtifacts { + if version == "" { + version = "latest" + } + + // The download URL example: 'https://downloads.greptime.cn/releases/charts/etcd/9.2.0/etcd-9.2.0.tgz'. + downloadURL := fmt.Sprintf("%s/%s/%s/%s.tgz", GreptimeCNCharts, chartName, version, chartName+"-"+version) r.logger.V(3).Infof("get given version chart '%s', version '%s', url: '%s'", chartName, version, downloadURL) + return downloadURL, nil } + // The download URL example: 'https://github.com/GreptimeTeam/helm-charts/releases/download/greptimedb-0.1.1-alpha.3/greptimedb-0.1.1-alpha.3.tgz'. + downloadURL := fmt.Sprintf("%s/%s/%s.tgz", GreptimeChartReleaseDownloadURL, chartName, chartName+"-"+version) + r.logger.V(3).Infof("get given version chart '%s', version '%s', url: '%s'", + chartName, version, downloadURL) + return downloadURL, nil } diff --git a/pkg/helm/helm_test.go b/pkg/helm/helm_test.go index 611adacb..eae50e5d 100644 --- a/pkg/helm/helm_test.go +++ b/pkg/helm/helm_test.go @@ -76,7 +76,7 @@ func TestLoadAndRenderChart(t *testing.T) { ctx := context.Background() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - manifests, err := r.LoadAndRenderChart(ctx, tt.name, tt.namespace, tt.chartName, tt.chartVersion, tt.values) + manifests, err := r.LoadAndRenderChart(ctx, tt.name, tt.namespace, tt.chartName, tt.chartVersion, false, tt.values) if err != nil { t.Errorf("failed to load and render chart: %v", err) }