From c077e15192006842b3739d6e4d219f8335da998d Mon Sep 17 00:00:00 2001 From: nexustar Date: Thu, 24 Aug 2023 19:06:51 +0800 Subject: [PATCH] cluster: support use different component versions --- components/cluster/command/upgrade.go | 27 ++++++++- components/dm/command/upgrade.go | 2 +- pkg/cluster/manager/builder.go | 11 ++-- pkg/cluster/manager/check.go | 2 +- pkg/cluster/manager/deploy.go | 4 +- pkg/cluster/manager/upgrade.go | 87 ++++++++++++++++++++++----- pkg/cluster/spec/alertmanager.go | 9 ++- pkg/cluster/spec/bindversion.go | 1 - pkg/cluster/spec/cdc.go | 12 ++-- pkg/cluster/spec/dashboard.go | 2 +- pkg/cluster/spec/drainer.go | 3 +- pkg/cluster/spec/grafana.go | 1 + pkg/cluster/spec/instance.go | 24 +++++++- pkg/cluster/spec/monitoring.go | 3 +- pkg/cluster/spec/pd.go | 4 +- pkg/cluster/spec/pump.go | 1 + pkg/cluster/spec/server_config.go | 14 ++--- pkg/cluster/spec/spec.go | 16 ++--- pkg/cluster/spec/tidb.go | 6 +- pkg/cluster/spec/tiflash.go | 22 ++++--- pkg/cluster/spec/tikv.go | 3 +- pkg/cluster/spec/tikv_cdc.go | 6 ++ pkg/cluster/task/builder.go | 10 +-- 23 files changed, 199 insertions(+), 71 deletions(-) diff --git a/components/cluster/command/upgrade.go b/components/cluster/command/upgrade.go index 2afe973a07..3fc36fa98e 100644 --- a/components/cluster/command/upgrade.go +++ b/components/cluster/command/upgrade.go @@ -14,12 +14,14 @@ package command import ( + "github.com/pingcap/tiup/pkg/cluster/spec" "github.com/pingcap/tiup/pkg/utils" "github.com/spf13/cobra" ) func newUpgradeCmd() *cobra.Command { offlineMode := false + var tidbVer, tikvVer, pdVer, tiflashVer, kvcdcVer, dashboardVer, cdcVer, alertmanagerVer, nodeExporterVer, blackboxExporterVer string cmd := &cobra.Command{ Use: "upgrade ", @@ -38,7 +40,20 @@ func newUpgradeCmd() *cobra.Command { teleCommand = append(teleCommand, scrubClusterName(clusterName)) teleCommand = append(teleCommand, version) - return cm.Upgrade(clusterName, version, gOpt, skipConfirm, offlineMode) + componentVersions := map[string]string{ + spec.ComponentDashboard: dashboardVer, + spec.ComponentAlertmanager: alertmanagerVer, + spec.ComponentTiDB: tidbVer, + spec.ComponentTiKV: tikvVer, + spec.ComponentPD: pdVer, + spec.ComponentTiFlash: tiflashVer, + spec.ComponentTiKVCDC: kvcdcVer, + spec.ComponentCDC: cdcVer, + spec.ComponentBlackboxExporter: blackboxExporterVer, + spec.ComponentNodeExporter: nodeExporterVer, + } + + return cm.Upgrade(clusterName, version, componentVersions, gOpt, skipConfirm, offlineMode) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { switch len(args) { @@ -56,5 +71,15 @@ func newUpgradeCmd() *cobra.Command { cmd.Flags().StringVar(&gOpt.SSHCustomScripts.BeforeRestartInstance.Raw, "pre-upgrade-script", "", "(EXPERIMENTAL) Custom script to be executed on each server before the server is upgraded") cmd.Flags().StringVar(&gOpt.SSHCustomScripts.AfterRestartInstance.Raw, "post-upgrade-script", "", "(EXPERIMENTAL) Custom script to be executed on each server after the server is upgraded") + cmd.Flags().StringVar(&tidbVer, "tidb-version", "", "Specify the version of tidb to upgrade to") + cmd.Flags().StringVar(&tikvVer, "tikv-version", "", "Specify the version of tikv to upgrade to") + cmd.Flags().StringVar(&pdVer, "pd-version", "", "Specify the version of pd to upgrade to") + cmd.Flags().StringVar(&tiflashVer, "tiflash-version", "", "Specify the version of tiflash to upgrade to") + cmd.Flags().StringVar(&dashboardVer, "tidb-dashboard-version", "", "Specify the version of tidb-dashboard to upgrade to") + cmd.Flags().StringVar(&cdcVer, "cdc-version", "", "Specify the version of cdc to upgrade to") + cmd.Flags().StringVar(&kvcdcVer, "tikv-cdc-version", "", "Specify the cersion of tikc-cdc to upgrade to") + cmd.Flags().StringVar(&alertmanagerVer, "alertmanager-version", "", "Specify the version of alertmanager to upgrade to") + cmd.Flags().StringVar(&nodeExporterVer, "node-exporter-version", "", "Specify the version of node-exporter to upgrade to") + cmd.Flags().StringVar(&blackboxExporterVer, "blackbox-exporter-version", "", "Specify the version of blackbox-exporter to upgrade to") return cmd } diff --git a/components/dm/command/upgrade.go b/components/dm/command/upgrade.go index bb6abf0ac7..af79ccfeda 100644 --- a/components/dm/command/upgrade.go +++ b/components/dm/command/upgrade.go @@ -28,7 +28,7 @@ func newUpgradeCmd() *cobra.Command { return cmd.Help() } - return cm.Upgrade(args[0], args[1], gOpt, skipConfirm, offlineMode) + return cm.Upgrade(args[0], args[1], nil, gOpt, skipConfirm, offlineMode) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { switch len(args) { diff --git a/pkg/cluster/manager/builder.go b/pkg/cluster/manager/builder.go index e512a3e201..f288685c3f 100644 --- a/pkg/cluster/manager/builder.go +++ b/pkg/cluster/manager/builder.go @@ -213,7 +213,7 @@ func buildScaleOutTask( inst.ComponentSource(), inst.OS(), inst.Arch(), - version, + inst.CalculateVersion(version), srcPath, inst.GetManageHost(), deployDir, @@ -272,7 +272,6 @@ func buildScaleOutTask( noAgentHosts, topo.BaseTopo().GlobalOptions, topo.BaseTopo().MonitoredOptions, - base.Version, gOpt, p, ) @@ -429,7 +428,6 @@ func buildMonitoredDeployTask( noAgentHosts set.StringSet, // hosts that do not deploy monitor agents globalOptions *spec.GlobalOptions, monitoredOptions *spec.MonitoredOptions, - version string, gOpt operator.Options, p *tui.SSHConnectionProps, ) (downloadCompTasks []*task.StepDisplay, deployCompTasks []*task.StepDisplay, err error) { @@ -440,7 +438,10 @@ func buildMonitoredDeployTask( uniqueCompOSArch := set.NewStringSet() // monitoring agents for _, comp := range []string{spec.ComponentNodeExporter, spec.ComponentBlackboxExporter} { - version := m.bindVersion(comp, version) + version := monitoredOptions.NodeExporterVersion + if comp == spec.ComponentBlackboxExporter { + version = monitoredOptions.BlackboxExporterVersion + } for host, info := range uniqueHosts { // skip deploying monitoring agents if the instance is marked so if noAgentHosts.Exist(host) { @@ -698,7 +699,7 @@ func buildDownloadCompTasks( // download spark as dependency of tispark tasks = append(tasks, buildDownloadSparkTask(inst, logger, gOpt)) } else { - version = bindVersion(inst.ComponentSource(), clusterVersion) + version = bindVersion(inst.ComponentSource(), inst.CalculateVersion(clusterVersion)) } t := task.NewBuilder(logger). diff --git a/pkg/cluster/manager/check.go b/pkg/cluster/manager/check.go index 7bc2fc61a7..ab2d59dfc0 100644 --- a/pkg/cluster/manager/check.go +++ b/pkg/cluster/manager/check.go @@ -182,7 +182,7 @@ func checkSystemInfo( downloadTasks []*task.StepDisplay ) logger := ctx.Value(logprinter.ContextKeyLogger).(*logprinter.Logger) - insightVer := spec.TiDBComponentVersion(spec.ComponentCheckCollector, "") + insightVer := "" uniqueHosts := map[string]int{} // host -> ssh-port uniqueArchList := make(map[string]struct{}) // map["os-arch"]{} diff --git a/pkg/cluster/manager/deploy.go b/pkg/cluster/manager/deploy.go index ed1dfa0ba7..8963dd6114 100644 --- a/pkg/cluster/manager/deploy.go +++ b/pkg/cluster/manager/deploy.go @@ -249,7 +249,8 @@ func (m *Manager) Deploy( // Deploy components to remote topo.IterInstance(func(inst spec.Instance) { - version := m.bindVersion(inst.ComponentSource(), clusterVersion) + version := inst.CalculateVersion(clusterVersion) + inst.SetVersion(version) deployDir := spec.Abs(globalOptions.User, inst.DeployDir()) // data dir would be empty for components which don't need it dataDirs := spec.MultiDirAbs(globalOptions.User, inst.DataDir()) @@ -320,7 +321,6 @@ func (m *Manager) Deploy( noAgentHosts, globalOptions, topo.GetMonitoredOptions(), - clusterVersion, gOpt, sshProxyProps, ) diff --git a/pkg/cluster/manager/upgrade.go b/pkg/cluster/manager/upgrade.go index cf28dbadb0..422372b5ba 100644 --- a/pkg/cluster/manager/upgrade.go +++ b/pkg/cluster/manager/upgrade.go @@ -25,6 +25,7 @@ import ( perrs "github.com/pingcap/errors" "github.com/pingcap/tiup/pkg/cluster/clusterutil" "github.com/pingcap/tiup/pkg/cluster/ctxt" + "github.com/pingcap/tiup/pkg/cluster/executor" operator "github.com/pingcap/tiup/pkg/cluster/operation" "github.com/pingcap/tiup/pkg/cluster/spec" "github.com/pingcap/tiup/pkg/cluster/task" @@ -37,7 +38,19 @@ import ( ) // Upgrade the cluster. -func (m *Manager) Upgrade(name string, clusterVersion string, opt operator.Options, skipConfirm, offline bool) error { +func (m *Manager) Upgrade(name string, clusterVersion string, componentVersions map[string]string, opt operator.Options, skipConfirm, offline bool) error { + if !skipConfirm && strings.ToLower(opt.DisplayMode) != "json" { + for _, v := range componentVersions { + if v != "" { + m.logger.Warnf(color.YellowString("tiup-cluster does not provide compatibility guarantees or version checks for different component versions. Please be aware of the risks or use it with the assistance of PingCAP support.")) + err := tui.PromptForConfirmOrAbortError("Do you want to continue? [y/N]: ") + if err != nil { + return err + } + break + } + } + } if err := clusterutil.ValidateClusterNameOrError(name); err != nil { return err } @@ -91,16 +104,12 @@ Do you want to continue? [y/N]:`, for _, inst := range comp.Instances() { compName := inst.ComponentName() - // ignore monitor agents for instances marked as ignore_exporter - switch compName { - case spec.ComponentNodeExporter, - spec.ComponentBlackboxExporter: - if inst.IgnoreMonitorAgent() { - continue - } + // if component version is not specified, use the cluster version or latest("") + version := componentVersions[compName] + if version == "" { + version = m.bindVersion(compName, clusterVersion) } - - version := m.bindVersion(inst.ComponentSource(), clusterVersion) + inst.SetVersion(version) // Download component from repository key := fmt.Sprintf("%s-%s-%s-%s", compName, version, inst.OS(), inst.Arch()) @@ -144,6 +153,7 @@ Do you want to continue? [y/N]:`, // backup files of the old version tb = tb.BackupComponent(inst.ComponentSource(), base.Version, inst.GetManageHost(), deployDir) + // this interface is not used if deployerInstance, ok := inst.(DeployerInstance); ok { deployerInstance.Deploy(tb, "", deployDir, version, name, clusterVersion) } else { @@ -174,7 +184,7 @@ Do you want to continue? [y/N]:`, tb.InitConfig( name, - clusterVersion, + version, m.specManager, inst, base.User, @@ -190,6 +200,52 @@ Do you want to continue? [y/N]:`, } } + var sshProxyProps *tui.SSHConnectionProps = &tui.SSHConnectionProps{} + if opt.SSHType != executor.SSHTypeNone { + var err error + if len(opt.SSHProxyHost) != 0 { + if sshProxyProps, err = tui.ReadIdentityFileOrPassword(opt.SSHProxyIdentity, opt.SSHProxyUsePassword); err != nil { + return err + } + } + } + + monitoredOptions := topo.GetMonitoredOptions() + if componentVersions[spec.ComponentBlackboxExporter] != "" { + monitoredOptions.BlackboxExporterVersion = componentVersions[spec.ComponentBlackboxExporter] + } + if componentVersions[spec.ComponentNodeExporter] != "" { + monitoredOptions.NodeExporterVersion = componentVersions[spec.ComponentNodeExporter] + } + uniqueHosts, noAgentHosts := getMonitorHosts(topo) + // Deploy monitor relevant components to remote + dlTasks, dpTasks, err := buildMonitoredDeployTask( + m, + uniqueHosts, + noAgentHosts, + topo.BaseTopo().GlobalOptions, + monitoredOptions, + opt, + sshProxyProps, + ) + if err != nil { + return err + } + + monitorConfigTasks := buildInitMonitoredConfigTasks( + m.specManager, + name, + uniqueHosts, + noAgentHosts, + *topo.BaseTopo().GlobalOptions, + monitoredOptions, + m.logger, + opt.SSHTimeout, + opt.OptTimeout, + opt, + sshProxyProps, + ) + // handle dir scheme changes if hasImported { if err := spec.HandleImportPathMigration(name); err != nil { @@ -229,7 +285,10 @@ Do you want to continue? [y/N]:`, } t := b. Parallel(false, downloadCompTasks...). + ParallelStep("download monitored", false, dlTasks...). Parallel(opt.Force, copyCompTasks...). + ParallelStep("deploy monitored", false, dpTasks...). + ParallelStep("refresh monitored config", false, monitorConfigTasks...). Func("UpgradeCluster", func(ctx context.Context) error { if offline { return nil @@ -274,10 +333,10 @@ func versionCompare(curVersion, newVersion string) error { } switch semver.Compare(curVersion, newVersion) { - case -1: + case -1, 0: return nil - case 0, 1: - return perrs.Errorf("please specify a higher version than %s", curVersion) + case 1: + return perrs.Errorf("please specify a higher or equle version than %s", curVersion) default: return perrs.Errorf("unreachable") } diff --git a/pkg/cluster/spec/alertmanager.go b/pkg/cluster/spec/alertmanager.go index 50a4522478..62e85084d9 100644 --- a/pkg/cluster/spec/alertmanager.go +++ b/pkg/cluster/spec/alertmanager.go @@ -32,6 +32,7 @@ type AlertmanagerSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` @@ -208,7 +209,8 @@ func (i *AlertManagerInstance) InitConfig( if err := i.TransferLocalConfigFile(ctx, e, configPath, dst); err != nil { return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".yml", paths, nil) + // version is not used for alertmanager + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), "", i.OS(), i.Arch(), i.ComponentName()+".yml", paths) } // ScaleConfig deploy temporary config on scaling @@ -231,3 +233,8 @@ func (i *AlertManagerInstance) ScaleConfig( func (i *AlertManagerInstance) setTLSConfig(ctx context.Context, enableTLS bool, configs map[string]any, paths meta.DirPaths) (map[string]any, error) { return nil, nil } + +func (i *AlertManagerInstance) CalculateVersion(_ string) string { + // always not follow global version, use ""(latest) by default + return i.InstanceSpec.(*AlertmanagerSpec).Version +} diff --git a/pkg/cluster/spec/bindversion.go b/pkg/cluster/spec/bindversion.go index 6e6ac9fcf8..b20c24c9fb 100644 --- a/pkg/cluster/spec/bindversion.go +++ b/pkg/cluster/spec/bindversion.go @@ -25,7 +25,6 @@ func TiDBComponentVersion(comp, version string) string { case ComponentAlertmanager, ComponentBlackboxExporter, ComponentNodeExporter, - ComponentPushwaygate, ComponentCheckCollector, ComponentSpark, ComponentTiSpark, diff --git a/pkg/cluster/spec/cdc.go b/pkg/cluster/spec/cdc.go index 5ba4646f3b..102780353c 100644 --- a/pkg/cluster/spec/cdc.go +++ b/pkg/cluster/spec/cdc.go @@ -36,6 +36,7 @@ type CDCSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` @@ -191,14 +192,15 @@ func (i *CDCInstance) InitConfig( spec := i.InstanceSpec.(*CDCSpec) globalConfig := topo.ServerConfigs.CDC instanceConfig := spec.Config + version := i.CalculateVersion(clusterVersion) - if !tidbver.TiCDCSupportConfigFile(clusterVersion) { + if !tidbver.TiCDCSupportConfigFile(version) { if len(globalConfig)+len(instanceConfig) > 0 { return errors.New("server_config is only supported with TiCDC version v4.0.13 or later") } } - if !tidbver.TiCDCSupportClusterID(clusterVersion) && spec.TiCDCClusterID != "" { + if !tidbver.TiCDCSupportClusterID(version) && spec.TiCDCClusterID != "" { return errors.New("ticdc_cluster_id is only supported with TiCDC version v6.2.0 or later") } @@ -213,13 +215,13 @@ func (i *CDCInstance) InitConfig( GCTTL: spec.GCTTL, TZ: spec.TZ, ClusterID: spec.TiCDCClusterID, - DataDirEnabled: tidbver.TiCDCSupportDataDir(clusterVersion), - ConfigFileEnabled: tidbver.TiCDCSupportConfigFile(clusterVersion), + DataDirEnabled: tidbver.TiCDCSupportDataDir(version), + ConfigFileEnabled: tidbver.TiCDCSupportConfigFile(version), TLSEnabled: enableTLS, DeployDir: paths.Deploy, LogDir: paths.Log, - DataDir: utils.Ternary(tidbver.TiCDCSupportSortOrDataDir(clusterVersion), spec.DataDir, "").(string), + DataDir: utils.Ternary(tidbver.TiCDCSupportSortOrDataDir(version), spec.DataDir, "").(string), NumaNode: spec.NumaNode, } diff --git a/pkg/cluster/spec/dashboard.go b/pkg/cluster/spec/dashboard.go index 75f36db7f2..123e7a090e 100644 --- a/pkg/cluster/spec/dashboard.go +++ b/pkg/cluster/spec/dashboard.go @@ -224,7 +224,7 @@ func (i *DashboardInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths, nil) + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), i.CalculateVersion(clusterVersion), i.OS(), i.Arch(), i.ComponentName()+".toml", paths) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/drainer.go b/pkg/cluster/spec/drainer.go index 1ad3360a82..f9686982dd 100644 --- a/pkg/cluster/spec/drainer.go +++ b/pkg/cluster/spec/drainer.go @@ -33,6 +33,7 @@ import ( type DrainerSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + Version string `yaml:"version,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -274,7 +275,7 @@ func (i *DrainerInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths, nil) + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/grafana.go b/pkg/cluster/spec/grafana.go index ae6b39f817..eace8dd0f7 100644 --- a/pkg/cluster/spec/grafana.go +++ b/pkg/cluster/spec/grafana.go @@ -37,6 +37,7 @@ type GrafanaSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` diff --git a/pkg/cluster/spec/instance.go b/pkg/cluster/spec/instance.go index 769ec93bd4..d4f39b0e2c 100644 --- a/pkg/cluster/spec/instance.go +++ b/pkg/cluster/spec/instance.go @@ -53,7 +53,6 @@ const ( ComponentDMMaster = "dm-master" ComponentDMWorker = "dm-worker" ComponentPrometheus = "prometheus" - ComponentPushwaygate = "pushgateway" ComponentBlackboxExporter = "blackbox_exporter" ComponentNodeExporter = "node_exporter" ComponentCheckCollector = "insight" @@ -108,6 +107,8 @@ type Instance interface { Arch() string IsPatched() bool SetPatched(bool) + CalculateVersion(string) string + SetVersion(string) setTLSConfig(ctx context.Context, enableTLS bool, configs map[string]any, paths meta.DirPaths) (map[string]any, error) } @@ -444,6 +445,27 @@ func (i *BaseInstance) SetPatched(p bool) { v.SetBool(p) } +// CalculateVersion implements the Instance interface +func (i *BaseInstance) CalculateVersion(globalVersion string) string { + v := reflect.Indirect(reflect.ValueOf(i.InstanceSpec)).FieldByName("Version") + if !v.IsValid() { + return globalVersion + } + if v.String() == "" { + return globalVersion + } + return v.String() +} + +// SetVersion implements the Instance interface +func (i *BaseInstance) SetVersion(version string) { + v := reflect.Indirect(reflect.ValueOf(i.InstanceSpec)).FieldByName("Version") + if !v.CanSet() { + return + } + v.SetString(version) +} + // PrepareStart checks instance requirements before starting func (i *BaseInstance) PrepareStart(ctx context.Context, tlsCfg *tls.Config) error { return nil diff --git a/pkg/cluster/spec/monitoring.go b/pkg/cluster/spec/monitoring.go index a5753448eb..7a0954c1c6 100644 --- a/pkg/cluster/spec/monitoring.go +++ b/pkg/cluster/spec/monitoring.go @@ -40,6 +40,7 @@ type PrometheusSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` @@ -415,7 +416,7 @@ func (i *MonitorInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".yml", paths, nil) + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".yml", paths) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/pd.go b/pkg/cluster/spec/pd.go index 008d1917da..b5fa0887e5 100644 --- a/pkg/cluster/spec/pd.go +++ b/pkg/cluster/spec/pd.go @@ -37,6 +37,7 @@ type PDSpec struct { ListenHost string `yaml:"listen_host,omitempty"` AdvertiseClientAddr string `yaml:"advertise_client_addr,omitempty"` AdvertisePeerAddr string `yaml:"advertise_peer_addr,omitempty"` + Version string `yaml:"version,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -219,6 +220,7 @@ func (i *PDInstance) InitConfig( enableTLS := topo.GlobalOptions.TLSEnabled spec := i.InstanceSpec.(*PDSpec) scheme := utils.Ternary(enableTLS, "https", "http").(string) + version := i.CalculateVersion(clusterVersion) initialCluster := []string{} for _, pdspec := range topo.PDServers { @@ -283,7 +285,7 @@ func (i *PDInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths, nil) + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), version, i.OS(), i.Arch(), i.ComponentName()+".toml", paths) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/pump.go b/pkg/cluster/spec/pump.go index 7428105d08..1e1b680f9d 100644 --- a/pkg/cluster/spec/pump.go +++ b/pkg/cluster/spec/pump.go @@ -34,6 +34,7 @@ type PumpSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` diff --git a/pkg/cluster/spec/server_config.go b/pkg/cluster/spec/server_config.go index eccde16282..f8a0113cb9 100644 --- a/pkg/cluster/spec/server_config.go +++ b/pkg/cluster/spec/server_config.go @@ -263,7 +263,7 @@ func mergeImported(importConfig []byte, specConfigs ...map[string]any) (map[stri // BindVersion map the cluster version to the third components binding version. type BindVersion func(comp string, version string) (bindVersion string) -func checkConfig(ctx context.Context, e ctxt.Executor, componentName, componentSource, clusterVersion, nodeOS, arch, config string, paths meta.DirPaths, bindVersion BindVersion) error { +func checkConfig(ctx context.Context, e ctxt.Executor, componentName, componentSource, version, nodeOS, arch, config string, paths meta.DirPaths) error { var cmd string configPath := path.Join(paths.Deploy, "conf", config) switch componentName { @@ -277,17 +277,11 @@ func checkConfig(ctx context.Context, e ctxt.Executor, componentName, componentS return perrs.Annotate(ErrorCheckConfig, err.Error()) } - clsVer := utils.Version(clusterVersion) - ver := clusterVersion - if clsVer.IsNightly() { - ver = utils.NightlyVersionAlias - } - // FIXME: workaround for nightly versions, need refactor - if bindVersion != nil { - ver = bindVersion(componentSource, ver) + if utils.Version(version).IsNightly() { + version = utils.NightlyVersionAlias } - entry, err := repo.ComponentBinEntry(componentSource, ver) + entry, err := repo.ComponentBinEntry(componentSource, version) if err != nil { return perrs.Annotate(ErrorCheckConfig, err.Error()) } diff --git a/pkg/cluster/spec/spec.go b/pkg/cluster/spec/spec.go index 47e67251a1..2994670b5b 100644 --- a/pkg/cluster/spec/spec.go +++ b/pkg/cluster/spec/spec.go @@ -93,13 +93,15 @@ type ( // MonitoredOptions represents the monitored node configuration MonitoredOptions struct { - NodeExporterPort int `yaml:"node_exporter_port,omitempty" default:"9100"` - BlackboxExporterPort int `yaml:"blackbox_exporter_port,omitempty" default:"9115"` - DeployDir string `yaml:"deploy_dir,omitempty"` - DataDir string `yaml:"data_dir,omitempty"` - LogDir string `yaml:"log_dir,omitempty"` - NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` - ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` + NodeExporterPort int `yaml:"node_exporter_port,omitempty" default:"9100"` + BlackboxExporterPort int `yaml:"blackbox_exporter_port,omitempty" default:"9115"` + NodeExporterVersion string `yaml:node_exporter_version,omitempty` + BlackboxExporterVersion string `yaml:black_exporter_version,omitempty` + DeployDir string `yaml:"deploy_dir,omitempty"` + DataDir string `yaml:"data_dir,omitempty"` + LogDir string `yaml:"log_dir,omitempty"` + NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` + ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` } // ServerConfigs represents the server runtime configuration diff --git a/pkg/cluster/spec/tidb.go b/pkg/cluster/spec/tidb.go index 668bc15e57..d0a7be6c64 100644 --- a/pkg/cluster/spec/tidb.go +++ b/pkg/cluster/spec/tidb.go @@ -35,6 +35,7 @@ type TiDBSpec struct { ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` AdvertiseAddr string `yaml:"advertise_address,omitempty"` + Version string `yaml:"version,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -165,6 +166,7 @@ func (i *TiDBInstance) InitConfig( enableTLS := topo.GlobalOptions.TLSEnabled spec := i.InstanceSpec.(*TiDBSpec) + version := i.CalculateVersion(clusterVersion) pds := []string{} for _, pdspec := range topo.PDServers { @@ -176,7 +178,7 @@ func (i *TiDBInstance) InitConfig( ListenHost: i.GetListenHost(), AdvertiseAddr: utils.Ternary(spec.AdvertiseAddr != "", spec.AdvertiseAddr, spec.Host).(string), PD: strings.Join(pds, ","), - SupportSecboot: tidbver.TiDBSupportSecureBoot(clusterVersion), + SupportSecboot: tidbver.TiDBSupportSecureBoot(version), DeployDir: paths.Deploy, LogDir: paths.Log, @@ -232,7 +234,7 @@ func (i *TiDBInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths, nil) + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), version, i.OS(), i.Arch(), i.ComponentName()+".toml", paths) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/tiflash.go b/pkg/cluster/spec/tiflash.go index d19eab1f92..ac4f7c06fd 100644 --- a/pkg/cluster/spec/tiflash.go +++ b/pkg/cluster/spec/tiflash.go @@ -43,6 +43,7 @@ type TiFlashSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` @@ -435,7 +436,7 @@ func checkTiFlashStorageConfigWithVersion(clusterVersion string, config map[stri } // InitTiFlashConfig initializes TiFlash config file with the configurations in server_configs -func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion string, src map[string]any, paths meta.DirPaths) (map[string]any, error) { +func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, version string, src map[string]any, paths meta.DirPaths) (map[string]any, error) { var ( pathConfig string isStorageDirsDefined bool @@ -444,7 +445,7 @@ func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion markCacheSize string err error ) - if isStorageDirsDefined, err = checkTiFlashStorageConfigWithVersion(clusterVersion, src); err != nil { + if isStorageDirsDefined, err = checkTiFlashStorageConfigWithVersion(version, src); err != nil { return nil, err } // For backward compatibility, we need to rollback to set 'path' @@ -454,7 +455,7 @@ func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion pathConfig = fmt.Sprintf(`path: "%s"`, strings.Join(paths.Data, ",")) } - if tidbver.TiFlashDeprecatedUsersConfig(clusterVersion) { + if tidbver.TiFlashDeprecatedUsersConfig(version) { // For v4.0.12 or later, 5.0.0 or later, TiFlash can ignore these `user.*`, `quotas.*` settings deprecatedUsersConfig = "#" } else { @@ -489,7 +490,7 @@ func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion enableTLS := i.topo.(*Specification).GlobalOptions.TLSEnabled httpPort := "#" // For 7.1.0 or later, TiFlash HTTP service is removed, so we don't need to set http_port - if !tidbver.TiFlashNotNeedHTTPPortConfig(clusterVersion) { + if !tidbver.TiFlashNotNeedHTTPPortConfig(version) { if enableTLS { httpPort = fmt.Sprintf(`https_port: %d`, spec.HTTPPort) } else { @@ -498,7 +499,7 @@ func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion } tcpPort := "#" // Config tcp_port is only required for TiFlash version < 7.1.0, and is recommended to not specify for TiFlash version >= 7.1.0. - if tidbver.TiFlashRequiresTCPPortConfig(clusterVersion) { + if tidbver.TiFlashRequiresTCPPortConfig(version) { tcpPort = fmt.Sprintf(`tcp_port: %d`, spec.TCPPort) } @@ -510,7 +511,7 @@ func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion topo := Specification{} - if tidbver.TiFlashNotNeedSomeConfig(clusterVersion) { + if tidbver.TiFlashNotNeedSomeConfig(version) { // For 5.4.0 or later, TiFlash can ignore application.runAsDaemon and mark_cache_size setting daemonConfig = "#" markCacheSize = "#" @@ -742,9 +743,10 @@ func (i *TiFlashInstance) InitConfig( return err } spec := i.InstanceSpec.(*TiFlashSpec) + version := i.CalculateVersion(clusterVersion) cfg := &scripts.TiFlashScript{ - RequiredCPUFlags: getTiFlashRequiredCPUFlagsWithVersion(clusterVersion, spec.Arch), + RequiredCPUFlags: getTiFlashRequiredCPUFlagsWithVersion(version, spec.Arch), DeployDir: paths.Deploy, LogDir: paths.Log, @@ -767,7 +769,7 @@ func (i *TiFlashInstance) InitConfig( return err } - conf, err := i.InitTiFlashLearnerConfig(ctx, clusterVersion, topo.ServerConfigs.TiFlashLearner, paths) + conf, err := i.InitTiFlashLearnerConfig(ctx, version, topo.ServerConfigs.TiFlashLearner, paths) if err != nil { return err } @@ -800,7 +802,7 @@ func (i *TiFlashInstance) InitConfig( } // Init the configuration using cfg and server_configs - if conf, err = i.initTiFlashConfig(ctx, clusterVersion, topo.ServerConfigs.TiFlash, paths); err != nil { + if conf, err = i.initTiFlashConfig(ctx, version, topo.ServerConfigs.TiFlash, paths); err != nil { return err } @@ -831,7 +833,7 @@ func (i *TiFlashInstance) InitConfig( } // Check the configuration of instance level - if conf, err = i.mergeTiFlashInstanceConfig(clusterVersion, conf, spec.Config); err != nil { + if conf, err = i.mergeTiFlashInstanceConfig(version, conf, spec.Config); err != nil { return err } diff --git a/pkg/cluster/spec/tikv.go b/pkg/cluster/spec/tikv.go index 270bae06c2..ce7ef82970 100644 --- a/pkg/cluster/spec/tikv.go +++ b/pkg/cluster/spec/tikv.go @@ -51,6 +51,7 @@ type TiKVSpec struct { ListenHost string `yaml:"listen_host,omitempty"` AdvertiseAddr string `yaml:"advertise_addr,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` @@ -309,7 +310,7 @@ func (i *TiKVInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths, nil) + return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), clusterVersion, i.OS(), i.Arch(), i.ComponentName()+".toml", paths) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/tikv_cdc.go b/pkg/cluster/spec/tikv_cdc.go index 55c393d099..ebff85fdb3 100644 --- a/pkg/cluster/spec/tikv_cdc.go +++ b/pkg/cluster/spec/tikv_cdc.go @@ -36,6 +36,7 @@ type TiKVCDCSpec struct { Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + Version string `yaml:"version,omitempty"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` @@ -328,3 +329,8 @@ func (i *TiKVCDCInstance) PostRestart(ctx context.Context, topo Topology, tlsCfg logger.Debugf("tikv-cdc post-restart success, addr: %s, elapsed: %+v", address, time.Since(start)) return nil } + +func (i *TiKVCDCInstance) CalculateVersion(_ string) string { + // always not follow global version, use ""(latest) by default + return i.InstanceSpec.(*AlertmanagerSpec).Version +} diff --git a/pkg/cluster/task/builder.go b/pkg/cluster/task/builder.go index 6f8973b191..96e74cbb09 100644 --- a/pkg/cluster/task/builder.go +++ b/pkg/cluster/task/builder.go @@ -243,25 +243,25 @@ func (b *Builder) BackupComponent(component, fromVer string, host, deployDir str } // InitConfig appends a CopyComponent task to the current task collection -func (b *Builder) InitConfig(clusterName, clusterVersion string, specManager *spec.SpecManager, inst spec.Instance, deployUser string, ignoreCheck bool, paths meta.DirPaths) *Builder { +func (b *Builder) InitConfig(clusterName, version string, specManager *spec.SpecManager, inst spec.Instance, deployUser string, ignoreCheck bool, paths meta.DirPaths) *Builder { // get nightly version var componentVersion utils.Version meta := specManager.NewMetadata() // full version - componentVersion = utils.Version(clusterVersion) + componentVersion = utils.Version(version) if err := specManager.Metadata(clusterName, meta); err == nil { // get nightly version - if clusterVersion == utils.NightlyVersionAlias { + if version == utils.NightlyVersionAlias { componentVersion, _, err = environment.GlobalEnv().V1Repository().LatestNightlyVersion(inst.ComponentSource()) if err != nil { - componentVersion = utils.Version(clusterVersion) + componentVersion = utils.Version(version) } } // dm cluster does not require a full nightly version if meta.GetTopology().Type() == spec.TopoTypeDM { - componentVersion = utils.Version(clusterVersion) + componentVersion = utils.Version(version) } }