Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: change the way to obtain component version #680

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 3 additions & 4 deletions internal/cli/cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -34,12 +33,12 @@ 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.`,
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 {
Expand Down
7 changes: 3 additions & 4 deletions internal/cli/cmd/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -34,12 +33,12 @@ 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`,
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) {
Expand Down
120 changes: 92 additions & 28 deletions internal/cli/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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", "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",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should use master branch here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I see, the chart in the master branch is always of the stable version. The stable and dev are used to describe the status of deploy/local-path-storage.yaml, I thought.

}

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":
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
}
11 changes: 9 additions & 2 deletions internal/cli/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
11 changes: 9 additions & 2 deletions internal/cli/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/utils/cmd_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion make/build.mk
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
6 changes: 1 addition & 5 deletions make/cli.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion make/helper.mk
Original file line number Diff line number Diff line change
@@ -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
Loading