From df2a2ed956767d17a0a08d38f7c8abc39541f708 Mon Sep 17 00:00:00 2001 From: lzy <674194901@qq.com> Date: Wed, 18 Dec 2024 17:39:10 +0800 Subject: [PATCH 1/3] refactor: change the way to obtain component version --- internal/cli/cmd/install/install.go | 5 +- internal/cli/cmd/update/update.go | 5 +- internal/cli/config/config.go | 120 +++++++++++++++++++++------- internal/cli/install/install.go | 11 ++- internal/cli/update/update.go | 11 ++- 5 files changed, 114 insertions(+), 38 deletions(-) diff --git a/internal/cli/cmd/install/install.go b/internal/cli/cmd/install/install.go index f8071195..c7b6229d 100644 --- a/internal/cli/cmd/install/install.go +++ b/internal/cli/cmd/install/install.go @@ -16,12 +16,11 @@ package install import ( "github.com/spf13/cobra" + "github.com/oceanbase/ob-operator/internal/cli/config" "github.com/oceanbase/ob-operator/internal/cli/install" "github.com/oceanbase/ob-operator/internal/cli/utils" ) -var componentList = []string{"ob-operator", "ob-dashboard", "local-path-provisioner", "cert-manager", "local-path-provisioner-dev", "ob-operator-dev"} - // NewCmd install the ob-operator and other components func NewCmd() *cobra.Command { o := install.NewInstallOptions() @@ -39,7 +38,7 @@ Currently support: if not specified, install ob-operator and ob-dashboard by default, and cert-manager if it is not found in cluster.`, PreRunE: o.Parse, - ValidArgs: componentList, + ValidArgs: config.ComponentList, Args: cobra.MatchAll(cobra.MaximumNArgs(1), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { diff --git a/internal/cli/cmd/update/update.go b/internal/cli/cmd/update/update.go index 08907c9d..505690d8 100644 --- a/internal/cli/cmd/update/update.go +++ b/internal/cli/cmd/update/update.go @@ -16,12 +16,11 @@ package update import ( "github.com/spf13/cobra" + "github.com/oceanbase/ob-operator/internal/cli/config" "github.com/oceanbase/ob-operator/internal/cli/update" "github.com/oceanbase/ob-operator/internal/cli/utils" ) -var componentList = []string{"ob-operator", "ob-dashboard", "local-path-provisioner", "cert-manager"} - // NewCmd update the ob-operator and other components func NewCmd() *cobra.Command { o := update.NewUpdateOptions() @@ -39,7 +38,7 @@ Currently support: if not specified, update ob-operator and ob-dashboard by default`, PreRunE: o.Parse, - ValidArgs: componentList, + ValidArgs: config.ComponentUpdateList, DisableFlagsInUseLine: true, Args: cobra.MatchAll(cobra.MaximumNArgs(1), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index 22a0cca3..e47ca0ff 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -14,53 +14,117 @@ See the Mulan PSL v2 for more details. package config import ( - "bytes" - "fmt" + "errors" + "io" + "net/http" - "github.com/spf13/viper" + "gopkg.in/yaml.v2" - "github.com/oceanbase/ob-operator/internal/cli/generated/bindata" "github.com/oceanbase/ob-operator/internal/cli/utils" ) -// component config for test -var confPath = "internal/assets/cli-templates/component_config.yaml" +// Chart struct to parse the chart.yaml +type Chart struct { + apiVersion string `yaml:"apiVersion"` + AppVersion string `yaml:"appVersion"` + description string `yaml:"description"` + name string `yaml:"name"` + chartType string `yaml:"type"` + version string `yaml:"version"` +} -func readComponentConf(path string) map[string]string { - components := make(map[string]string) - fileobj, err := bindata.Asset(path) - // panic if file not exists +const ( + stableVersion = "stable" + devVersion = "master" +) + +// ComponentList is the list of components that can be installed +var ComponentList = []string{ + "cert-manager", "ob-operator", "ob-dashboard", "local-path-provisioner", "local-path-provisioner-dev", "ob-operator-dev", +} + +// ComponentUpdateList is the list of components that can be updated +var ComponentUpdateList = []string{ + "cert-manager", "ob-operator", "ob-dashboard", "local-path-provisioner", +} + +var versionURLs = map[string]string{ + "ob-dashboard": "https://raw.githubusercontent.com/oceanbase/ob-operator/refs/heads/stable/charts/oceanbase-dashboard/Chart.yaml", + "local-path-provisioner": "https://raw.githubusercontent.com/rancher/local-path-provisioner/refs/tags/v0.0.30/deploy/chart/local-path-provisioner/Chart.yaml", +} + +func getVersionFromChart(component string) (string, error) { + url, ok := versionURLs[component] + if !ok { + return "", errors.New("url not found for the component") + } + + // get the yaml + resp, err := http.Get(url) if err != nil { - panic(fmt.Errorf("Error reading component config file: %v", err)) + return "", err } - viper.SetConfigType("yaml") - err = viper.ReadConfig(bytes.NewBuffer(fileobj)) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", errors.New("failed to fetch chart: " + resp.Status) + } + + // parse the yaml + body, err := io.ReadAll(resp.Body) if err != nil { - panic(fmt.Errorf("Read Config err:%v", err)) + return "", err } - if err := viper.UnmarshalKey("components", &components); err != nil { - panic(fmt.Errorf("Error decoding component config file: %v", err)) + var chart Chart + err = yaml.Unmarshal(body, &chart) + if err != nil { + return "", err + } + + return chart.AppVersion, nil +} + +func getVersion(component string) (string, error) { + switch component { + case "ob-dashboard", "local-path-provisioner": + return getVersionFromChart(component) + case "cert-manager", "ob-operator": + return stableVersion, nil + case "ob-operator-dev", "local-path-provisioner-dev": + return devVersion, nil + default: + return "", errors.New("version not found for the component") } - return components } // GetAllComponents returns all the components -func GetAllComponents() map[string]string { - return readComponentConf(confPath) +func GetAllComponents() (map[string]string, error) { + components := make(map[string]string) + for _, component := range ComponentList { + version, err := getVersion(component) + if err != nil { + return nil, err + } + components[component] = version + } + return components, nil } -// GetDefaultComponents returns the default components to be installed -func GetDefaultComponents() map[string]string { - var componentsList []string - components := GetAllComponents() - defaultComponents := make(map[string]string) // Initialize the map +// GetDefaultComponents returns the default components to be installed if not specified +func GetDefaultComponents() (map[string]string, error) { + var installList []string + components, err := GetAllComponents() + if err != nil { + return nil, err + } + defaultComponents := make(map[string]string) if !utils.CheckIfComponentExists("cert-manager") { - componentsList = []string{"cert-manager", "ob-operator", "ob-dashboard"} + installList = []string{"cert-manager", "ob-operator", "ob-dashboard"} } else { - componentsList = []string{"ob-operator", "ob-dashboard"} + installList = []string{"ob-operator", "ob-dashboard"} } - for _, component := range componentsList { + for _, component := range installList { defaultComponents[component] = components[component] } - return defaultComponents + return defaultComponents, nil } diff --git a/internal/cli/install/install.go b/internal/cli/install/install.go index fcf09ce4..0e13fad6 100644 --- a/internal/cli/install/install.go +++ b/internal/cli/install/install.go @@ -38,7 +38,11 @@ func (o *InstallOptions) Parse(_ *cobra.Command, args []string) error { // if specified, use the specified component if len(args) > 0 { name := args[0] - components := config.GetAllComponents() + components, err := config.GetAllComponents() + if err != nil { + return err + } + // check if the component is supported defaultVersion, exist := components[name] if !exist { @@ -53,7 +57,10 @@ func (o *InstallOptions) Parse(_ *cobra.Command, args []string) error { } } else { // if no component is specified, install default components - defaultComponents := config.GetDefaultComponents() + defaultComponents, err := config.GetDefaultComponents() + if err != nil { + return err + } o.Components = defaultComponents } return nil diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index 9e23edd4..05d91d83 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -37,7 +37,11 @@ func (o *UpdateOptions) Parse(_ *cobra.Command, args []string) error { // if specified, use the specified component if len(args) > 0 { name := args[0] - components := config.GetAllComponents() + components, err := config.GetAllComponents() + if err != nil { + return err + } + // check if the component is supported defaultVersion, exist := components[name] if !exist { @@ -46,7 +50,10 @@ func (o *UpdateOptions) Parse(_ *cobra.Command, args []string) error { o.Components = map[string]string{name: defaultVersion} } else { // if no component is specified, update default components - defaultComponents := config.GetDefaultComponents() + defaultComponents, err := config.GetDefaultComponents() + if err != nil { + return err + } o.Components = defaultComponents } return nil From 3926c5131782625198c892b459b28eb5d0693cc0 Mon Sep 17 00:00:00 2001 From: lzy <674194901@qq.com> Date: Thu, 19 Dec 2024 20:31:33 +0800 Subject: [PATCH 2/3] delete local-path-provisioner dev version support --- internal/cli/cmd/install/install.go | 2 +- internal/cli/cmd/update/update.go | 2 +- internal/cli/config/config.go | 4 ++-- internal/cli/utils/cmd_runner.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/cli/cmd/install/install.go b/internal/cli/cmd/install/install.go index c7b6229d..24de769d 100644 --- a/internal/cli/cmd/install/install.go +++ b/internal/cli/cmd/install/install.go @@ -33,7 +33,7 @@ func NewCmd() *cobra.Command { Currently support: - ob-operator: A Kubernetes operator that simplifies the deployment and management of OceanBase cluster and related resources on Kubernetes, support stable and develop version. - ob-dashboard: A web application that provides resource management capabilities. -- local-path-provisioner: Provides a way for the Kubernetes users to utilize the local storage in each node, Storage of OceanBase cluster relies on it, which should be installed beforehand, support stable and develop version. +- local-path-provisioner: Provides a way for the Kubernetes users to utilize the local storage in each node, Storage of OceanBase cluster relies on it, which should be installed beforehand. - cert-manager: Creates TLS certificates for workloads in Kubernetes and renews the certificates before they expire, ob-operator relies on it for certificate management, which should be installed beforehand. if not specified, install ob-operator and ob-dashboard by default, and cert-manager if it is not found in cluster.`, diff --git a/internal/cli/cmd/update/update.go b/internal/cli/cmd/update/update.go index 505690d8..dca6d907 100644 --- a/internal/cli/cmd/update/update.go +++ b/internal/cli/cmd/update/update.go @@ -33,7 +33,7 @@ func NewCmd() *cobra.Command { Currently support: - ob-operator: A Kubernetes operator that simplifies the deployment and management of OceanBase cluster and related resources on Kubernetes, support stable and develop version. - ob-dashboard: A web application that provides resource management capabilities. -- local-path-provisioner: Provides a way for the Kubernetes users to utilize the local storage in each node, Storage of OceanBase cluster relies on it, which should be installed beforehand, support stable and develop version. +- local-path-provisioner: Provides a way for the Kubernetes users to utilize the local storage in each node, Storage of OceanBase cluster relies on it, which should be installed beforehand. - cert-manager: Creates TLS certificates for workloads in Kubernetes and renews the certificates before they expire, ob-operator relies on it for certificate management, which should be installed beforehand. if not specified, update ob-operator and ob-dashboard by default`, diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index e47ca0ff..1fc876d8 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -40,7 +40,7 @@ const ( // ComponentList is the list of components that can be installed var ComponentList = []string{ - "cert-manager", "ob-operator", "ob-dashboard", "local-path-provisioner", "local-path-provisioner-dev", "ob-operator-dev", + "cert-manager", "ob-operator", "ob-dashboard", "local-path-provisioner", "ob-operator-dev", } // ComponentUpdateList is the list of components that can be updated @@ -90,7 +90,7 @@ func getVersion(component string) (string, error) { return getVersionFromChart(component) case "cert-manager", "ob-operator": return stableVersion, nil - case "ob-operator-dev", "local-path-provisioner-dev": + case "ob-operator-dev": return devVersion, nil default: return "", errors.New("version not found for the component") diff --git a/internal/cli/utils/cmd_runner.go b/internal/cli/utils/cmd_runner.go index 85ab4d8b..6453ce54 100644 --- a/internal/cli/utils/cmd_runner.go +++ b/internal/cli/utils/cmd_runner.go @@ -66,7 +66,7 @@ func BuildCmd(component, version string) (*exec.Cmd, error) { componentFile := "operator.yaml" url := fmt.Sprintf("%s%s/deploy/%s", obURL, version, componentFile) cmd = exec.Command("kubectl", "apply", "-f", url) - case "local-path-provisioner", "local-path-provisioner-dev": + case "local-path-provisioner": componentFile := "local-path-storage.yaml" url := fmt.Sprintf("%s%s/deploy/%s", localPathURL, version, componentFile) cmd = exec.Command("kubectl", "apply", "-f", url) From cbfa6aa361f1c10042a2a1a0a10072b2ba559e13 Mon Sep 17 00:00:00 2001 From: lzy <674194901@qq.com> Date: Thu, 19 Dec 2024 20:42:06 +0800 Subject: [PATCH 3/3] remove `cli-bindata-gen` from ci and makefile --- .github/workflows/build.yml | 2 +- .github/workflows/ci-tests.yml | 2 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/release-cli.yml | 2 +- make/build.mk | 2 +- make/cli.mk | 6 +----- make/helper.mk | 2 +- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 714246e7..799e2cda 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: generate bindata - run: make dashboard-bindata-gen dashboard-doc-gen cli-bindata-gen + run: make dashboard-bindata-gen dashboard-doc-gen - name: go mod vendor run: go mod vendor diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index c2733832..9df2a896 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -31,7 +31,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: generate bindata - run: make dashboard-bindata-gen cli-bindata-gen dashboard-doc-gen + run: make dashboard-bindata-gen dashboard-doc-gen - name: go mod vendor run: go mod vendor diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 1e8de775..292007d9 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -24,7 +24,7 @@ jobs: cache: true - name: generate bindata - run: make dashboard-bindata-gen dashboard-doc-gen cli-bindata-gen + run: make dashboard-bindata-gen dashboard-doc-gen - name: golangci-lint uses: golangci/golangci-lint-action@v3 diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index ab1ea75e..18b1787a 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -28,7 +28,7 @@ jobs: go-version: ${{ env.GO_VERSION }} # The Go version to download (if necessary) and use. - name: generate bindata - run: make dashboard-bindata-gen dashboard-doc-gen cli-bindata-gen + run: make dashboard-bindata-gen dashboard-doc-gen - name: go mod vendor run: go mod vendor diff --git a/make/build.mk b/make/build.mk index 043effae..eb518d79 100644 --- a/make/build.mk +++ b/make/build.mk @@ -1,7 +1,7 @@ ##@ Build .PHONY: build -build: dashboard-doc-gen dashboard-bindata-gen cli-bindata-gen manifests generate fmt vet ## Build manager binary. +build: dashboard-doc-gen dashboard-bindata-gen manifests generate fmt vet ## Build manager binary. CGO_ENABLED=0 GOOS=linux go build -o bin/manager cmd/operator/main.go # If you wish built the manager image targeting other platforms you can use the --platform flag. diff --git a/make/cli.mk b/make/cli.mk index 5d916159..3dbaeabe 100644 --- a/make/cli.mk +++ b/make/cli.mk @@ -27,14 +27,10 @@ CLI_BUILD := GO11MODULE=ON CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build BUILD_DIR?=bin/ .PHONY: cli-build -cli-build: cli-bindata-gen dashboard-doc-gen dashboard-bindata-gen ## Build oceanbase-cli +cli-build: ## Build oceanbase-cli @echo "Building $(BINARY_NAME) for $(GOOS)/$(GOARCH)..." $(CLI_BUILD) -o $(BUILD_DIR)$(BINARY_NAME) cmd/cli/main.go -.PHONY: cli-bindata-gen -cli-bindata-gen: cli-dep-install ## Generate bindata - go-bindata -o internal/cli/generated/bindata/bindata.go -pkg bindata internal/assets/cli-templates/... - .PHONY: cli-clean cli-clean: ## Clean build rm -rf $(RELEASE_DIR)/$(BINARY_NAME) diff --git a/make/helper.mk b/make/helper.mk index e4b214d4..d9f315d3 100644 --- a/make/helper.mk +++ b/make/helper.mk @@ -1,6 +1,6 @@ ##@ Helper .PHONY: helper-build -helper-build: dashboard-bindata-gen dashboard-doc-gen cli-bindata-gen ## Build oceanbase helper binary. +helper-build: dashboard-bindata-gen dashboard-doc-gen ## Build oceanbase helper binary. @echo "Building helper..." CGO_ENABLED=0 GOOS=linux go build -a -o bin/oceanbase-helper ./cmd/oceanbase-helper/main.go \ No newline at end of file