diff --git a/CHANGELOG.md b/CHANGELOG.md index cc50d969c8..6f076ea746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ TiUP Changelog +## [1.12.5] 2023-7-17 + +### Fix + +- Fix cannot start tiflash above v7.1.0 in `tiup-cluster` (#2230, @zanmato1984) + +## [1.12.4] 2023-7-13 + +### Fix + +- Fix cannot show tiflash uptime in `tiup-cluster` (#2227, @nexustar) + +### Improvement + +- Remove tcp_port for tiflash in `tiup-cluster` and `tiup-playground` (#2220, @zanmato1984) + +## [1.12.3] 2023-6-14 + +### Fixes + +- Fix cannot edit manage_host on an exist cluster in `tiup-cluster` (#2210, @nexustar) +- Fix still use host instead of manage_host in `tiup-cluster` (#2206 #2207, @nexustar) + +### Improvement + +- Check if the compnoent exists when uninstall in `tiup` (#2209, @srstack) + ## [1.12.2] 2023-5-19 ### Notes diff --git a/cmd/uninstall.go b/cmd/uninstall.go index 058727cd4c..0b243bc6cc 100644 --- a/cmd/uninstall.go +++ b/cmd/uninstall.go @@ -51,7 +51,7 @@ which is used to uninstall tiup. teleCommand = cmd.CommandPath() env := environment.GlobalEnv() if self { - deletable := []string{"bin", "manifest", "manifests", "components", "storage/cluster/packages"} + deletable := []string{"storage/cluster/packages", "components", "manifests", "manifest", "bin"} for _, dir := range deletable { if err := os.RemoveAll(env.Profile().Path(dir)); err != nil { return errors.Trace(err) @@ -86,6 +86,9 @@ func removeComponents(env *environment.Environment, specs []string, all bool) er if strings.Contains(spec, ":") { parts := strings.SplitN(spec, ":", 2) // after this version is deleted, component will have no version left. delete the whole component dir directly + if !utils.IsExist(env.LocalPath(localdata.ComponentParentDir, parts[0])) { + return errors.Trace(fmt.Errorf("component `%s` is not installed, please use `tiup list %s` to check", parts[0], parts[0])) + } dir, err := os.ReadDir(env.LocalPath(localdata.ComponentParentDir, parts[0])) if err != nil { return errors.Trace(err) @@ -99,6 +102,7 @@ func removeComponents(env *environment.Environment, specs []string, all bool) er } else { paths = append(paths, env.LocalPath(localdata.ComponentParentDir, parts[0], parts[1])) } + // if no more version left, delete the whole component dir if len(dir)-len(paths) < 1 { paths = append(paths, env.LocalPath(localdata.ComponentParentDir, parts[0])) } @@ -110,6 +114,10 @@ func removeComponents(env *environment.Environment, specs []string, all bool) er paths = append(paths, env.LocalPath(localdata.ComponentParentDir, spec)) } for _, path := range paths { + if !utils.IsExist(path) { + return errors.Trace(fmt.Errorf("component `%s` is not installed, please check", spec)) + } + fmt.Println(path) if err := os.RemoveAll(path); err != nil { return errors.Trace(err) } diff --git a/components/dm/command/prune.go b/components/dm/command/prune.go index c6bb13b97d..6b7c50cbc7 100644 --- a/components/dm/command/prune.go +++ b/components/dm/command/prune.go @@ -76,7 +76,7 @@ func clearOutDatedEtcdInfo(clusterName string, metadata *spec.Metadata, opt oper if err != nil { return err } - dmMasterClient := api.NewDMMasterClient(topo.GetMasterList(), 10*time.Second, tlsCfg) + dmMasterClient := api.NewDMMasterClient(topo.GetMasterListWithManageHost(), 10*time.Second, tlsCfg) registeredMasters, registeredWorkers, err := dmMasterClient.GetRegisteredMembers() if err != nil { return err diff --git a/components/dm/spec/logic.go b/components/dm/spec/logic.go index 0272100b3d..c1227f87d6 100644 --- a/components/dm/spec/logic.go +++ b/components/dm/spec/logic.go @@ -82,6 +82,7 @@ func (c *DMMasterComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.Port, @@ -284,6 +285,7 @@ func (c *DMWorkerComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.Port, diff --git a/components/dm/spec/topology_dm.go b/components/dm/spec/topology_dm.go index 4e5de5327c..6e073fb7c3 100644 --- a/components/dm/spec/topology_dm.go +++ b/components/dm/spec/topology_dm.go @@ -122,7 +122,7 @@ func AllDMComponentNames() (roles []string) { // MasterSpec represents the Master topology specification in topology.yaml type MasterSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -134,6 +134,7 @@ type MasterSpec struct { DeployDir string `yaml:"deploy_dir,omitempty"` DataDir string `yaml:"data_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -202,10 +203,18 @@ func (s *MasterSpec) GetAdvertisePeerURL(enableTLS bool) string { return fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(s.Host, s.PeerPort)) } +// GetSource returns source to download the component +func (s *MasterSpec) GetSource() string { + if s.Source == "" { + return ComponentDMMaster + } + return s.Source +} + // WorkerSpec represents the Master topology specification in topology.yaml type WorkerSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -216,6 +225,7 @@ type WorkerSpec struct { DeployDir string `yaml:"deploy_dir,omitempty"` DataDir string `yaml:"data_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -272,6 +282,14 @@ func (s *WorkerSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *WorkerSpec) GetSource() string { + if s.Source == "" { + return ComponentDMWorker + } + return s.Source +} + // UnmarshalYAML sets default values when unmarshaling the topology file func (s *Specification) UnmarshalYAML(unmarshal func(any) error) error { type topology Specification @@ -675,7 +693,7 @@ func (s *Specification) BaseTopo() *spec.BaseTopo { return &spec.BaseTopo{ GlobalOptions: &s.GlobalOptions, MonitoredOptions: s.GetMonitoredOptions(), - MasterList: s.GetMasterList(), + MasterList: s.GetMasterListWithManageHost(), Monitors: s.Monitors, Grafanas: s.Grafanas, Alertmanagers: s.Alertmanagers, @@ -701,12 +719,16 @@ func (s *Specification) MergeTopo(rhs spec.Topology) spec.Topology { return s.Merge(other) } -// GetMasterList returns a list of Master API hosts of the current cluster -func (s *Specification) GetMasterList() []string { +// GetMasterListWithManageHost returns a list of Master API hosts of the current cluster +func (s *Specification) GetMasterListWithManageHost() []string { var masterList []string for _, master := range s.Masters { - masterList = append(masterList, utils.JoinHostPort(master.Host, master.Port)) + host := master.Host + if master.ManageHost != "" { + host = master.ManageHost + } + masterList = append(masterList, utils.JoinHostPort(host, master.Port)) } return masterList diff --git a/components/playground/command.go b/components/playground/command.go index 49bf1a649c..31f9a19718 100644 --- a/components/playground/command.go +++ b/components/playground/command.go @@ -102,7 +102,6 @@ func newScaleOut() *cobra.Command { cmd.Flags().IntVarP(&opt.TiKVCDC.Num, "kvcdc", "", opt.TiKVCDC.Num, "TiKV-CDC instance number") cmd.Flags().IntVarP(&opt.Pump.Num, "pump", "", opt.Pump.Num, "Pump instance number") cmd.Flags().IntVarP(&opt.Drainer.Num, "drainer", "", opt.Pump.Num, "Drainer instance number") - cmd.Flags().StringVarP(&opt.TiDB.Host, "db.host", "", opt.TiDB.Host, "Playground TiDB host. If not provided, TiDB will still use `host` flag as its host") cmd.Flags().StringVarP(&opt.PD.Host, "pd.host", "", opt.PD.Host, "Playground PD host. If not provided, PD will still use `host` flag as its host") diff --git a/components/playground/instance/instance.go b/components/playground/instance/instance.go index 3a87555588..902e32b52a 100644 --- a/components/playground/instance/instance.go +++ b/components/playground/instance/instance.go @@ -109,6 +109,9 @@ func logIfErr(err error) { func pdEndpoints(pds []*PDInstance, isHTTP bool) []string { var endpoints []string for _, pd := range pds { + if pd.Role == PDRoleTSO || pd.Role == PDRoleResourceManager { + continue + } if isHTTP { endpoints = append(endpoints, "http://"+utils.JoinHostPort(AdvertiseHost(pd.Host), pd.StatusPort)) } else { diff --git a/components/playground/instance/pd.go b/components/playground/instance/pd.go index b37bee57de..84f1f53117 100644 --- a/components/playground/instance/pd.go +++ b/components/playground/instance/pd.go @@ -24,16 +24,32 @@ import ( "github.com/pingcap/tiup/pkg/utils" ) +// PDRole is the role of PD. +type PDRole string + +const ( + // PDRoleNormal is the default role of PD + PDRoleNormal PDRole = "pd" + // PDRoleAPI is the role of PD API + PDRoleAPI PDRole = "api" + // PDRoleTSO is the role of PD TSO + PDRoleTSO PDRole = "tso" + // PDRoleResourceManager is the role of PD resource manager + PDRoleResourceManager PDRole = "resource manager" +) + // PDInstance represent a running pd-server type PDInstance struct { instance + Role PDRole initEndpoints []*PDInstance joinEndpoints []*PDInstance + pds []*PDInstance Process } // NewPDInstance return a PDInstance -func NewPDInstance(binPath, dir, host, configPath string, id, port int) *PDInstance { +func NewPDInstance(role PDRole, binPath, dir, host, configPath string, id int, pds []*PDInstance, port int) *PDInstance { if port <= 0 { port = 2379 } @@ -47,6 +63,8 @@ func NewPDInstance(binPath, dir, host, configPath string, id, port int) *PDInsta StatusPort: utils.MustGetFreePort(host, port), ConfigPath: configPath, }, + Role: role, + pds: pds, } } @@ -70,35 +88,67 @@ func (inst *PDInstance) Name() string { // Start calls set inst.cmd and Start func (inst *PDInstance) Start(ctx context.Context, version utils.Version) error { uid := inst.Name() - args := []string{ - "--name=" + uid, - fmt.Sprintf("--data-dir=%s", filepath.Join(inst.Dir, "data")), - fmt.Sprintf("--peer-urls=http://%s", utils.JoinHostPort(inst.Host, inst.Port)), - fmt.Sprintf("--advertise-peer-urls=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.Port)), - fmt.Sprintf("--client-urls=http://%s", utils.JoinHostPort(inst.Host, inst.StatusPort)), - fmt.Sprintf("--advertise-client-urls=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.StatusPort)), - fmt.Sprintf("--log-file=%s", inst.LogFile()), - } - if inst.ConfigPath != "" { - args = append(args, fmt.Sprintf("--config=%s", inst.ConfigPath)) - } - - switch { - case len(inst.initEndpoints) > 0: - endpoints := make([]string, 0) - for _, pd := range inst.initEndpoints { - uid := fmt.Sprintf("pd-%d", pd.ID) - endpoints = append(endpoints, fmt.Sprintf("%s=http://%s", uid, utils.JoinHostPort(AdvertiseHost(inst.Host), pd.Port))) + var args []string + switch inst.Role { + case PDRoleNormal, PDRoleAPI: + if inst.Role == PDRoleAPI { + args = []string{"services", "api"} } - args = append(args, fmt.Sprintf("--initial-cluster=%s", strings.Join(endpoints, ","))) - case len(inst.joinEndpoints) > 0: - endpoints := make([]string, 0) - for _, pd := range inst.joinEndpoints { - endpoints = append(endpoints, fmt.Sprintf("http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), pd.Port))) + args = append(args, []string{ + "--name=" + uid, + fmt.Sprintf("--data-dir=%s", filepath.Join(inst.Dir, "data")), + fmt.Sprintf("--peer-urls=http://%s", utils.JoinHostPort(inst.Host, inst.Port)), + fmt.Sprintf("--advertise-peer-urls=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.Port)), + fmt.Sprintf("--client-urls=http://%s", utils.JoinHostPort(inst.Host, inst.StatusPort)), + fmt.Sprintf("--advertise-client-urls=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.StatusPort)), + fmt.Sprintf("--log-file=%s", inst.LogFile()), + }...) + if inst.ConfigPath != "" { + args = append(args, fmt.Sprintf("--config=%s", inst.ConfigPath)) + } + switch { + case len(inst.initEndpoints) > 0: + endpoints := make([]string, 0) + for _, pd := range inst.initEndpoints { + uid := fmt.Sprintf("pd-%d", pd.ID) + endpoints = append(endpoints, fmt.Sprintf("%s=http://%s", uid, utils.JoinHostPort(AdvertiseHost(inst.Host), pd.Port))) + } + args = append(args, fmt.Sprintf("--initial-cluster=%s", strings.Join(endpoints, ","))) + case len(inst.joinEndpoints) > 0: + endpoints := make([]string, 0) + for _, pd := range inst.joinEndpoints { + endpoints = append(endpoints, fmt.Sprintf("http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), pd.Port))) + } + args = append(args, fmt.Sprintf("--join=%s", strings.Join(endpoints, ","))) + default: + return errors.Errorf("must set the init or join instances") + } + case PDRoleTSO: + endpoints := pdEndpoints(inst.pds, true) + args = []string{ + "services", + "tso", + fmt.Sprintf("--listen-addr=http://%s", utils.JoinHostPort(inst.Host, inst.Port)), + fmt.Sprintf("--advertise-listen-addr=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.Port)), + fmt.Sprintf("--backend-endpoints=%s", strings.Join(endpoints, ",")), + fmt.Sprintf("--log-file=%s", inst.LogFile()), + } + if inst.ConfigPath != "" { + args = append(args, fmt.Sprintf("--config=%s", inst.ConfigPath)) + } + case PDRoleResourceManager: + endpoints := pdEndpoints(inst.pds, true) + args = []string{ + "services", + "resource-manager", + fmt.Sprintf("--listen-addr=http://%s", utils.JoinHostPort(inst.Host, inst.Port)), + fmt.Sprintf("--advertise-listen-addr=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.Port)), + fmt.Sprintf("--backend-endpoints=%s", strings.Join(endpoints, ",")), + fmt.Sprintf("--log-file=%s", inst.LogFile()), + } + if inst.ConfigPath != "" { + args = append(args, fmt.Sprintf("--config=%s", inst.ConfigPath)) } - args = append(args, fmt.Sprintf("--join=%s", strings.Join(endpoints, ","))) - default: - return errors.Errorf("must set the init or join instances") } var err error @@ -113,12 +163,15 @@ func (inst *PDInstance) Start(ctx context.Context, version utils.Version) error // Component return the component name. func (inst *PDInstance) Component() string { - return "pd" + if inst.Role == PDRoleNormal { + return "pd" + } + return fmt.Sprintf("pd %s", inst.Role) } // LogFile return the log file. func (inst *PDInstance) LogFile() string { - return filepath.Join(inst.Dir, "pd.log") + return filepath.Join(inst.Dir, fmt.Sprintf("%s.log", string(inst.Role))) } // Addr return the listen address of PD diff --git a/components/playground/instance/tiflash.go b/components/playground/instance/tiflash.go index 72f815cd23..cb73f2d722 100644 --- a/components/playground/instance/tiflash.go +++ b/components/playground/instance/tiflash.go @@ -138,7 +138,6 @@ func (inst *TiFlashInstance) Start(ctx context.Context, version utils.Version) e fmt.Sprintf("--tmp_path=%s", filepath.Join(inst.Dir, "tmp")), fmt.Sprintf("--path=%s", filepath.Join(inst.Dir, "data")), fmt.Sprintf("--listen_host=%s", inst.Host), - fmt.Sprintf("--tcp_port=%d", inst.TCPPort), fmt.Sprintf("--logger.log=%s", inst.LogFile()), fmt.Sprintf("--logger.errorlog=%s", filepath.Join(inst.Dir, "tiflash_error.log")), fmt.Sprintf("--status.metrics_port=%d", inst.StatusPort), diff --git a/components/playground/instance/tiflash_pre7_config.go b/components/playground/instance/tiflash_pre7_config.go index cd3e04be10..3481540c18 100644 --- a/components/playground/instance/tiflash_pre7_config.go +++ b/components/playground/instance/tiflash_pre7_config.go @@ -34,10 +34,10 @@ const tiflashMarkCacheSizeOld = `mark_cache_size = 5368709120` const tiflashConfigOld = ` default_profile = "default" display_name = "TiFlash" -%[2]s +http_port = %[2]d listen_host = "0.0.0.0" -path = "%[5]s" tcp_port = %[3]d +path = "%[5]s" tmp_path = "%[6]s" %[14]s %[13]s @@ -109,11 +109,11 @@ func writeTiFlashConfigOld(w io.Writer, version utils.Version, tcpPort, httpPort var conf string if tidbver.TiFlashNotNeedSomeConfig(version.String()) { - conf = fmt.Sprintf(tiflashConfigOld, pdAddrs, fmt.Sprintf(`http_port = %d`, httpPort), tcpPort, + conf = fmt.Sprintf(tiflashConfigOld, pdAddrs, httpPort, tcpPort, deployDir, dataDir, tmpDir, logDir, servicePort, metricsPort, ip, strings.Join(tidbStatusAddrs, ","), clusterManagerPath, "", "") } else { - conf = fmt.Sprintf(tiflashConfigOld, pdAddrs, fmt.Sprintf(`http_port = %d`, httpPort), tcpPort, + conf = fmt.Sprintf(tiflashConfigOld, pdAddrs, httpPort, tcpPort, deployDir, dataDir, tmpDir, logDir, servicePort, metricsPort, ip, strings.Join(tidbStatusAddrs, ","), clusterManagerPath, tiflashDaemonConfigOld, tiflashMarkCacheSizeOld) } diff --git a/components/playground/main.go b/components/playground/main.go index 9ef6a16cdf..7a08e81f4c 100644 --- a/components/playground/main.go +++ b/components/playground/main.go @@ -55,8 +55,12 @@ import ( // BootOptions is the topology and options used to start a playground cluster type BootOptions struct { Mode string `yaml:"mode"` + PDMode string `yaml:"pd_mode"` Version string `yaml:"version"` - PD instance.Config `yaml:"pd"` + PD instance.Config `yaml:"pd"` // ignored when pd_mode == ms + PDAPI instance.Config `yaml:"pd_api"` // Only available when pd_mode == ms + PDTSO instance.Config `yaml:"pd_tso"` // Only available when pd_mode == ms + PDRM instance.Config `yaml:"pd_rm"` // Only available when pd_mode == ms TiDB instance.Config `yaml:"tidb"` TiKV instance.Config `yaml:"tikv"` TiFlash instance.Config `yaml:"tiflash"` // ignored when mode == tidb-disagg @@ -267,6 +271,7 @@ If you'd like to use a TiDB version other than %s, cancel and retry with the fol } rootCmd.Flags().StringVar(&options.Mode, "mode", "tidb", "TiUP playground mode: 'tidb', 'tidb-disagg', 'tikv-slim'") + rootCmd.Flags().StringVar(&options.PDMode, "pd.mode", "pd", "PD mode: 'pd', 'ms'") rootCmd.PersistentFlags().StringVarP(&tag, "tag", "T", "", "Specify a tag for playground") // Use `PersistentFlags()` to make it available to subcommands. rootCmd.Flags().Bool("without-monitor", false, "Don't start prometheus and grafana component") rootCmd.Flags().BoolVar(&options.Monitor, "monitor", true, "Start prometheus and grafana component") @@ -285,6 +290,10 @@ If you'd like to use a TiDB version other than %s, cancel and retry with the fol rootCmd.Flags().IntVar(&options.Pump.Num, "pump", 0, "Pump instance number") rootCmd.Flags().IntVar(&options.Drainer.Num, "drainer", 0, "Drainer instance number") + rootCmd.Flags().IntVar(&options.PDAPI.Num, "pd.api", 0, "PD API instance number") + rootCmd.Flags().IntVar(&options.PDTSO.Num, "pd.tso", 0, "PD TSO instance number") + rootCmd.Flags().IntVar(&options.PDRM.Num, "pd.rm", 0, "PD resource manager instance number") + rootCmd.Flags().IntVar(&options.TiDB.UpTimeout, "db.timeout", 60, "TiDB max wait time in seconds for starting, 0 means no limit") rootCmd.Flags().IntVar(&options.TiFlash.UpTimeout, "tiflash.timeout", 120, "TiFlash max wait time in seconds for starting, 0 means no limit") @@ -309,6 +318,10 @@ If you'd like to use a TiDB version other than %s, cancel and retry with the fol rootCmd.Flags().StringVar(&options.TiCDC.ConfigPath, "ticdc.config", "", "TiCDC instance configuration file") rootCmd.Flags().StringVar(&options.TiKVCDC.ConfigPath, "kvcdc.config", "", "TiKV-CDC instance configuration file") + rootCmd.Flags().StringVar(&options.PDAPI.ConfigPath, "pd.api.config", "", "PD API instance configuration file") + rootCmd.Flags().StringVar(&options.PDTSO.ConfigPath, "pd.tso.config", "", "PD TSO instance configuration file") + rootCmd.Flags().StringVar(&options.PDRM.ConfigPath, "pd.rm.config", "", "PD resource manager instance configuration file") + rootCmd.Flags().StringVar(&options.TiDB.BinPath, "db.binpath", "", "TiDB instance binary path") rootCmd.Flags().StringVar(&options.TiKV.BinPath, "kv.binpath", "", "TiKV instance binary path") rootCmd.Flags().StringVar(&options.PD.BinPath, "pd.binpath", "", "PD instance binary path") @@ -320,6 +333,10 @@ If you'd like to use a TiDB version other than %s, cancel and retry with the fol rootCmd.Flags().StringVar(&options.Pump.BinPath, "pump.binpath", "", "Pump instance binary path") rootCmd.Flags().StringVar(&options.Drainer.BinPath, "drainer.binpath", "", "Drainer instance binary path") + rootCmd.Flags().StringVar(&options.PDAPI.BinPath, "pd.api.binpath", "", "PD API instance binary path") + rootCmd.Flags().StringVar(&options.PDTSO.BinPath, "pd.tso.binpath", "", "PD TSO instance binary path") + rootCmd.Flags().StringVar(&options.PDRM.BinPath, "pd.rm.binpath", "", "PD resource manager instance binary path") + rootCmd.Flags().StringVar(&options.TiKVCDC.Version, "kvcdc.version", "", "TiKV-CDC instance version") rootCmd.Flags().StringVar(&options.DisaggOpts.S3Endpoint, "disagg.s3_endpoint", "127.0.0.1:9000", "Object store URL for the disaggregated TiFlash, available when --mode=tidb-disagg") @@ -356,15 +373,12 @@ func populateDefaultOpt(flagSet *pflag.FlagSet) error { case "tidb": defaultInt(&options.TiDB.Num, "db", 1) defaultInt(&options.TiKV.Num, "kv", 1) - defaultInt(&options.PD.Num, "pd", 1) defaultInt(&options.TiFlash.Num, "tiflash", 1) case "tikv-slim": defaultInt(&options.TiKV.Num, "kv", 1) - defaultInt(&options.PD.Num, "pd", 1) case "tidb-disagg": defaultInt(&options.TiDB.Num, "db", 1) defaultInt(&options.TiKV.Num, "kv", 1) - defaultInt(&options.PD.Num, "pd", 1) defaultInt(&options.TiFlash.Num, "tiflash", 1) defaultInt(&options.TiFlashWrite.Num, "tiflash.write", options.TiFlash.Num) defaultStr(&options.TiFlashWrite.BinPath, "tiflash.write.binpath", options.TiFlash.BinPath) @@ -378,6 +392,23 @@ func populateDefaultOpt(flagSet *pflag.FlagSet) error { return errors.Errorf("Unknown --mode %s", options.Mode) } + switch options.PDMode { + case "pd": + defaultInt(&options.PD.Num, "pd", 1) + case "ms": + defaultInt(&options.PDAPI.Num, "pd.api", 1) + defaultStr(&options.PDAPI.BinPath, "pd.api.binpath", options.PDAPI.BinPath) + defaultStr(&options.PDAPI.ConfigPath, "pd.api.config", options.PDAPI.ConfigPath) + defaultInt(&options.PDTSO.Num, "pd.tso", 1) + defaultStr(&options.PDTSO.BinPath, "pd.tso.binpath", options.PDTSO.BinPath) + defaultStr(&options.PDTSO.ConfigPath, "pd.tso.config", options.PDTSO.ConfigPath) + defaultInt(&options.PDRM.Num, "pd.rm", 1) + defaultStr(&options.PDRM.BinPath, "pd.rm.binpath", options.PDRM.BinPath) + defaultStr(&options.PDRM.ConfigPath, "pd.rm.config", options.PDRM.ConfigPath) + default: + return errors.Errorf("Unknown --pd.mode %s", options.PDMode) + } + return nil } diff --git a/components/playground/playground.go b/components/playground/playground.go index 51e0dedc9e..adc5e85c73 100644 --- a/components/playground/playground.go +++ b/components/playground/playground.go @@ -430,7 +430,11 @@ func (p *Playground) sanitizeComponentConfig(cid string, cfg *instance.Config) e func (p *Playground) startInstance(ctx context.Context, inst instance.Instance) error { boundVersion := p.bindVersion(inst.Component(), p.bootOptions.Version) - version, err := environment.GlobalEnv().V1Repository().ResolveComponentVersion(inst.Component(), boundVersion) + component := inst.Component() + if strings.HasPrefix(component, "pd") { + component = string(instance.PDRoleNormal) + } + version, err := environment.GlobalEnv().V1Repository().ResolveComponentVersion(component, boundVersion) if err != nil { return err } @@ -469,7 +473,7 @@ func (p *Playground) handleScaleOut(w io.Writer, cmd *Command) error { return err } // TODO: Support scale-out in disaggregated mode - inst, err := p.addInstance(cmd.ComponentID, instance.TiFlashRoleNormal, cmd.Config) + inst, err := p.addInstance(cmd.ComponentID, instance.PDRoleNormal, instance.TiFlashRoleNormal, cmd.Config) if err != nil { return err } @@ -633,7 +637,7 @@ func (p *Playground) enableBinlog() bool { return p.bootOptions.Pump.Num > 0 } -func (p *Playground) addInstance(componentID string, tiflashRole instance.TiFlashRole, cfg instance.Config) (ins instance.Instance, err error) { +func (p *Playground) addInstance(componentID string, pdRole instance.PDRole, tiflashRole instance.TiFlashRole, cfg instance.Config) (ins instance.Instance, err error) { if cfg.BinPath != "" { cfg.BinPath, err = getAbsolutePath(cfg.BinPath) if err != nil { @@ -651,7 +655,7 @@ func (p *Playground) addInstance(componentID string, tiflashRole instance.TiFlas dataDir := p.dataDir id := p.allocID(componentID) - dir := filepath.Join(dataDir, fmt.Sprintf("%s-%d", componentID, id)) + dir := filepath.Join(dataDir, fmt.Sprintf("%s-%d", pdRole, id)) if err = utils.MkdirAll(dir, 0755); err != nil { return nil, err } @@ -663,16 +667,20 @@ func (p *Playground) addInstance(componentID string, tiflashRole instance.TiFlas switch componentID { case spec.ComponentPD: - inst := instance.NewPDInstance(cfg.BinPath, dir, host, cfg.ConfigPath, id, cfg.Port) + inst := instance.NewPDInstance(pdRole, cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds, cfg.Port) ins = inst - if p.booted { - inst.Join(p.pds) - p.pds = append(p.pds, inst) + if pdRole == instance.PDRoleNormal || pdRole == instance.PDRoleAPI { + if p.booted { + inst.Join(p.pds) + p.pds = append(p.pds, inst) + } else { + p.pds = append(p.pds, inst) + for _, pd := range p.pds { + pd.InitCluster(p.pds) + } + } } else { p.pds = append(p.pds, inst) - for _, pd := range p.pds { - pd.InitCluster(p.pds) - } } case spec.ComponentTiDB: inst := instance.NewTiDBInstance(cfg.BinPath, dir, host, cfg.ConfigPath, id, cfg.Port, p.pds, p.enableBinlog(), p.bootOptions.Mode == "tidb-disagg") @@ -801,6 +809,9 @@ func (p *Playground) bindVersion(comp string, version string) (bindVersion strin func (p *Playground) bootCluster(ctx context.Context, env *environment.Environment, options *BootOptions) error { for _, cfg := range []*instance.Config{ &options.PD, + &options.PDAPI, + &options.PDTSO, + &options.PDRM, &options.TiDB, &options.TiKV, &options.TiFlash, @@ -820,7 +831,7 @@ func (p *Playground) bootCluster(ctx context.Context, env *environment.Environme p.bootOptions = options // All others components depend on the pd, we just ensure the pd count must be great than 0 - if options.PD.Num < 1 { + if options.PDMode != "ms" && options.PD.Num < 1 { return fmt.Errorf("all components count must be great than 0 (pd=%v)", options.PD.Num) } @@ -837,24 +848,23 @@ func (p *Playground) bootCluster(ctx context.Context, env *environment.Environme type InstancePair struct { comp string + pdRole instance.PDRole tiflashRole instance.TiFlashRole instance.Config } instances := []InstancePair{ - {spec.ComponentPD, "", options.PD}, - {spec.ComponentTiKV, "", options.TiKV}, - {spec.ComponentPump, "", options.Pump}, - {spec.ComponentTiDB, "", options.TiDB}, - {spec.ComponentCDC, "", options.TiCDC}, - {spec.ComponentTiKVCDC, "", options.TiKVCDC}, - {spec.ComponentDrainer, "", options.Drainer}, + {spec.ComponentTiKV, "", "", options.TiKV}, + {spec.ComponentPump, "", "", options.Pump}, + {spec.ComponentTiDB, "", "", options.TiDB}, + {spec.ComponentCDC, "", "", options.TiCDC}, + {spec.ComponentTiKVCDC, "", "", options.TiKVCDC}, + {spec.ComponentDrainer, "", "", options.Drainer}, } if options.Mode == "tidb" { - instances = append( - instances, - InstancePair{spec.ComponentTiFlash, instance.TiFlashRoleNormal, options.TiFlash}, + instances = append(instances, + InstancePair{spec.ComponentTiFlash, instance.PDRoleNormal, instance.TiFlashRoleNormal, options.TiFlash}, ) } else if options.Mode == "tidb-disagg" { if !tidbver.TiDBSupportDisagg(options.Version) { @@ -892,14 +902,30 @@ func (p *Playground) bootCluster(ctx context.Context, env *environment.Environme instances = append( instances, - InstancePair{spec.ComponentTiFlash, instance.TiFlashRoleDisaggWrite, options.TiFlashWrite}, - InstancePair{spec.ComponentTiFlash, instance.TiFlashRoleDisaggCompute, options.TiFlashCompute}, + InstancePair{spec.ComponentTiFlash, instance.PDRoleNormal, instance.TiFlashRoleDisaggWrite, options.TiFlashWrite}, + InstancePair{spec.ComponentTiFlash, instance.PDRoleNormal, instance.TiFlashRoleDisaggCompute, options.TiFlashCompute}, + ) + } + + if options.PDMode == "pd" { + instances = append([]InstancePair{{spec.ComponentPD, instance.PDRoleNormal, instance.TiFlashRoleNormal, options.PD}}, + instances..., + ) + } else if options.PDMode == "ms" { + if !tidbver.PDSupportMicroServices(options.Version) { + return fmt.Errorf("PD cluster doesn't support microservices mode in version %s", options.Version) + } + instances = append([]InstancePair{ + {spec.ComponentPD, instance.PDRoleAPI, instance.TiFlashRoleNormal, options.PDAPI}, + {spec.ComponentPD, instance.PDRoleTSO, instance.TiFlashRoleNormal, options.PDTSO}, + {spec.ComponentPD, instance.PDRoleResourceManager, instance.TiFlashRoleNormal, options.PDRM}}, + instances..., ) } for _, inst := range instances { for i := 0; i < inst.Num; i++ { - _, err := p.addInstance(inst.comp, inst.tiflashRole, inst.Config) + _, err := p.addInstance(inst.comp, inst.pdRole, inst.tiflashRole, inst.Config) if err != nil { return err } @@ -990,12 +1016,36 @@ func (p *Playground) bootCluster(ctx context.Context, env *environment.Environme } if p.bootOptions.Mode == "tikv-slim" { - var pdAddrs []string - for _, pd := range p.pds { - pdAddrs = append(pdAddrs, pd.Addr()) + if p.bootOptions.PDMode == "ms" { + var ( + tsoAddr []string + apiAddr []string + rmAddr []string + ) + for _, pd := range p.pds { + switch pd.Role { + case instance.PDRoleTSO: + tsoAddr = append(tsoAddr, pd.Addr()) + case instance.PDRoleAPI: + apiAddr = append(apiAddr, pd.Addr()) + case instance.PDRoleResourceManager: + rmAddr = append(rmAddr, pd.Addr()) + } + } + fmt.Printf("PD TSO Endpoints: ") + colorCmd.Printf("%s\n", strings.Join(tsoAddr, ",")) + fmt.Printf("PD API Endpoints: ") + colorCmd.Printf("%s\n", strings.Join(apiAddr, ",")) + fmt.Printf("PD Resource Ranager Endpoints: ") + colorCmd.Printf("%s\n", strings.Join(rmAddr, ",")) + } else { + var pdAddrs []string + for _, pd := range p.pds { + pdAddrs = append(pdAddrs, pd.Addr()) + } + fmt.Printf("PD Endpoints: ") + colorCmd.Printf("%s\n", strings.Join(pdAddrs, ",")) } - fmt.Printf("PD Endpoints: ") - colorCmd.Printf("%s\n", strings.Join(pdAddrs, ",")) } if monitorInfo != nil { diff --git a/embed/examples/cluster/minimal.yaml b/embed/examples/cluster/minimal.yaml index 7f373b1514..91c7789b9c 100644 --- a/embed/examples/cluster/minimal.yaml +++ b/embed/examples/cluster/minimal.yaml @@ -42,9 +42,9 @@ monitored: # # Server configs are used to specify the runtime configuration of TiDB components. # # All configuration items can be found in TiDB docs: -# # - TiDB: https://pingcap.com/docs/stable/reference/configuration/tidb-server/configuration-file/ -# # - TiKV: https://pingcap.com/docs/stable/reference/configuration/tikv-server/configuration-file/ -# # - PD: https://pingcap.com/docs/stable/reference/configuration/pd-server/configuration-file/ +# # - TiDB: https://docs.pingcap.com/tidb/stable/tidb-configuration-file +# # - TiKV: https://docs.pingcap.com/tidb/stable/tikv-configuration-file +# # - PD: https://docs.pingcap.com/tidb/stable/pd-configuration-file # # - TiFlash: https://docs.pingcap.com/tidb/stable/tiflash-configuration # # # # All configuration items use points to represent the hierarchy, e.g: @@ -182,6 +182,7 @@ tiflash_servers: # # SSH port of the server. # ssh_port: 22 # # TiFlash TCP Service port. + # # Since 7.1.0, it is not actually listened, and only being used as part of the instance identity. # tcp_port: 9000 # # TiFlash raft service and coprocessor service listening address. # flash_service_port: 3930 diff --git a/embed/examples/cluster/multi-dc.yaml b/embed/examples/cluster/multi-dc.yaml index 06fdae3af9..666936f7bc 100644 --- a/embed/examples/cluster/multi-dc.yaml +++ b/embed/examples/cluster/multi-dc.yaml @@ -235,6 +235,7 @@ tiflash_servers: # # SSH port of the server. # ssh_port: 22 # # TiFlash TCP Service port. + # # Since 7.1.0, it is not actually listened, and only being used as part of the instance identity. # tcp_port: 9000 # # TiFlash raft service and coprocessor service listening address. # flash_service_port: 3930 diff --git a/embed/examples/cluster/topology.example.yaml b/embed/examples/cluster/topology.example.yaml index f476316f2b..d1b09a0daa 100644 --- a/embed/examples/cluster/topology.example.yaml +++ b/embed/examples/cluster/topology.example.yaml @@ -42,9 +42,9 @@ monitored: # # Server configs are used to specify the runtime configuration of TiDB components. # # All configuration items can be found in TiDB docs: -# # - TiDB: https://pingcap.com/docs/stable/reference/configuration/tidb-server/configuration-file/ -# # - TiKV: https://pingcap.com/docs/stable/reference/configuration/tikv-server/configuration-file/ -# # - PD: https://pingcap.com/docs/stable/reference/configuration/pd-server/configuration-file/ +# # - TiDB: https://docs.pingcap.com/tidb/stable/tidb-configuration-file +# # - TiKV: https://docs.pingcap.com/tidb/stable/tikv-configuration-file +# # - PD: https://docs.pingcap.com/tidb/stable/pd-configuration-file # # - TiFlash: https://docs.pingcap.com/tidb/stable/tiflash-configuration # # # # All configuration items use points to represent the hierarchy, e.g: @@ -224,6 +224,7 @@ tiflash_servers: # # SSH port of the server. # ssh_port: 22 # # TiFlash TCP Service port. + # # Since 7.1.0, it is not actually listened, and only being used as part of the instance identity. tcp_port: 9000 # # TiFlash raft service and coprocessor service listening address. flash_service_port: 3930 diff --git a/pkg/cluster/ansible/service_test.go b/pkg/cluster/ansible/service_test.go index a119f2455f..0c5f6044ec 100644 --- a/pkg/cluster/ansible/service_test.go +++ b/pkg/cluster/ansible/service_test.go @@ -23,7 +23,6 @@ default_profile = "default" display_name = "TiFlash" listen_host = "0.0.0.0" path = "/data1/test-cluster/leiysky-ansible-test-deploy/tiflash/data/db" -tcp_port = 11315 tmp_path = "/data1/test-cluster/leiysky-ansible-test-deploy/tiflash/data/db/tmp" [flash] diff --git a/pkg/cluster/manager/builder.go b/pkg/cluster/manager/builder.go index 59f39bc817..e512a3e201 100644 --- a/pkg/cluster/manager/builder.go +++ b/pkg/cluster/manager/builder.go @@ -210,7 +210,7 @@ func buildScaleOutTask( tb = tb.DeploySpark(inst, sparkVer.String(), srcPath, deployDir) default: tb.CopyComponent( - inst.ComponentName(), + inst.ComponentSource(), inst.OS(), inst.Arch(), version, @@ -688,7 +688,7 @@ func buildDownloadCompTasks( var tasks []*task.StepDisplay uniqueTaskList := set.NewStringSet() topo.IterInstance(func(inst spec.Instance) { - key := fmt.Sprintf("%s-%s-%s", inst.ComponentName(), inst.OS(), inst.Arch()) + key := fmt.Sprintf("%s-%s-%s", inst.ComponentSource(), inst.OS(), inst.Arch()) if found := uniqueTaskList.Exist(key); !found { uniqueTaskList.Insert(key) @@ -698,13 +698,13 @@ func buildDownloadCompTasks( // download spark as dependency of tispark tasks = append(tasks, buildDownloadSparkTask(inst, logger, gOpt)) } else { - version = bindVersion(inst.ComponentName(), clusterVersion) + version = bindVersion(inst.ComponentSource(), clusterVersion) } t := task.NewBuilder(logger). - Download(inst.ComponentName(), inst.OS(), inst.Arch(), version). + Download(inst.ComponentSource(), inst.OS(), inst.Arch(), version). BuildAsStep(fmt.Sprintf(" - Download %s:%s (%s/%s)", - inst.ComponentName(), version, inst.OS(), inst.Arch())) + inst.ComponentSource(), version, inst.OS(), inst.Arch())) tasks = append(tasks, t) } }) diff --git a/pkg/cluster/manager/check.go b/pkg/cluster/manager/check.go index 75b5776fd6..9790adc302 100644 --- a/pkg/cluster/manager/check.go +++ b/pkg/cluster/manager/check.go @@ -695,7 +695,7 @@ func (m *Manager) checkRegionsInfo(clusterName string, topo *spec.Specification, } pdClient := api.NewPDClient( context.WithValue(context.TODO(), logprinter.ContextKeyLogger, m.logger), - topo.GetPDList(), + topo.GetPDListWithManageHost(), time.Second*time.Duration(gOpt.APITimeout), tlsConfig, ) diff --git a/pkg/cluster/manager/deploy.go b/pkg/cluster/manager/deploy.go index aba59074d4..ed1dfa0ba7 100644 --- a/pkg/cluster/manager/deploy.go +++ b/pkg/cluster/manager/deploy.go @@ -249,7 +249,7 @@ func (m *Manager) Deploy( // Deploy components to remote topo.IterInstance(func(inst spec.Instance) { - version := m.bindVersion(inst.ComponentName(), clusterVersion) + version := m.bindVersion(inst.ComponentSource(), clusterVersion) 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()) @@ -285,7 +285,7 @@ func (m *Manager) Deploy( t = t.DeploySpark(inst, sparkVer.String(), "" /* default srcPath */, deployDir) default: t = t.CopyComponent( - inst.ComponentName(), + inst.ComponentSource(), inst.OS(), inst.Arch(), version, diff --git a/pkg/cluster/manager/display.go b/pkg/cluster/manager/display.go index 6b9981a8bf..8965b14bb0 100644 --- a/pkg/cluster/manager/display.go +++ b/pkg/cluster/manager/display.go @@ -42,7 +42,6 @@ import ( "github.com/pingcap/tiup/pkg/set" "github.com/pingcap/tiup/pkg/tui" "github.com/pingcap/tiup/pkg/utils" - "go.uber.org/zap" ) // DisplayOption represents option of display command @@ -233,7 +232,7 @@ func (m *Manager) Display(dopt DisplayOption, opt operator.Options) error { continue } if strings.HasPrefix(v.Status, "Up") || strings.HasPrefix(v.Status, "Healthy") { - instAddr := utils.JoinHostPort(v.Host, v.Port) + instAddr := utils.JoinHostPort(v.ManageHost, v.Port) masterActive = append(masterActive, instAddr) } } @@ -610,8 +609,9 @@ func (m *Manager) GetClusterTopology(dopt DisplayOption, opt operator.Options) ( e, found := ctxt.GetInner(ctx).GetExecutor(ins.GetManageHost()) if found { var active string + var systemdSince time.Duration nctx := checkpoint.NewContext(ctx) - active, memory, _ = operator.GetServiceStatus(nctx, e, ins.ServiceName()) + active, memory, systemdSince, _ = operator.GetServiceStatus(nctx, e, ins.ServiceName()) if status == "-" { if active == "active" { status = "Up" @@ -620,7 +620,7 @@ func (m *Manager) GetClusterTopology(dopt DisplayOption, opt operator.Options) ( } } if dopt.ShowUptime && since == "-" { - since = formatInstanceSince(parseSystemctlSince(active)) + since = formatInstanceSince(systemdSince) } } } @@ -733,37 +733,6 @@ func formatInstanceSince(uptime time.Duration) string { return strings.Join(parts, "") } -// `systemctl status xxx.service` returns as below -// Active: active (running) since Sat 2021-03-27 10:51:11 CST; 41min ago -func parseSystemctlSince(str string) (dur time.Duration) { - // if service is not found or other error, don't need to parse it - if str == "" { - return 0 - } - defer func() { - if dur == 0 { - zap.L().Warn("failed to parse systemctl since", zap.String("value", str)) - } - }() - parts := strings.Split(str, ";") - if len(parts) != 2 { - return - } - parts = strings.Split(parts[0], " ") - if len(parts) < 3 { - return - } - - dateStr := strings.Join(parts[len(parts)-3:], " ") - - tm, err := time.Parse("2006-01-02 15:04:05 MST", dateStr) - if err != nil { - return - } - - return time.Since(tm) -} - // SetSSHKeySet set ssh key set. func SetSSHKeySet(ctx context.Context, privateKeyPath string, publicKeyPath string) error { ctxt.GetInner(ctx).PrivateKeyPath = privateKeyPath diff --git a/pkg/cluster/manager/exec.go b/pkg/cluster/manager/exec.go index c2e36c152e..bdda8c2ba4 100644 --- a/pkg/cluster/manager/exec.go +++ b/pkg/cluster/manager/exec.go @@ -60,7 +60,7 @@ func (m *Manager) Exec(name string, opt ExecOptions, gOpt operator.Options) erro return } - if len(gOpt.Nodes) > 0 && (!filterNodes.Exist(inst.GetHost()) || !filterNodes.Exist(inst.GetManageHost())) { + if len(gOpt.Nodes) > 0 && (!filterNodes.Exist(inst.GetHost()) && !filterNodes.Exist(inst.GetManageHost())) { return } diff --git a/pkg/cluster/manager/upgrade.go b/pkg/cluster/manager/upgrade.go index 652905bca5..6f2c71145e 100644 --- a/pkg/cluster/manager/upgrade.go +++ b/pkg/cluster/manager/upgrade.go @@ -100,14 +100,14 @@ Do you want to continue? [y/N]:`, } } - version := m.bindVersion(inst.ComponentName(), clusterVersion) + version := m.bindVersion(inst.ComponentSource(), clusterVersion) // Download component from repository key := fmt.Sprintf("%s-%s-%s-%s", compName, version, inst.OS(), inst.Arch()) if _, found := uniqueComps[key]; !found { uniqueComps[key] = struct{}{} t := task.NewBuilder(m.logger). - Download(inst.ComponentName(), inst.OS(), inst.Arch(), version). + Download(inst.ComponentSource(), inst.OS(), inst.Arch(), version). Build() downloadCompTasks = append(downloadCompTasks, t) } @@ -129,7 +129,7 @@ Do you want to continue? [y/N]:`, switch inst.ComponentName() { case spec.ComponentPrometheus, spec.ComponentGrafana, spec.ComponentAlertmanager: tb.CopyComponent( - inst.ComponentName(), + inst.ComponentSource(), inst.OS(), inst.Arch(), version, @@ -142,7 +142,7 @@ Do you want to continue? [y/N]:`, } // backup files of the old version - tb = tb.BackupComponent(inst.ComponentName(), base.Version, inst.GetManageHost(), deployDir) + tb = tb.BackupComponent(inst.ComponentSource(), base.Version, inst.GetManageHost(), deployDir) if deployerInstance, ok := inst.(DeployerInstance); ok { deployerInstance.Deploy(tb, "", deployDir, version, name, clusterVersion) @@ -161,7 +161,7 @@ Do you want to continue? [y/N]:`, tb = tb.DeploySpark(inst, sparkVer.String(), "" /* default srcPath */, deployDir) default: tb = tb.CopyComponent( - inst.ComponentName(), + inst.ComponentSource(), inst.OS(), inst.Arch(), version, diff --git a/pkg/cluster/operation/check.go b/pkg/cluster/operation/check.go index 3784bc69a4..f04981518e 100644 --- a/pkg/cluster/operation/check.go +++ b/pkg/cluster/operation/check.go @@ -520,7 +520,7 @@ func CheckServices(ctx context.Context, e ctxt.Executor, host, service string, d return result } - active, _, err := GetServiceStatus(ctx, e, service+".service") + active, _, _, err := GetServiceStatus(ctx, e, service+".service") if err != nil { result.Err = err } diff --git a/pkg/cluster/operation/destroy.go b/pkg/cluster/operation/destroy.go index 0d44613bf3..aeae040e3a 100644 --- a/pkg/cluster/operation/destroy.go +++ b/pkg/cluster/operation/destroy.go @@ -497,7 +497,7 @@ func DestroyClusterTombstone( pdEndpoints = strings.Split(forcePDEndpoints, ",") logger.Warnf("%s is set, using %s as PD endpoints", EnvNamePDEndpointOverwrite, pdEndpoints) } else { - pdEndpoints = cluster.GetPDList() + pdEndpoints = cluster.GetPDListWithManageHost() } var pdClient = api.NewPDClient(ctx, pdEndpoints, 10*time.Second, tlsCfg) diff --git a/pkg/cluster/operation/systemd.go b/pkg/cluster/operation/systemd.go index 497d05db22..8c5ba4e2cc 100644 --- a/pkg/cluster/operation/systemd.go +++ b/pkg/cluster/operation/systemd.go @@ -16,10 +16,12 @@ package operator import ( "context" "strings" + "time" "github.com/pingcap/errors" "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/module" + "go.uber.org/zap" ) // GetServiceStatus return the Acitive line of status. @@ -34,7 +36,7 @@ import ( Mar 09 13:56:19 ip-172-16-5-70 systemd[1]: Started drainer-8249 service. */ -func GetServiceStatus(ctx context.Context, e ctxt.Executor, name string) (active, memory string, err error) { +func GetServiceStatus(ctx context.Context, e ctxt.Executor, name string) (active, memory string, since time.Duration, err error) { c := module.SystemdModuleConfig{ Unit: name, Action: "status", @@ -50,6 +52,7 @@ func GetServiceStatus(ctx context.Context, e ctxt.Executor, name string) (active switch words[0] { case "Active:": active = words[1] + since = parseSystemctlSince(line) case "Memory:": memory = words[1] } @@ -60,3 +63,34 @@ func GetServiceStatus(ctx context.Context, e ctxt.Executor, name string) (active } return } + +// `systemctl status xxx.service` returns as below +// Active: active (running) since Sat 2021-03-27 10:51:11 CST; 41min ago +func parseSystemctlSince(str string) (dur time.Duration) { + // if service is not found or other error, don't need to parse it + if str == "" { + return 0 + } + defer func() { + if dur == 0 { + zap.L().Warn("failed to parse systemctl since", zap.String("value", str)) + } + }() + parts := strings.Split(str, ";") + if len(parts) != 2 { + return + } + parts = strings.Split(parts[0], " ") + if len(parts) < 3 { + return + } + + dateStr := strings.Join(parts[len(parts)-3:], " ") + + tm, err := time.Parse("2006-01-02 15:04:05 MST", dateStr) + if err != nil { + return + } + + return time.Since(tm) +} diff --git a/pkg/cluster/operation/upgrade.go b/pkg/cluster/operation/upgrade.go index bf72673c1b..7976635d38 100644 --- a/pkg/cluster/operation/upgrade.go +++ b/pkg/cluster/operation/upgrade.go @@ -79,7 +79,7 @@ func Upgrade( pdEndpoints = strings.Split(forcePDEndpoints, ",") logger.Warnf("%s is set, using %s as PD endpoints", EnvNamePDEndpointOverwrite, pdEndpoints) } else { - pdEndpoints = topo.(*spec.Specification).GetPDList() + pdEndpoints = topo.(*spec.Specification).GetPDListWithManageHost() } pdClient := api.NewPDClient(ctx, pdEndpoints, 10*time.Second, tlsCfg) origLeaderScheduleLimit, origRegionScheduleLimit, err = increaseScheduleLimit(ctx, pdClient) diff --git a/pkg/cluster/spec/alertmanager.go b/pkg/cluster/spec/alertmanager.go index 527bb21927..50a4522478 100644 --- a/pkg/cluster/spec/alertmanager.go +++ b/pkg/cluster/spec/alertmanager.go @@ -30,7 +30,7 @@ import ( // AlertmanagerSpec represents the AlertManager topology specification in topology.yaml type AlertmanagerSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -67,6 +67,14 @@ func (s *AlertmanagerSpec) GetMainPort() int { return s.WebPort } +// GetManageHost returns the manage host of the instance +func (s *AlertmanagerSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *AlertmanagerSpec) IsImported() bool { return s.Imported @@ -117,10 +125,10 @@ func (c *AlertManagerComponent) Instances() []Instance { s.DataDir, }, StatusFn: func(_ context.Context, timeout time.Duration, _ *tls.Config, _ ...string) string { - return statusByHost(s.Host, s.WebPort, "/-/ready", timeout, nil) + return statusByHost(s.GetManageHost(), s.WebPort, "/-/ready", timeout, nil) }, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.WebPort, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.WebPort, timeout, tlsCfg) }, }, topo: c.Topology, @@ -200,7 +208,7 @@ func (i *AlertManagerInstance) InitConfig( if err := i.TransferLocalConfigFile(ctx, e, configPath, dst); err != nil { return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // ScaleConfig deploy temporary config on scaling diff --git a/pkg/cluster/spec/cdc.go b/pkg/cluster/spec/cdc.go index 3c75fbdbb0..5ba4646f3b 100644 --- a/pkg/cluster/spec/cdc.go +++ b/pkg/cluster/spec/cdc.go @@ -34,7 +34,7 @@ import ( // CDCSpec represents the CDC topology specification in topology.yaml type CDCSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -47,6 +47,7 @@ type CDCSpec struct { GCTTL int64 `yaml:"gc-ttl,omitempty" validate:"gc-ttl:editable"` TZ string `yaml:"tz,omitempty" validate:"tz:editable"` TiCDCClusterID string `yaml:"ticdc_cluster_id"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -73,6 +74,14 @@ func (s *CDCSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *CDCSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *CDCSpec) IsImported() bool { return s.Imported @@ -83,6 +92,14 @@ func (s *CDCSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *CDCSpec) GetSource() string { + if s.Source == "" { + return ComponentCDC + } + return s.Source +} + // CDCComponent represents CDC component. type CDCComponent struct{ Topology *Specification } @@ -108,6 +125,7 @@ func (c *CDCComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.Port, @@ -116,10 +134,10 @@ func (c *CDCComponent) Instances() []Instance { s.DeployDir, }, StatusFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config, _ ...string) string { - return statusByHost(s.Host, s.Port, "/status", timeout, tlsCfg) + return statusByHost(s.GetManageHost(), s.Port, "/status", timeout, tlsCfg) }, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, c.Topology} if s.DataDir != "" { diff --git a/pkg/cluster/spec/dashboard.go b/pkg/cluster/spec/dashboard.go index e415227164..75f36db7f2 100644 --- a/pkg/cluster/spec/dashboard.go +++ b/pkg/cluster/spec/dashboard.go @@ -29,7 +29,7 @@ import ( // DashboardSpec represents the Dashboard topology specification in topology.yaml type DashboardSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + 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"` Patched bool `yaml:"patched,omitempty"` @@ -38,6 +38,7 @@ type DashboardSpec struct { DeployDir string `yaml:"deploy_dir,omitempty"` DataDir string `yaml:"data_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -51,7 +52,7 @@ func (s *DashboardSpec) Status(ctx context.Context, timeout time.Duration, tlsCf timeout = statusQueryTimeout } - state := statusByHost(s.Host, s.Port, "/status", timeout, tlsCfg) + state := statusByHost(s.GetManageHost(), s.Port, "/status", timeout, tlsCfg) return state } @@ -75,6 +76,14 @@ func (s *DashboardSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *DashboardSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *DashboardSpec) IsImported() bool { // TiDB-Ansible do not support dashboard @@ -86,6 +95,14 @@ func (s *DashboardSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *DashboardSpec) GetSource() string { + if s.Source == "" { + return ComponentDashboard + } + return s.Source +} + // DashboardComponent represents Drainer component. type DashboardComponent struct{ Topology *Specification } @@ -111,6 +128,7 @@ func (c *DashboardComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.Source, Ports: []int{ s.Port, @@ -121,7 +139,7 @@ func (c *DashboardComponent) Instances() []Instance { }, StatusFn: s.Status, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, c.Topology}) } @@ -206,7 +224,7 @@ func (i *DashboardInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/drainer.go b/pkg/cluster/spec/drainer.go index 347e2fd7c0..1ad3360a82 100644 --- a/pkg/cluster/spec/drainer.go +++ b/pkg/cluster/spec/drainer.go @@ -32,7 +32,7 @@ import ( // DrainerSpec represents the Drainer topology specification in topology.yaml type DrainerSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -43,6 +43,7 @@ type DrainerSpec struct { LogDir string `yaml:"log_dir,omitempty"` CommitTS *int64 `yaml:"commit_ts,omitempty" validate:"commit_ts:editable"` // do not use it anymore, exist for compatibility Offline bool `yaml:"offline,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -56,7 +57,7 @@ func (s *DrainerSpec) Status(ctx context.Context, timeout time.Duration, tlsCfg timeout = statusQueryTimeout } - state := statusByHost(s.Host, s.Port, "/status", timeout, tlsCfg) + state := statusByHost(s.GetManageHost(), s.Port, "/status", timeout, tlsCfg) if s.Offline { binlogClient, err := api.NewBinlogClient(pdList, timeout, tlsCfg) @@ -94,6 +95,14 @@ func (s *DrainerSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *DrainerSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *DrainerSpec) IsImported() bool { return s.Imported @@ -104,6 +113,14 @@ func (s *DrainerSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *DrainerSpec) GetSource() string { + if s.Source == "" { + return ComponentDrainer + } + return s.Source +} + // DrainerComponent represents Drainer component. type DrainerComponent struct{ Topology *Specification } @@ -129,6 +146,7 @@ func (c *DrainerComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.Port, @@ -139,7 +157,7 @@ func (c *DrainerComponent) Instances() []Instance { }, StatusFn: s.Status, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, c.Topology}) } @@ -256,7 +274,7 @@ func (i *DrainerInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/grafana.go b/pkg/cluster/spec/grafana.go index 7284bf1d54..6379b9a51e 100644 --- a/pkg/cluster/spec/grafana.go +++ b/pkg/cluster/spec/grafana.go @@ -35,7 +35,7 @@ import ( // GrafanaSpec represents the Grafana topology specification in topology.yaml type GrafanaSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -76,6 +76,14 @@ func (s *GrafanaSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *GrafanaSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *GrafanaSpec) IsImported() bool { return s.Imported @@ -122,10 +130,10 @@ func (c *GrafanaComponent) Instances() []Instance { s.DeployDir, }, StatusFn: func(_ context.Context, timeout time.Duration, _ *tls.Config, _ ...string) string { - return statusByHost(s.Host, s.Port, "/login", timeout, nil) + return statusByHost(s.GetManageHost(), s.Port, "/login", timeout, nil) }, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, topo: c.Topology, diff --git a/pkg/cluster/spec/instance.go b/pkg/cluster/spec/instance.go index 56eaac76ab..769ec93bd4 100644 --- a/pkg/cluster/spec/instance.go +++ b/pkg/cluster/spec/instance.go @@ -89,6 +89,7 @@ type Instance interface { ScaleConfig(ctx context.Context, e ctxt.Executor, topo Topology, clusterName string, clusterVersion string, deployUser string, paths meta.DirPaths) error PrepareStart(ctx context.Context, tlsCfg *tls.Config) error ComponentName() string + ComponentSource() string InstanceName() string ServiceName() string ResourceControl() meta.ResourceControl @@ -142,6 +143,7 @@ type BaseInstance struct { ListenHost string Port int SSHP int + Source string Ports []int Dirs []string @@ -302,6 +304,14 @@ func (i *BaseInstance) ComponentName() string { return i.Name } +// ComponentSource implements Instance interface +func (i *BaseInstance) ComponentSource() string { + if i.Source == "" { + return i.Name + } + return i.Source +} + // InstanceName implements Instance interface func (i *BaseInstance) InstanceName() string { if i.Port > 0 { diff --git a/pkg/cluster/spec/monitoring.go b/pkg/cluster/spec/monitoring.go index 3698d1d998..bf58056457 100644 --- a/pkg/cluster/spec/monitoring.go +++ b/pkg/cluster/spec/monitoring.go @@ -38,7 +38,7 @@ import ( // PrometheusSpec represents the Prometheus Server topology specification in topology.yaml type PrometheusSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -93,6 +93,14 @@ func (s *PrometheusSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *PrometheusSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *PrometheusSpec) IsImported() bool { return s.Imported @@ -139,10 +147,10 @@ func (c *MonitorComponent) Instances() []Instance { s.DataDir, }, StatusFn: func(_ context.Context, timeout time.Duration, _ *tls.Config, _ ...string) string { - return statusByHost(s.Host, s.Port, "/-/ready", timeout, nil) + return statusByHost(s.GetManageHost(), s.Port, "/-/ready", timeout, nil) }, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, c.Topology} if s.NgPort > 0 { @@ -407,7 +415,7 @@ func (i *MonitorInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/pd.go b/pkg/cluster/spec/pd.go index 3c2972298b..008d1917da 100644 --- a/pkg/cluster/spec/pd.go +++ b/pkg/cluster/spec/pd.go @@ -33,7 +33,7 @@ import ( // PDSpec represents the PD topology specification in topology.yaml type PDSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` AdvertiseClientAddr string `yaml:"advertise_client_addr,omitempty"` AdvertisePeerAddr string `yaml:"advertise_peer_addr,omitempty"` @@ -48,6 +48,7 @@ type PDSpec struct { DeployDir string `yaml:"deploy_dir,omitempty"` DataDir string `yaml:"data_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -137,6 +138,14 @@ func (s *PDSpec) GetAdvertisePeerURL(enableTLS bool) string { return fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(s.Host, s.PeerPort)) } +// GetSource returns source to download the component +func (s *PDSpec) GetSource() string { + if s.Source == "" { + return ComponentPD + } + return s.Source +} + // PDComponent represents PD component. type PDComponent struct{ Topology *Specification } @@ -165,6 +174,7 @@ func (c *PDComponent) Instances() []Instance { ListenHost: s.ListenHost, Port: s.ClientPort, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.ClientPort, @@ -176,7 +186,7 @@ func (c *PDComponent) Instances() []Instance { }, StatusFn: s.Status, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.ClientPort, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.ClientPort, timeout, tlsCfg) }, }, topo: c.Topology, @@ -273,7 +283,7 @@ func (i *PDInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/pump.go b/pkg/cluster/spec/pump.go index 1844403fc7..7428105d08 100644 --- a/pkg/cluster/spec/pump.go +++ b/pkg/cluster/spec/pump.go @@ -32,7 +32,7 @@ import ( // PumpSpec represents the Pump topology specification in topology.yaml type PumpSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -42,6 +42,7 @@ type PumpSpec struct { DataDir string `yaml:"data_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` Offline bool `yaml:"offline,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -55,7 +56,7 @@ func (s *PumpSpec) Status(ctx context.Context, timeout time.Duration, tlsCfg *tl timeout = statusQueryTimeout } - state := statusByHost(s.Host, s.Port, "/status", timeout, tlsCfg) + state := statusByHost(s.GetManageHost(), s.Port, "/status", timeout, tlsCfg) if s.Offline { binlogClient, err := api.NewBinlogClient(pdList, timeout, tlsCfg) @@ -93,6 +94,14 @@ func (s *PumpSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *PumpSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *PumpSpec) IsImported() bool { return s.Imported @@ -103,6 +112,14 @@ func (s *PumpSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *PumpSpec) GetSource() string { + if s.Source == "" { + return ComponentPump + } + return s.Source +} + // PumpComponent represents Pump component. type PumpComponent struct{ Topology *Specification } @@ -128,6 +145,7 @@ func (c *PumpComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.Port, @@ -138,7 +156,7 @@ func (c *PumpComponent) Instances() []Instance { }, StatusFn: s.Status, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, c.Topology}) } diff --git a/pkg/cluster/spec/server_config.go b/pkg/cluster/spec/server_config.go index d5de0f0bdf..eccde16282 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, clusterVersion, nodeOS, arch, config string, paths meta.DirPaths, bindVersion BindVersion) error { +func checkConfig(ctx context.Context, e ctxt.Executor, componentName, componentSource, clusterVersion, nodeOS, arch, config string, paths meta.DirPaths, bindVersion BindVersion) error { var cmd string configPath := path.Join(paths.Deploy, "conf", config) switch componentName { @@ -284,10 +284,10 @@ func checkConfig(ctx context.Context, e ctxt.Executor, componentName, clusterVer } // FIXME: workaround for nightly versions, need refactor if bindVersion != nil { - ver = bindVersion(componentName, ver) + ver = bindVersion(componentSource, ver) } - entry, err := repo.ComponentBinEntry(componentName, ver) + entry, err := repo.ComponentBinEntry(componentSource, ver) if err != nil { return perrs.Annotate(ErrorCheckConfig, err.Error()) } diff --git a/pkg/cluster/spec/spec.go b/pkg/cluster/spec/spec.go index 9a62d5897f..058c694101 100644 --- a/pkg/cluster/spec/spec.go +++ b/pkg/cluster/spec/spec.go @@ -254,7 +254,7 @@ func (s *Specification) BaseTopo() *BaseTopo { return &BaseTopo{ GlobalOptions: &s.GlobalOptions, MonitoredOptions: s.GetMonitoredOptions(), - MasterList: s.GetPDList(), + MasterList: s.GetPDListWithManageHost(), Monitors: s.Monitors, Grafanas: s.Grafanas, Alertmanagers: s.Alertmanagers, @@ -475,14 +475,14 @@ func (s *Specification) GetDashboardAddress(ctx context.Context, tlsCfg *tls.Con // GetEtcdClient loads EtcdClient of current cluster func (s *Specification) GetEtcdClient(tlsCfg *tls.Config) (*clientv3.Client, error) { return clientv3.New(clientv3.Config{ - Endpoints: s.GetPDList(), + Endpoints: s.GetPDListWithManageHost(), TLS: tlsCfg, }) } // GetEtcdProxyClient loads EtcdClient of current cluster with TCP proxy func (s *Specification) GetEtcdProxyClient(tlsCfg *tls.Config, tcpProxy *proxy.TCPProxy) (*clientv3.Client, chan struct{}, error) { - closeC := tcpProxy.Run(s.GetPDList()) + closeC := tcpProxy.Run(s.GetPDListWithManageHost()) cli, err := clientv3.New(clientv3.Config{ Endpoints: tcpProxy.GetEndpoints(), TLS: tlsCfg, diff --git a/pkg/cluster/spec/testdata/topology_err.yaml b/pkg/cluster/spec/testdata/topology_err.yaml index 61deec4203..6b64e33afe 100644 --- a/pkg/cluster/spec/testdata/topology_err.yaml +++ b/pkg/cluster/spec/testdata/topology_err.yaml @@ -15,16 +15,6 @@ monitored: # data_dir: "/tidb/data/monitored-9100" # log_dir: "/tidb/deploy/monitored-9100/log" -# # Server configs are used to specify the runtime configuration of TiDB components -# # All configuration items can be found in TiDB docs: -# # - TiDB: https://pingcap.com/docs/stable/reference/configuration/tidb-server/configuration-file/ -# # - TiKV: https://pingcap.com/docs/stable/reference/configuration/tikv-server/configuration-file/ -# # - PD: https://pingcap.com/docs/stable/reference/configuration/pd-server/configuration-file/ -# # All configuration items use points to represent the hierarchy, e.g: -# # readpool.storage.use-unified-pool -# # ^ ^ -# # You can overwrite this configuration via instance-level `config` field - server_configs: tidb: log.slow-threshold: 300 diff --git a/pkg/cluster/spec/tidb.go b/pkg/cluster/spec/tidb.go index 45f00b5c9c..668bc15e57 100644 --- a/pkg/cluster/spec/tidb.go +++ b/pkg/cluster/spec/tidb.go @@ -32,7 +32,7 @@ import ( // TiDBSpec represents the TiDB topology specification in topology.yaml type TiDBSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` AdvertiseAddr string `yaml:"advertise_address,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` @@ -43,6 +43,7 @@ type TiDBSpec struct { StatusPort int `yaml:"status_port" default:"10080"` DeployDir string `yaml:"deploy_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` NumaCores string `yaml:"numa_cores,omitempty" validate:"numa_cores:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` @@ -70,6 +71,14 @@ func (s *TiDBSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *TiDBSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *TiDBSpec) IsImported() bool { return s.Imported @@ -80,6 +89,14 @@ func (s *TiDBSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *TiDBSpec) GetSource() string { + if s.Source == "" { + return ComponentTiDB + } + return s.Source +} + // TiDBComponent represents TiDB component. type TiDBComponent struct{ Topology *Specification } @@ -106,6 +123,7 @@ func (c *TiDBComponent) Instances() []Instance { ListenHost: s.ListenHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.Source, Ports: []int{ s.Port, @@ -115,10 +133,10 @@ func (c *TiDBComponent) Instances() []Instance { s.DeployDir, }, StatusFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config, _ ...string) string { - return statusByHost(s.Host, s.StatusPort, "/status", timeout, tlsCfg) + return statusByHost(s.GetManageHost(), s.StatusPort, "/status", timeout, tlsCfg) }, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.StatusPort, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.StatusPort, timeout, tlsCfg) }, }, c.Topology}) } @@ -214,7 +232,7 @@ func (i *TiDBInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // setTLSConfig set TLS Config to support enable/disable TLS diff --git a/pkg/cluster/spec/tiflash.go b/pkg/cluster/spec/tiflash.go index 654929bf35..d19eab1f92 100644 --- a/pkg/cluster/spec/tiflash.go +++ b/pkg/cluster/spec/tiflash.go @@ -41,7 +41,7 @@ import ( // TiFlashSpec represents the TiFlash topology specification in topology.yaml type TiFlashSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -57,6 +57,7 @@ type TiFlashSpec struct { LogDir string `yaml:"log_dir,omitempty"` TmpDir string `yaml:"tmp_path,omitempty"` Offline bool `yaml:"offline,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` NumaCores string `yaml:"numa_cores,omitempty" validate:"numa_cores:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` @@ -143,6 +144,14 @@ func (s *TiFlashSpec) GetMainPort() int { return s.TCPPort } +// GetManageHost returns the manage host of the instance +func (s *TiFlashSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *TiFlashSpec) IsImported() bool { return s.Imported @@ -153,6 +162,14 @@ func (s *TiFlashSpec) IgnoreMonitorAgent() bool { return s.IgnoreExporter } +// GetSource returns source to download the component +func (s *TiFlashSpec) GetSource() string { + if s.Source == "" { + return ComponentTiFlash + } + return s.Source +} + // key names for storage config const ( TiFlashStorageKeyMainDirs string = "storage.main.dir" @@ -276,6 +293,7 @@ func (c *TiFlashComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.GetMainPort(), SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.TCPPort, @@ -291,7 +309,7 @@ func (c *TiFlashComponent) Instances() []Instance { }, StatusFn: s.Status, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.StatusPort, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.StatusPort, timeout, tlsCfg) }, }, c.Topology}) } @@ -478,6 +496,11 @@ func (i *TiFlashInstance) initTiFlashConfig(ctx context.Context, clusterVersion httpPort = fmt.Sprintf(`http_port: %d`, spec.HTTPPort) } } + 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) { + tcpPort = fmt.Sprintf(`tcp_port: %d`, spec.TCPPort) + } // set TLS configs spec.Config, err = i.setTLSConfig(ctx, enableTLS, spec.Config, paths) @@ -503,7 +526,7 @@ server_configs: listen_host: "%[7]s" tmp_path: "%[11]s" %[1]s - tcp_port: %[3]d + %[3]s %[4]s flash.tidb_status_addr: "%[5]s" flash.service_addr: "%[6]s" @@ -527,7 +550,7 @@ server_configs: `, pathConfig, paths.Log, - spec.TCPPort, + tcpPort, httpPort, strings.Join(tidbStatusAddrs, ","), utils.JoinHostPort(spec.Host, spec.FlashServicePort), @@ -868,7 +891,7 @@ func (i *TiFlashInstance) PrepareStart(ctx context.Context, tlsCfg *tls.Config) func (i *TiFlashInstance) Ready(ctx context.Context, e ctxt.Executor, timeout uint64, tlsCfg *tls.Config) error { // FIXME: the timeout is applied twice in the whole `Ready()` process, in the worst // case it might wait double time as other components - if err := PortStarted(ctx, e, i.Port, timeout); err != nil { + if err := PortStarted(ctx, e, i.GetServicePort(), timeout); err != nil { return err } @@ -876,7 +899,7 @@ func (i *TiFlashInstance) Ready(ctx context.Context, e ctxt.Executor, timeout ui if i.topo.BaseTopo().GlobalOptions.TLSEnabled { scheme = "https" } - addr := fmt.Sprintf("%s://%s/tiflash/store-status", scheme, utils.JoinHostPort(i.Host, i.GetStatusPort())) + addr := fmt.Sprintf("%s://%s/tiflash/store-status", scheme, utils.JoinHostPort(i.GetManageHost(), i.GetStatusPort())) req, err := http.NewRequest("GET", addr, nil) if err != nil { return err diff --git a/pkg/cluster/spec/tikv.go b/pkg/cluster/spec/tikv.go index 6047bc4b9f..270bae06c2 100644 --- a/pkg/cluster/spec/tikv.go +++ b/pkg/cluster/spec/tikv.go @@ -47,7 +47,7 @@ const ( // TiKVSpec represents the TiKV topology specification in topology.yaml type TiKVSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` AdvertiseAddr string `yaml:"advertise_addr,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` @@ -61,6 +61,7 @@ type TiKVSpec struct { DataDir string `yaml:"data_dir,omitempty"` LogDir string `yaml:"log_dir,omitempty"` Offline bool `yaml:"offline,omitempty"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` NumaCores string `yaml:"numa_cores,omitempty" validate:"numa_cores:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` @@ -115,6 +116,14 @@ func (s *TiKVSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *TiKVSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *TiKVSpec) IsImported() bool { return s.Imported @@ -155,6 +164,14 @@ func (s *TiKVSpec) Labels() (map[string]string, error) { return lbs, nil } +// GetSource returns source to download the component +func (s *TiKVSpec) GetSource() string { + if s.Source == "" { + return ComponentTiKV + } + return s.Source +} + // TiKVComponent represents TiKV component. type TiKVComponent struct{ Topology *Specification } @@ -181,6 +198,7 @@ func (c *TiKVComponent) Instances() []Instance { ListenHost: s.ListenHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.Source, Ports: []int{ s.Port, @@ -192,7 +210,7 @@ func (c *TiKVComponent) Instances() []Instance { }, StatusFn: s.Status, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.StatusPort, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.StatusPort, timeout, tlsCfg) }, }, c.Topology, 0}) } @@ -291,7 +309,7 @@ func (i *TiKVInstance) InitConfig( return err } - return checkConfig(ctx, e, i.ComponentName(), 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, nil) } // setTLSConfig set TLS Config to support enable/disable TLS @@ -367,7 +385,7 @@ func (i *TiKVInstance) PreRestart(ctx context.Context, topo Topology, apiTimeout return nil } - pdClient := api.NewPDClient(ctx, tidbTopo.GetPDList(), 5*time.Second, tlsCfg) + pdClient := api.NewPDClient(ctx, tidbTopo.GetPDListWithManageHost(), 5*time.Second, tlsCfg) // Make sure there's leader of PD. // Although we evict pd leader when restart pd, @@ -405,7 +423,7 @@ func (i *TiKVInstance) PostRestart(ctx context.Context, topo Topology, tlsCfg *t return nil } - pdClient := api.NewPDClient(ctx, tidbTopo.GetPDList(), 5*time.Second, tlsCfg) + pdClient := api.NewPDClient(ctx, tidbTopo.GetPDListWithManageHost(), 5*time.Second, tlsCfg) // remove store leader evict scheduler after restart if err := pdClient.RemoveStoreEvict(addr(i.InstanceSpec.(*TiKVSpec))); err != nil { @@ -443,7 +461,7 @@ func genLeaderCounter(topo *Specification, tlsCfg *tls.Config) func(string) (int for _, kv := range topo.TiKVServers { kvid := utils.JoinHostPort(kv.Host, kv.Port) if id == kvid { - statusAddress = utils.JoinHostPort(kv.Host, kv.StatusPort) + statusAddress = utils.JoinHostPort(kv.GetManageHost(), kv.StatusPort) break } foundIds = append(foundIds, kvid) diff --git a/pkg/cluster/spec/tikv_cdc.go b/pkg/cluster/spec/tikv_cdc.go index c2eca361bc..55c393d099 100644 --- a/pkg/cluster/spec/tikv_cdc.go +++ b/pkg/cluster/spec/tikv_cdc.go @@ -34,7 +34,7 @@ import ( // TiKVCDCSpec represents the TiKVCDC topology specification in topology.yaml type TiKVCDCSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` Patched bool `yaml:"patched,omitempty"` @@ -46,6 +46,7 @@ type TiKVCDCSpec struct { Offline bool `yaml:"offline,omitempty"` GCTTL int64 `yaml:"gc-ttl,omitempty" validate:"gc-ttl:editable"` TZ string `yaml:"tz,omitempty" validate:"tz:editable"` + Source string `yaml:"source,omitempty" validate:"source:editable"` NumaNode string `yaml:"numa_node,omitempty" validate:"numa_node:editable"` Config map[string]any `yaml:"config,omitempty" validate:"config:ignore"` ResourceControl meta.ResourceControl `yaml:"resource_control,omitempty" validate:"resource_control:editable"` @@ -72,6 +73,14 @@ func (s *TiKVCDCSpec) GetMainPort() int { return s.Port } +// GetManageHost returns the manage host of the instance +func (s *TiKVCDCSpec) GetManageHost() string { + if s.ManageHost != "" { + return s.ManageHost + } + return s.Host +} + // IsImported returns if the node is imported from TiDB-Ansible func (s *TiKVCDCSpec) IsImported() bool { // TiDB-Ansible do not support TiKV-CDC @@ -96,6 +105,14 @@ func (c *TiKVCDCComponent) Role() string { return ComponentTiKVCDC } +// GetSource returns source to download the component +func (s *TiKVCDCSpec) GetSource() string { + if s.Source == "" { + return ComponentTiKVCDC + } + return s.Source +} + // Instances implements Component interface. func (c *TiKVCDCComponent) Instances() []Instance { ins := make([]Instance, 0, len(c.Topology.TiKVCDCServers)) @@ -108,6 +125,7 @@ func (c *TiKVCDCComponent) Instances() []Instance { ManageHost: s.ManageHost, Port: s.Port, SSHP: s.SSHPort, + Source: s.GetSource(), Ports: []int{ s.Port, @@ -116,10 +134,10 @@ func (c *TiKVCDCComponent) Instances() []Instance { s.DeployDir, }, StatusFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config, _ ...string) string { - return statusByHost(s.Host, s.Port, "/status", timeout, tlsCfg) + return statusByHost(s.GetManageHost(), s.Port, "/status", timeout, tlsCfg) }, UptimeFn: func(_ context.Context, timeout time.Duration, tlsCfg *tls.Config) time.Duration { - return UptimeByHost(s.Host, s.Port, timeout, tlsCfg) + return UptimeByHost(s.GetManageHost(), s.Port, timeout, tlsCfg) }, }, c.Topology} if s.DataDir != "" { diff --git a/pkg/cluster/spec/tispark.go b/pkg/cluster/spec/tispark.go index 11a447c0e1..bacd9f4b04 100644 --- a/pkg/cluster/spec/tispark.go +++ b/pkg/cluster/spec/tispark.go @@ -37,7 +37,7 @@ import ( // TiSparkMasterSpec is the topology specification for TiSpark master node type TiSparkMasterSpec struct { Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` Imported bool `yaml:"imported,omitempty"` diff --git a/pkg/cluster/task/builder.go b/pkg/cluster/task/builder.go index 9a5bbbfab8..6f8973b191 100644 --- a/pkg/cluster/task/builder.go +++ b/pkg/cluster/task/builder.go @@ -253,7 +253,7 @@ func (b *Builder) InitConfig(clusterName, clusterVersion string, specManager *sp if err := specManager.Metadata(clusterName, meta); err == nil { // get nightly version if clusterVersion == utils.NightlyVersionAlias { - componentVersion, _, err = environment.GlobalEnv().V1Repository().LatestNightlyVersion(inst.ComponentName()) + componentVersion, _, err = environment.GlobalEnv().V1Repository().LatestNightlyVersion(inst.ComponentSource()) if err != nil { componentVersion = utils.Version(clusterVersion) } diff --git a/pkg/repository/testdata/manifests/root.json b/pkg/repository/testdata/manifests/root.json index eb7de68e7b..ca16fcc0cb 100644 --- a/pkg/repository/testdata/manifests/root.json +++ b/pkg/repository/testdata/manifests/root.json @@ -1 +1 @@ -{"signatures":[{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"aptcBUxk5mIY3a2lqNChLU6dXUP/tcaIiwv7e/nQFZjsL3YOm9VG8OQzc4Sy+sv1DqFDvmwNZVp4FyfbPluXRyRgMRYJ194Z9Z1GXHQBmaWaVhMX9qpwzcSe8XNsReaDugHl+iJYfFif34vVm6fbhQgwxggXgJ37TbScVe3OB4LZ7RuSo3RExj3ojMkZr5wWtb4nFKd0VwfGH7KROmz06Pdok/k5PmI7spBLCFUWSAheVThA4jFXtlFPXGmbgBnPMRaRR5uWf59QFD0YQ4xTsJvWLHVmLtIgvDQnouVKYURXooCbYj/OfnvWIQIy3HzuEJC09ZQJokzpluhXaI8J+g=="},{"keyid":"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e","sig":"wENeklsuDdoRNLCvvzsD3sJRymbAjMNT/ZTWsPX7tdPtfvq6+jyvvAgXiPMM92Kvb/WUVjBp5lwD5txGfD/2QLWRER9eDbz0XoZ1hGbAERQCWW7BZIc0tgc7EDLoPUxNQBMVYvHi1XTn1kEZqXHu8lrDLSpL2jIRMJOuLqJv6mmBraxGOc+loIwH2hQkXCvp8C8fW9M/bK5YKzuV3FafKyLuCkqMV7AIkKH2PztPXEVDQ3Mhrxzz9P1q7d6E07Hee9FP/xSm2B4MR9eqHiQTJW+aH/9BI60OaWLNxOg2GEr3t72j7mgDZq4d5i99zWwDG3YyWNw7AXtcuPPvKl6Vzg=="},{"keyid":"818c3ab5ddd59a79d4cff76ebb594be56e5a630c05cfcae382f32e07899e7ab7","sig":"PVoqno+m+HiHzkE+wMskafuHU/WUGw/eT/QRkXKgmAdDce6C5yvEVM1H37OpMPvfAjf70Q9opdaxBpkiTo3637EJbHGo7Eqs61hyIYecbYP9/LMinBSQZNOaTdtMUMYB28Cm9rERZCekxs2izLnkwX0py+V3IvfATOKy8jes13fiUF44A27J0X0n8601WicrOrDK37c0pSg66sd4xg5TucMcDsdxlGRW6+puvXLjAt2xk+qHSzbFEoMramfagWBF+hveKcv+buoZ81+f/H+3VBiNAxtTQLgDDqHI5IqAf1HlT20ThNimmN9q8bonirxYx6xhn0y4HvXLOn6nwMrqLQ=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"VOIfdL0qGiHvHmCAu4vLG2s5Ny1+zBZ7ZovPFo8eJT8ppquUDR7POzNBlk+xgteCfUFx56imsvBxKu77zCIe2yT2FcwYdpzcDzaJqOxsEhdusZa7gXdvDVs+JYoZMtRWrjo9InfXVpT8s8SOKglQAnuwcS5/Y+5T5czdXqeWOW9Lnk0Xpt09PUrW3tqrVKhWq1WqRSIayCNV1nnlM3Tj2240DiuYiTEIZn95p8ThB0ZzNLPVNzrvs5/7ZjTdmYCeDSNRwseHO3XFPUOtApEvSWNwjhH4x/YJOo64hqwnaO99utN4jGOKcXkHwQpKPDWKRecgo5+n8VzEZeA+XKLvow=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"QkVHaGa0K8UBc146leEndu2RFQY6tBzoZXGQ9osUyzLVpn3706LLxwD70zOqDhKHaWnnyf5sd3wJrzlhHXjpz3p380xgparaSyEky5d7OB7s5mBToy2bnA7f85IX3sRq7eyb4gcZfFTiZaTT+ygWzPClJaZsiF8p+XzQSkBXXycn3xl8XKtP81+CQOwhdhF9l1oXSEVFKjwMZC9WG4X9ipLS1MPr7J08YVxiMpMKiXtTQtlPdbqP1r65dWDtdJ1y7zMcatWjYGY4JakIrawIcfYJlYrMpAGUzyxx/Tm21d85b+NzyNN7sMpoUKLNHS3vUHOD2a9vSCiwFTjIrsxJDQ=="}],"signed":{"_type":"root","expires":"2023-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"818c3ab5ddd59a79d4cff76ebb594be56e5a630c05cfcae382f32e07899e7ab7":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA37V4zn8sYuhC5HbIos/6\nf3zhnr7WSnV0GtrOj2q6tCvo/1rGXDKbL8KJgLBHcQT6P732sm5BmZ+y8hRXZDqy\njTBqT70Vc0fGfCkH5Z0FU8WWlhQ2Ck3W20TxXPJY7p+wnuUCmcLzD7cKwUGOshjs\nyozqAMQ7C/HSmJFCUY8PaASvQCCg/YyMr3Ft8xpyc5IGmIi4NkVjf/JWIUFFv7kr\nIkRbT5K1nKJ2earot1TIcWUY2O4OvbhtueJ+IN0Lkdg+v98W/pvlF+ji24DBlcGw\nLdOeGRt5z6GnHKlAuZ/tbjRHeXnq1KxMETlXCgu2xCwsSK/10SE8oTaXbFoMHNBN\nAQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kgU3v3SxYzm5J6P+GPP\nmy6toBnKYtTViAVmpUJiIEjdZ9NLpoJU0na9q0CD8sIgo2Js/W/owJUvSj6rm8us\nsu/Ve5KsoJN6zca2am1uZ5IKnc48i0mCv76WXawCxM+NFGqSCMJcltlhj3fC/GDS\ngu+BiIbrgR1PgJf6Jk6l7uMJdN3TL6JJQcEC4lz+2hj5zoVNYkq06ZC79j2tPDCI\nkTAYGF/TAAVLH08/kGH5ZeRPlVKJ7cwW3OniLM5NeFnS8+shRNb6AYr7xju3Ikbw\nDo14ipIghBI0iAxn6Lvr/iilc7TM7RWJ4OiTrmK3SQSJ+U6H2N2/I5OGEHBEKzbA\nOQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":3}} \ No newline at end of file +{"signatures":[{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"kJdviRCj2xr6Mqb8maOJZUnBgHJqLI5V2MqhQL9mxqsHFE/6z3bmT1OIpaG31b0COhIg0gtR60Y/rUu1YRTs8UpUJa+9bHVcLxrg6PuewzT34ZjtsGpQ8PDhe2j99EULN85rq7jV+HRwdZLHVZXI1P25I0wy1AGtprVo13ZB4h5CBy4ZEUlmae0QKbH+Ej9ouVaeBlyw1JHLew8I1eWEj7x9WYMkO6spqDtPhrIYjqxnh9zUBAvMNQzv3ysu0KM+D4Pr6kALRE9G3AMmbCEzhy+C+r/FT7egNv28kJvxoQjgfEMABYLgLU/Gp7qRVbEbthH4XI8IohmiCH6NavQKBA=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"cQAJkEEpUdauI7TN2nrEF/wZbPKa/Rhu/xEDZgm5tBAc0LKhD48aLH0VdxapytSf1IWk+MatEK/vVMA2sppqrJTGyJ5Ue+JEUe+JhcTAFW0sUzTHUgR5ARTFqDR0RnKysPO/a9BMZsJfyEfS2j2Nlx7iE/2PeMVc2GhhSEY+cHE000ZFXxaxuWYjYzd35LeLQotMWmtsEx0JYrqHgXzMU0yJ0QikE1JUd8uQ4LMvd53iPIEuHxKyq87oIMfvx+gKhbGvgQx3XMYI54qMP+fumPVYQ3alYX5FB+vFX2MFqzl7GxAQJCd57xsanRhKSAkG2LKvEUZuCfTtqiwqb13Lyg=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"cPqcr9zhryFMREpIm81u+vAy1anzJFEFwWk6gCSRNW8lZuGQPgF66qc09YGHe6wGFHmlAm7CTFKh561W8zJfi6IbGS7wUArkaNV5fgPkxg2FDGCC5tHs8we3fgyv+kgr6yzGwQVHl6v4J8S5bkK1MM7GbMGAP6dmf774f6ysLOkjGurAg7UwrZey8/ZQKCjzysnAxyRC+/4QhUfAC5OPs2hI+BUjPDTET3f1Icgq0f9CZfUZ4nW1utMd4/sbQKowNVfZ8j62r8awUuOGmmJbuqLs6ifkfKCXw5ZfrT9G8ySxbI8CshWd54Ck6c7WsyRjY4Y9TB+Oh3pJ+ieE91HJKg=="},{"keyid":"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c","sig":"lnfUXTabAURE8BKzbGBJ4oXtDYbpXl1hsEtzOfjJwBae+c9qMusYMR9aU3ZOm2hlAasUXf+bfIy5NoDZMuDC8roYD3UHokC2qrym1h3VgfVl1aMlWDAgtIhNQuHVbKGyPBDMW+O0gDIV2RPwTwcedZHxLbakMqgHaSI1SPFu4ryoLbOsBr2wxQSVKUXRhcvQFvgRJS884TfIYmY3v4EIHvSfHrnPmDmMFrpMUCVzseDPMG/FEWamzjk0GnRAZiwv5NVjbtIAtIUxBASZRWQr1h176k03jwPodT/iynNTNMy/2WHMwUSrVxeFB+aXI9+Pbl/OHw3UAz2qp3kS2ny0aQ=="},{"keyid":"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6","sig":"QilsuGt2x4NjB8uTQeFaUb8sfRwhwcEKGqBBAXLPtgCLm7GXxRb4RXO8nPQ0o5Kg1nZp7t899Q5nMzOO6Qc5ng3vTOwDW2cDSVhyllPKJAzgJC5uwHQdQi9y3vSiNb4j2mpkQbyfu9va5yUiAZzSoJHuRv+aperJHvv+Ev/kxqlvy/4TtXtMPebG2qc08K/WdXBA0S++oWhsC8J5mFgBJBFXFJ6ewLlRJK7DmZKEG+0vtaOeCLOsRnKFSQ3rfrMYdBnGU32+NtlmTU4rjpZ/HdSwgi4K8tDVoo1CE9EwvLvZ1oKpHyRiZWmviRCy81WVB/kpYgfSR4u1CQ02CgZVkQ=="}],"signed":{"_type":"root","expires":"2024-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApU5RHP0K+Fgkzm9L0yHR\n4CEqLLwHr7hQxjWOaq5K0UfaOKcsPQZ1SkJ/AMppz7ovzwOU4hcy0wJOV7ms6ACk\nS3hte2GlH/xp+OzWiRnI4qJ6GRrAe+ototj1ZMGvpLK4ifxkKaY6vuWFFAeS0fSe\nPHUGAl5v+PaJWgDNQTRmuAu5oCaYP6oT6VKHj6ulLAgAOqWsBSJiK3oIRcWPR+uI\nIW/9BV158wfmxAw1+7ch1RD44+1vV3+Eo94alvVZIAfcJqDS3XGr2Hfd/YWGj1d2\nD26eblBJoQt0L2E2EL8igu1sudVkMZ3NAIfmBrOWUxHEbIjYeKvXPbaSGdC+FoXD\nrwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5oDytiywLDOSpIBovZxx\nNlZJg5Gk3O9kpiOQ0XnD+L2LV+a2dJU1KmBOoGCUr2TNaGTPihAStjpFIsW4c7Ye\nB2RjUFUrXRf3mvc3n4fACayenxtnCleSR4gKkAdHqqPCiWHT5TAtybKSHuHAluUL\nkMvavUZjIPMj0YYB0R8Re7BjU+zxnipJosTbbPQ7fa3+x2VAHc066Y9qp1YucdpB\nMZ3UwtSVNK7aCbFZvKPwAm22fnDYmMbYFeTz/rrl8k+rKTM37d4D3mURC9xDJxIP\nXVaU2dBImYjoFcY0/5oBU5vr1sj2sdUH+3G5AUr6iCL+XJLiwA1x24jKA6mUjQ93\ndwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":4}} \ No newline at end of file diff --git a/pkg/repository/testdata/polluted/bin/root.json b/pkg/repository/testdata/polluted/bin/root.json index eb7de68e7b..ca16fcc0cb 100644 --- a/pkg/repository/testdata/polluted/bin/root.json +++ b/pkg/repository/testdata/polluted/bin/root.json @@ -1 +1 @@ -{"signatures":[{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"aptcBUxk5mIY3a2lqNChLU6dXUP/tcaIiwv7e/nQFZjsL3YOm9VG8OQzc4Sy+sv1DqFDvmwNZVp4FyfbPluXRyRgMRYJ194Z9Z1GXHQBmaWaVhMX9qpwzcSe8XNsReaDugHl+iJYfFif34vVm6fbhQgwxggXgJ37TbScVe3OB4LZ7RuSo3RExj3ojMkZr5wWtb4nFKd0VwfGH7KROmz06Pdok/k5PmI7spBLCFUWSAheVThA4jFXtlFPXGmbgBnPMRaRR5uWf59QFD0YQ4xTsJvWLHVmLtIgvDQnouVKYURXooCbYj/OfnvWIQIy3HzuEJC09ZQJokzpluhXaI8J+g=="},{"keyid":"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e","sig":"wENeklsuDdoRNLCvvzsD3sJRymbAjMNT/ZTWsPX7tdPtfvq6+jyvvAgXiPMM92Kvb/WUVjBp5lwD5txGfD/2QLWRER9eDbz0XoZ1hGbAERQCWW7BZIc0tgc7EDLoPUxNQBMVYvHi1XTn1kEZqXHu8lrDLSpL2jIRMJOuLqJv6mmBraxGOc+loIwH2hQkXCvp8C8fW9M/bK5YKzuV3FafKyLuCkqMV7AIkKH2PztPXEVDQ3Mhrxzz9P1q7d6E07Hee9FP/xSm2B4MR9eqHiQTJW+aH/9BI60OaWLNxOg2GEr3t72j7mgDZq4d5i99zWwDG3YyWNw7AXtcuPPvKl6Vzg=="},{"keyid":"818c3ab5ddd59a79d4cff76ebb594be56e5a630c05cfcae382f32e07899e7ab7","sig":"PVoqno+m+HiHzkE+wMskafuHU/WUGw/eT/QRkXKgmAdDce6C5yvEVM1H37OpMPvfAjf70Q9opdaxBpkiTo3637EJbHGo7Eqs61hyIYecbYP9/LMinBSQZNOaTdtMUMYB28Cm9rERZCekxs2izLnkwX0py+V3IvfATOKy8jes13fiUF44A27J0X0n8601WicrOrDK37c0pSg66sd4xg5TucMcDsdxlGRW6+puvXLjAt2xk+qHSzbFEoMramfagWBF+hveKcv+buoZ81+f/H+3VBiNAxtTQLgDDqHI5IqAf1HlT20ThNimmN9q8bonirxYx6xhn0y4HvXLOn6nwMrqLQ=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"VOIfdL0qGiHvHmCAu4vLG2s5Ny1+zBZ7ZovPFo8eJT8ppquUDR7POzNBlk+xgteCfUFx56imsvBxKu77zCIe2yT2FcwYdpzcDzaJqOxsEhdusZa7gXdvDVs+JYoZMtRWrjo9InfXVpT8s8SOKglQAnuwcS5/Y+5T5czdXqeWOW9Lnk0Xpt09PUrW3tqrVKhWq1WqRSIayCNV1nnlM3Tj2240DiuYiTEIZn95p8ThB0ZzNLPVNzrvs5/7ZjTdmYCeDSNRwseHO3XFPUOtApEvSWNwjhH4x/YJOo64hqwnaO99utN4jGOKcXkHwQpKPDWKRecgo5+n8VzEZeA+XKLvow=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"QkVHaGa0K8UBc146leEndu2RFQY6tBzoZXGQ9osUyzLVpn3706LLxwD70zOqDhKHaWnnyf5sd3wJrzlhHXjpz3p380xgparaSyEky5d7OB7s5mBToy2bnA7f85IX3sRq7eyb4gcZfFTiZaTT+ygWzPClJaZsiF8p+XzQSkBXXycn3xl8XKtP81+CQOwhdhF9l1oXSEVFKjwMZC9WG4X9ipLS1MPr7J08YVxiMpMKiXtTQtlPdbqP1r65dWDtdJ1y7zMcatWjYGY4JakIrawIcfYJlYrMpAGUzyxx/Tm21d85b+NzyNN7sMpoUKLNHS3vUHOD2a9vSCiwFTjIrsxJDQ=="}],"signed":{"_type":"root","expires":"2023-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"818c3ab5ddd59a79d4cff76ebb594be56e5a630c05cfcae382f32e07899e7ab7":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA37V4zn8sYuhC5HbIos/6\nf3zhnr7WSnV0GtrOj2q6tCvo/1rGXDKbL8KJgLBHcQT6P732sm5BmZ+y8hRXZDqy\njTBqT70Vc0fGfCkH5Z0FU8WWlhQ2Ck3W20TxXPJY7p+wnuUCmcLzD7cKwUGOshjs\nyozqAMQ7C/HSmJFCUY8PaASvQCCg/YyMr3Ft8xpyc5IGmIi4NkVjf/JWIUFFv7kr\nIkRbT5K1nKJ2earot1TIcWUY2O4OvbhtueJ+IN0Lkdg+v98W/pvlF+ji24DBlcGw\nLdOeGRt5z6GnHKlAuZ/tbjRHeXnq1KxMETlXCgu2xCwsSK/10SE8oTaXbFoMHNBN\nAQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kgU3v3SxYzm5J6P+GPP\nmy6toBnKYtTViAVmpUJiIEjdZ9NLpoJU0na9q0CD8sIgo2Js/W/owJUvSj6rm8us\nsu/Ve5KsoJN6zca2am1uZ5IKnc48i0mCv76WXawCxM+NFGqSCMJcltlhj3fC/GDS\ngu+BiIbrgR1PgJf6Jk6l7uMJdN3TL6JJQcEC4lz+2hj5zoVNYkq06ZC79j2tPDCI\nkTAYGF/TAAVLH08/kGH5ZeRPlVKJ7cwW3OniLM5NeFnS8+shRNb6AYr7xju3Ikbw\nDo14ipIghBI0iAxn6Lvr/iilc7TM7RWJ4OiTrmK3SQSJ+U6H2N2/I5OGEHBEKzbA\nOQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":3}} \ No newline at end of file +{"signatures":[{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"kJdviRCj2xr6Mqb8maOJZUnBgHJqLI5V2MqhQL9mxqsHFE/6z3bmT1OIpaG31b0COhIg0gtR60Y/rUu1YRTs8UpUJa+9bHVcLxrg6PuewzT34ZjtsGpQ8PDhe2j99EULN85rq7jV+HRwdZLHVZXI1P25I0wy1AGtprVo13ZB4h5CBy4ZEUlmae0QKbH+Ej9ouVaeBlyw1JHLew8I1eWEj7x9WYMkO6spqDtPhrIYjqxnh9zUBAvMNQzv3ysu0KM+D4Pr6kALRE9G3AMmbCEzhy+C+r/FT7egNv28kJvxoQjgfEMABYLgLU/Gp7qRVbEbthH4XI8IohmiCH6NavQKBA=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"cQAJkEEpUdauI7TN2nrEF/wZbPKa/Rhu/xEDZgm5tBAc0LKhD48aLH0VdxapytSf1IWk+MatEK/vVMA2sppqrJTGyJ5Ue+JEUe+JhcTAFW0sUzTHUgR5ARTFqDR0RnKysPO/a9BMZsJfyEfS2j2Nlx7iE/2PeMVc2GhhSEY+cHE000ZFXxaxuWYjYzd35LeLQotMWmtsEx0JYrqHgXzMU0yJ0QikE1JUd8uQ4LMvd53iPIEuHxKyq87oIMfvx+gKhbGvgQx3XMYI54qMP+fumPVYQ3alYX5FB+vFX2MFqzl7GxAQJCd57xsanRhKSAkG2LKvEUZuCfTtqiwqb13Lyg=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"cPqcr9zhryFMREpIm81u+vAy1anzJFEFwWk6gCSRNW8lZuGQPgF66qc09YGHe6wGFHmlAm7CTFKh561W8zJfi6IbGS7wUArkaNV5fgPkxg2FDGCC5tHs8we3fgyv+kgr6yzGwQVHl6v4J8S5bkK1MM7GbMGAP6dmf774f6ysLOkjGurAg7UwrZey8/ZQKCjzysnAxyRC+/4QhUfAC5OPs2hI+BUjPDTET3f1Icgq0f9CZfUZ4nW1utMd4/sbQKowNVfZ8j62r8awUuOGmmJbuqLs6ifkfKCXw5ZfrT9G8ySxbI8CshWd54Ck6c7WsyRjY4Y9TB+Oh3pJ+ieE91HJKg=="},{"keyid":"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c","sig":"lnfUXTabAURE8BKzbGBJ4oXtDYbpXl1hsEtzOfjJwBae+c9qMusYMR9aU3ZOm2hlAasUXf+bfIy5NoDZMuDC8roYD3UHokC2qrym1h3VgfVl1aMlWDAgtIhNQuHVbKGyPBDMW+O0gDIV2RPwTwcedZHxLbakMqgHaSI1SPFu4ryoLbOsBr2wxQSVKUXRhcvQFvgRJS884TfIYmY3v4EIHvSfHrnPmDmMFrpMUCVzseDPMG/FEWamzjk0GnRAZiwv5NVjbtIAtIUxBASZRWQr1h176k03jwPodT/iynNTNMy/2WHMwUSrVxeFB+aXI9+Pbl/OHw3UAz2qp3kS2ny0aQ=="},{"keyid":"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6","sig":"QilsuGt2x4NjB8uTQeFaUb8sfRwhwcEKGqBBAXLPtgCLm7GXxRb4RXO8nPQ0o5Kg1nZp7t899Q5nMzOO6Qc5ng3vTOwDW2cDSVhyllPKJAzgJC5uwHQdQi9y3vSiNb4j2mpkQbyfu9va5yUiAZzSoJHuRv+aperJHvv+Ev/kxqlvy/4TtXtMPebG2qc08K/WdXBA0S++oWhsC8J5mFgBJBFXFJ6ewLlRJK7DmZKEG+0vtaOeCLOsRnKFSQ3rfrMYdBnGU32+NtlmTU4rjpZ/HdSwgi4K8tDVoo1CE9EwvLvZ1oKpHyRiZWmviRCy81WVB/kpYgfSR4u1CQ02CgZVkQ=="}],"signed":{"_type":"root","expires":"2024-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApU5RHP0K+Fgkzm9L0yHR\n4CEqLLwHr7hQxjWOaq5K0UfaOKcsPQZ1SkJ/AMppz7ovzwOU4hcy0wJOV7ms6ACk\nS3hte2GlH/xp+OzWiRnI4qJ6GRrAe+ototj1ZMGvpLK4ifxkKaY6vuWFFAeS0fSe\nPHUGAl5v+PaJWgDNQTRmuAu5oCaYP6oT6VKHj6ulLAgAOqWsBSJiK3oIRcWPR+uI\nIW/9BV158wfmxAw1+7ch1RD44+1vV3+Eo94alvVZIAfcJqDS3XGr2Hfd/YWGj1d2\nD26eblBJoQt0L2E2EL8igu1sudVkMZ3NAIfmBrOWUxHEbIjYeKvXPbaSGdC+FoXD\nrwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5oDytiywLDOSpIBovZxx\nNlZJg5Gk3O9kpiOQ0XnD+L2LV+a2dJU1KmBOoGCUr2TNaGTPihAStjpFIsW4c7Ye\nB2RjUFUrXRf3mvc3n4fACayenxtnCleSR4gKkAdHqqPCiWHT5TAtybKSHuHAluUL\nkMvavUZjIPMj0YYB0R8Re7BjU+zxnipJosTbbPQ7fa3+x2VAHc066Y9qp1YucdpB\nMZ3UwtSVNK7aCbFZvKPwAm22fnDYmMbYFeTz/rrl8k+rKTM37d4D3mURC9xDJxIP\nXVaU2dBImYjoFcY0/5oBU5vr1sj2sdUH+3G5AUr6iCL+XJLiwA1x24jKA6mUjQ93\ndwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":4}} \ No newline at end of file diff --git a/pkg/repository/v1manifest/testdata/polluted/bin/root.json b/pkg/repository/v1manifest/testdata/polluted/bin/root.json index eb7de68e7b..ca16fcc0cb 100644 --- a/pkg/repository/v1manifest/testdata/polluted/bin/root.json +++ b/pkg/repository/v1manifest/testdata/polluted/bin/root.json @@ -1 +1 @@ -{"signatures":[{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"aptcBUxk5mIY3a2lqNChLU6dXUP/tcaIiwv7e/nQFZjsL3YOm9VG8OQzc4Sy+sv1DqFDvmwNZVp4FyfbPluXRyRgMRYJ194Z9Z1GXHQBmaWaVhMX9qpwzcSe8XNsReaDugHl+iJYfFif34vVm6fbhQgwxggXgJ37TbScVe3OB4LZ7RuSo3RExj3ojMkZr5wWtb4nFKd0VwfGH7KROmz06Pdok/k5PmI7spBLCFUWSAheVThA4jFXtlFPXGmbgBnPMRaRR5uWf59QFD0YQ4xTsJvWLHVmLtIgvDQnouVKYURXooCbYj/OfnvWIQIy3HzuEJC09ZQJokzpluhXaI8J+g=="},{"keyid":"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e","sig":"wENeklsuDdoRNLCvvzsD3sJRymbAjMNT/ZTWsPX7tdPtfvq6+jyvvAgXiPMM92Kvb/WUVjBp5lwD5txGfD/2QLWRER9eDbz0XoZ1hGbAERQCWW7BZIc0tgc7EDLoPUxNQBMVYvHi1XTn1kEZqXHu8lrDLSpL2jIRMJOuLqJv6mmBraxGOc+loIwH2hQkXCvp8C8fW9M/bK5YKzuV3FafKyLuCkqMV7AIkKH2PztPXEVDQ3Mhrxzz9P1q7d6E07Hee9FP/xSm2B4MR9eqHiQTJW+aH/9BI60OaWLNxOg2GEr3t72j7mgDZq4d5i99zWwDG3YyWNw7AXtcuPPvKl6Vzg=="},{"keyid":"818c3ab5ddd59a79d4cff76ebb594be56e5a630c05cfcae382f32e07899e7ab7","sig":"PVoqno+m+HiHzkE+wMskafuHU/WUGw/eT/QRkXKgmAdDce6C5yvEVM1H37OpMPvfAjf70Q9opdaxBpkiTo3637EJbHGo7Eqs61hyIYecbYP9/LMinBSQZNOaTdtMUMYB28Cm9rERZCekxs2izLnkwX0py+V3IvfATOKy8jes13fiUF44A27J0X0n8601WicrOrDK37c0pSg66sd4xg5TucMcDsdxlGRW6+puvXLjAt2xk+qHSzbFEoMramfagWBF+hveKcv+buoZ81+f/H+3VBiNAxtTQLgDDqHI5IqAf1HlT20ThNimmN9q8bonirxYx6xhn0y4HvXLOn6nwMrqLQ=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"VOIfdL0qGiHvHmCAu4vLG2s5Ny1+zBZ7ZovPFo8eJT8ppquUDR7POzNBlk+xgteCfUFx56imsvBxKu77zCIe2yT2FcwYdpzcDzaJqOxsEhdusZa7gXdvDVs+JYoZMtRWrjo9InfXVpT8s8SOKglQAnuwcS5/Y+5T5czdXqeWOW9Lnk0Xpt09PUrW3tqrVKhWq1WqRSIayCNV1nnlM3Tj2240DiuYiTEIZn95p8ThB0ZzNLPVNzrvs5/7ZjTdmYCeDSNRwseHO3XFPUOtApEvSWNwjhH4x/YJOo64hqwnaO99utN4jGOKcXkHwQpKPDWKRecgo5+n8VzEZeA+XKLvow=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"QkVHaGa0K8UBc146leEndu2RFQY6tBzoZXGQ9osUyzLVpn3706LLxwD70zOqDhKHaWnnyf5sd3wJrzlhHXjpz3p380xgparaSyEky5d7OB7s5mBToy2bnA7f85IX3sRq7eyb4gcZfFTiZaTT+ygWzPClJaZsiF8p+XzQSkBXXycn3xl8XKtP81+CQOwhdhF9l1oXSEVFKjwMZC9WG4X9ipLS1MPr7J08YVxiMpMKiXtTQtlPdbqP1r65dWDtdJ1y7zMcatWjYGY4JakIrawIcfYJlYrMpAGUzyxx/Tm21d85b+NzyNN7sMpoUKLNHS3vUHOD2a9vSCiwFTjIrsxJDQ=="}],"signed":{"_type":"root","expires":"2023-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"818c3ab5ddd59a79d4cff76ebb594be56e5a630c05cfcae382f32e07899e7ab7":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA37V4zn8sYuhC5HbIos/6\nf3zhnr7WSnV0GtrOj2q6tCvo/1rGXDKbL8KJgLBHcQT6P732sm5BmZ+y8hRXZDqy\njTBqT70Vc0fGfCkH5Z0FU8WWlhQ2Ck3W20TxXPJY7p+wnuUCmcLzD7cKwUGOshjs\nyozqAMQ7C/HSmJFCUY8PaASvQCCg/YyMr3Ft8xpyc5IGmIi4NkVjf/JWIUFFv7kr\nIkRbT5K1nKJ2earot1TIcWUY2O4OvbhtueJ+IN0Lkdg+v98W/pvlF+ji24DBlcGw\nLdOeGRt5z6GnHKlAuZ/tbjRHeXnq1KxMETlXCgu2xCwsSK/10SE8oTaXbFoMHNBN\nAQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kgU3v3SxYzm5J6P+GPP\nmy6toBnKYtTViAVmpUJiIEjdZ9NLpoJU0na9q0CD8sIgo2Js/W/owJUvSj6rm8us\nsu/Ve5KsoJN6zca2am1uZ5IKnc48i0mCv76WXawCxM+NFGqSCMJcltlhj3fC/GDS\ngu+BiIbrgR1PgJf6Jk6l7uMJdN3TL6JJQcEC4lz+2hj5zoVNYkq06ZC79j2tPDCI\nkTAYGF/TAAVLH08/kGH5ZeRPlVKJ7cwW3OniLM5NeFnS8+shRNb6AYr7xju3Ikbw\nDo14ipIghBI0iAxn6Lvr/iilc7TM7RWJ4OiTrmK3SQSJ+U6H2N2/I5OGEHBEKzbA\nOQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":3}} \ No newline at end of file +{"signatures":[{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"kJdviRCj2xr6Mqb8maOJZUnBgHJqLI5V2MqhQL9mxqsHFE/6z3bmT1OIpaG31b0COhIg0gtR60Y/rUu1YRTs8UpUJa+9bHVcLxrg6PuewzT34ZjtsGpQ8PDhe2j99EULN85rq7jV+HRwdZLHVZXI1P25I0wy1AGtprVo13ZB4h5CBy4ZEUlmae0QKbH+Ej9ouVaeBlyw1JHLew8I1eWEj7x9WYMkO6spqDtPhrIYjqxnh9zUBAvMNQzv3ysu0KM+D4Pr6kALRE9G3AMmbCEzhy+C+r/FT7egNv28kJvxoQjgfEMABYLgLU/Gp7qRVbEbthH4XI8IohmiCH6NavQKBA=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"cQAJkEEpUdauI7TN2nrEF/wZbPKa/Rhu/xEDZgm5tBAc0LKhD48aLH0VdxapytSf1IWk+MatEK/vVMA2sppqrJTGyJ5Ue+JEUe+JhcTAFW0sUzTHUgR5ARTFqDR0RnKysPO/a9BMZsJfyEfS2j2Nlx7iE/2PeMVc2GhhSEY+cHE000ZFXxaxuWYjYzd35LeLQotMWmtsEx0JYrqHgXzMU0yJ0QikE1JUd8uQ4LMvd53iPIEuHxKyq87oIMfvx+gKhbGvgQx3XMYI54qMP+fumPVYQ3alYX5FB+vFX2MFqzl7GxAQJCd57xsanRhKSAkG2LKvEUZuCfTtqiwqb13Lyg=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"cPqcr9zhryFMREpIm81u+vAy1anzJFEFwWk6gCSRNW8lZuGQPgF66qc09YGHe6wGFHmlAm7CTFKh561W8zJfi6IbGS7wUArkaNV5fgPkxg2FDGCC5tHs8we3fgyv+kgr6yzGwQVHl6v4J8S5bkK1MM7GbMGAP6dmf774f6ysLOkjGurAg7UwrZey8/ZQKCjzysnAxyRC+/4QhUfAC5OPs2hI+BUjPDTET3f1Icgq0f9CZfUZ4nW1utMd4/sbQKowNVfZ8j62r8awUuOGmmJbuqLs6ifkfKCXw5ZfrT9G8ySxbI8CshWd54Ck6c7WsyRjY4Y9TB+Oh3pJ+ieE91HJKg=="},{"keyid":"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c","sig":"lnfUXTabAURE8BKzbGBJ4oXtDYbpXl1hsEtzOfjJwBae+c9qMusYMR9aU3ZOm2hlAasUXf+bfIy5NoDZMuDC8roYD3UHokC2qrym1h3VgfVl1aMlWDAgtIhNQuHVbKGyPBDMW+O0gDIV2RPwTwcedZHxLbakMqgHaSI1SPFu4ryoLbOsBr2wxQSVKUXRhcvQFvgRJS884TfIYmY3v4EIHvSfHrnPmDmMFrpMUCVzseDPMG/FEWamzjk0GnRAZiwv5NVjbtIAtIUxBASZRWQr1h176k03jwPodT/iynNTNMy/2WHMwUSrVxeFB+aXI9+Pbl/OHw3UAz2qp3kS2ny0aQ=="},{"keyid":"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6","sig":"QilsuGt2x4NjB8uTQeFaUb8sfRwhwcEKGqBBAXLPtgCLm7GXxRb4RXO8nPQ0o5Kg1nZp7t899Q5nMzOO6Qc5ng3vTOwDW2cDSVhyllPKJAzgJC5uwHQdQi9y3vSiNb4j2mpkQbyfu9va5yUiAZzSoJHuRv+aperJHvv+Ev/kxqlvy/4TtXtMPebG2qc08K/WdXBA0S++oWhsC8J5mFgBJBFXFJ6ewLlRJK7DmZKEG+0vtaOeCLOsRnKFSQ3rfrMYdBnGU32+NtlmTU4rjpZ/HdSwgi4K8tDVoo1CE9EwvLvZ1oKpHyRiZWmviRCy81WVB/kpYgfSR4u1CQ02CgZVkQ=="}],"signed":{"_type":"root","expires":"2024-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApU5RHP0K+Fgkzm9L0yHR\n4CEqLLwHr7hQxjWOaq5K0UfaOKcsPQZ1SkJ/AMppz7ovzwOU4hcy0wJOV7ms6ACk\nS3hte2GlH/xp+OzWiRnI4qJ6GRrAe+ototj1ZMGvpLK4ifxkKaY6vuWFFAeS0fSe\nPHUGAl5v+PaJWgDNQTRmuAu5oCaYP6oT6VKHj6ulLAgAOqWsBSJiK3oIRcWPR+uI\nIW/9BV158wfmxAw1+7ch1RD44+1vV3+Eo94alvVZIAfcJqDS3XGr2Hfd/YWGj1d2\nD26eblBJoQt0L2E2EL8igu1sudVkMZ3NAIfmBrOWUxHEbIjYeKvXPbaSGdC+FoXD\nrwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5oDytiywLDOSpIBovZxx\nNlZJg5Gk3O9kpiOQ0XnD+L2LV+a2dJU1KmBOoGCUr2TNaGTPihAStjpFIsW4c7Ye\nB2RjUFUrXRf3mvc3n4fACayenxtnCleSR4gKkAdHqqPCiWHT5TAtybKSHuHAluUL\nkMvavUZjIPMj0YYB0R8Re7BjU+zxnipJosTbbPQ7fa3+x2VAHc066Y9qp1YucdpB\nMZ3UwtSVNK7aCbFZvKPwAm22fnDYmMbYFeTz/rrl8k+rKTM37d4D3mURC9xDJxIP\nXVaU2dBImYjoFcY0/5oBU5vr1sj2sdUH+3G5AUr6iCL+XJLiwA1x24jKA6mUjQ93\ndwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":4}} \ No newline at end of file diff --git a/pkg/tidbver/tidbver.go b/pkg/tidbver/tidbver.go index f9807fe494..01cdca48ad 100644 --- a/pkg/tidbver/tidbver.go +++ b/pkg/tidbver/tidbver.go @@ -66,6 +66,15 @@ func TiFlashNotNeedHTTPPortConfig(version string) bool { return semver.Compare(version, "v7.1.0") >= 0 || strings.Contains(version, "nightly") } +// TiFlashRequiresTCPPortConfig return if given version of TiFlash requires tcp_port config. +// TiFlash 7.1.0 and later versions won't listen to tpc_port if the config is not given, which is recommended. +// However this config is required for pre-7.1.0 versions because TiFlash will listen to it anyway, +// and we must make sure the port is being configured as specified in the topology file, +// otherwise multiple TiFlash instances will conflict. +func TiFlashRequiresTCPPortConfig(version string) bool { + return semver.Compare(version, "v7.1.0") < 0 && !strings.Contains(version, "nightly") +} + // TiFlashNotNeedSomeConfig return if given version of TiFlash do not need some config like runAsDaemon func TiFlashNotNeedSomeConfig(version string) bool { // https://github.com/pingcap/tiup/pull/1673 @@ -84,6 +93,11 @@ func TiDBSupportDisagg(version string) bool { return semver.Compare(version, "v7.0.0") >= 0 || strings.Contains(version, "nightly") } +// PDSupportMicroServices returns true if the given version of PD supports micro services. +func PDSupportMicroServices(version string) bool { + return semver.Compare(version, "v7.3.0") >= 0 || strings.Contains(version, "nightly") +} + // TiCDCSupportConfigFile return if given version of TiCDC support config file func TiCDCSupportConfigFile(version string) bool { // config support since v4.0.13, ignore v5.0.0-rc diff --git a/pkg/tui/progress/display_props.go b/pkg/tui/progress/display_props.go index 48dd5d2462..5e01a62734 100644 --- a/pkg/tui/progress/display_props.go +++ b/pkg/tui/progress/display_props.go @@ -96,6 +96,7 @@ type DisplayProps struct { Prefix string `json:"prefix,omitempty"` Suffix string `json:"suffix,omitempty"` // If `Mode == Done / Error`, Suffix is not printed Mode Mode `json:"mode,omitempty"` + Detail string `json:"detail,omitempty"` } // String implements string diff --git a/pkg/tui/progress/example_single_bar_test.go b/pkg/tui/progress/example_single_bar_test.go index 0c1f66724a..514a91796f 100644 --- a/pkg/tui/progress/example_single_bar_test.go +++ b/pkg/tui/progress/example_single_bar_test.go @@ -1,6 +1,7 @@ package progress_test import ( + "errors" "strconv" "testing" "time" @@ -42,9 +43,44 @@ func ExampleSingleBar() { b.StopRenderLoop() } +func ExampleSingleBar_err() { + b := progress.NewSingleBar("Prefix") + + b.UpdateDisplay(&progress.DisplayProps{ + Prefix: "Prefix", + Suffix: "Suffix", + }) + + n := 3 + + go func() { + time.Sleep(time.Second) + for i := 0; i < n; i++ { + b.UpdateDisplay(&progress.DisplayProps{ + Prefix: "Prefix" + strconv.Itoa(i), + Suffix: "Suffix" + strconv.Itoa(i), + }) + time.Sleep(time.Second) + } + }() + + b.StartRenderLoop() + + time.Sleep(time.Second * time.Duration(n+1)) + + b.UpdateDisplay(&progress.DisplayProps{ + Mode: progress.ModeError, + Prefix: "Prefix", + Detail: errors.New("expected failure").Error(), + }) + + b.StopRenderLoop() +} + func TestExampleOutput(t *testing.T) { if !testing.Verbose() { return } ExampleSingleBar() + ExampleSingleBar_err() } diff --git a/pkg/tui/progress/single_bar.go b/pkg/tui/progress/single_bar.go index 854f27c160..1f5a454c4e 100644 --- a/pkg/tui/progress/single_bar.go +++ b/pkg/tui/progress/single_bar.go @@ -31,7 +31,7 @@ type singleBarCore struct { func (b *singleBarCore) renderDoneOrError(w io.Writer, dp *DisplayProps) { width := int(termSizeWidth.Load()) - var tail string + var tail, detail string var tailColor *color.Color switch dp.Mode { case ModeDone: @@ -51,7 +51,10 @@ func (b *singleBarCore) renderDoneOrError(w io.Writer, dp *DisplayProps) { } else { displayPrefix = runewidth.Truncate(dp.Prefix, width-prefixWidth, "") } - _, _ = fmt.Fprintf(w, "%s ... %s", displayPrefix, tailColor.Sprint(tail)) + if len(dp.Detail) > 0 { + detail = ": " + dp.Detail + } + _, _ = fmt.Fprintf(w, "%s ... %s%s", displayPrefix, tailColor.Sprint(tail), detail) } func (b *singleBarCore) renderSpinner(w io.Writer, dp *DisplayProps) { diff --git a/pkg/version/version.go b/pkg/version/version.go index b12afe666b..107925ed68 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -23,7 +23,7 @@ var ( // TiUPVerMinor is the minor version of TiUP TiUPVerMinor = 12 // TiUPVerPatch is the patch version of TiUP - TiUPVerPatch = 2 + TiUPVerPatch = 5 // TiUPVerName is an alternative name of the version TiUPVerName = "tiup" // GitHash is the current git commit hash diff --git a/tests/tiup-cluster/root.json b/tests/tiup-cluster/root.json index 45278e8382..6a57d89c25 100644 --- a/tests/tiup-cluster/root.json +++ b/tests/tiup-cluster/root.json @@ -1 +1 @@ -{"signatures":[{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"cHrebh9dB5z0ypRdAGKso4xBhCp6mY8pZ3ul6Ggzc5+WGU1rOGHEJPS3SP1F7FaBUu4A4aytvQ1fn0fzL20HyiwtSXu7nFzrO5MiGMNa3afyGYxGjHNWZZmYm/6+eZ9fqt7erTrtJgvuiV4VgmzCbQ3uIFEt89tRlsmkFIQ2bry4Z9ml06b/zT243pO7uInU2On+W3/ggluIoATubggzNxhB0OSqREwNfEUACq4N5UzqRwinCURISk/xUHU4/n/P9VraSocXjcMCryrsvaYHEq0AZMNNUPhSn5ow4kPqeELgb0NZxvG5wo276LngCQUqk7FvcxWSH9gMR3VcBc3OnQ=="},{"keyid":"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e","sig":"aFlunIdjZAnm2/tY9QqKGGM2XxVM/cvNpmHrs3Z9BoGzLhOoubhPi70cEfoE2/NQX43SDKr97KT6cPY3XpkNa7mQtVxXEX1/hxc0U6qRFwdAfnV0EzuJeBfn33pfhA/TKVd6FGOEOtrLYrzigLFOuPYrQrvvfWEJGL9merz6kpjXEtTDX+378TQ5wzvphNYDVI3Hp8S+cvatwn+85agzlc4zOrRkp9TMz+vnJZSwQ6eoYqrHFQkuACto+N500lizueeEOSt2Ke17TjxeZIka192XlojHp3iiIm0TsI04DJCAsQ7yliT22BkI/NO+DhWecruJIfb7KfaTmxSG+nddiA=="},{"keyid":"2001b18089c9a865cebee793dbc23f9b1f5ce457f96b8d0b2c0909c26b00c643","sig":"H2qSlXtLWHiECouClS86Enw7pCdbM1duEyG3IcblU8pDmiu72T8SNsz4nq3TZw0hFSqAVw5udVenQ1d3sxQDix1/DCYi6PhkM/ghhyWr6+Ko2mJMT+ejqcCYFvbrb2UoeDEeS85obzi2UPELNC5iBt8iJlRtLzRvpKN+0pTwKhusnLUgan9ZLnRJsZdw2U67W2u/dABxpYsbXDYGa/4M/MkA/NEZhJ53VCvxr8RweBdEeVfKmzF/Ipkxn49aB4hlPgH/2E015U9gu7UQffiWRf+ww3eHgzjp1ItJhclUTbI0Q7BBJ4A5oYWP9DLRab+07y8+iNZmj7wTPvCS+V0+Fw=="},{"keyid":"545c31fd615bbaa4c5424509a9305eb280e019996b043a576dc12b758aa0890a","sig":"PAK7AKXTx61/MKT7ml1QrDaPlbIYZ+UmG+6xgDN/P3ForyqvLgTiqif7ZqZMlUOEXEo/aOZIcJS5yt6xp+XrQT5Dj0OAemmn7kHaYuhl5A3HyMksm2TBGxQXRByyrqsD5OtzWKHXgOIByMBBFnJbPqp3cDU+SoRYizVW114iDo0PXPXQPeX/ffVWkw7kP3l4JBgcUhCrLCND6temGJT7hAMkfPWeDeuuNlyy3ajXH+ENm6DR/RthFi1ys1rAu2j6bDwOpOu3FIzFFdGTs0fJz8tJeLIUejoDJCOwSh7qnpeIBM7cDJlT9sZrVUL5Oluelj4tgoJCO1BN8o7myVCGDw=="},{"keyid":"3f32d76cac38c9d87232ed7570132deb343a68bce4b12d365b8ab61085e1a633","sig":"2UTi6cgCF/EELQtGWU2ENk458JrFymHn1S8aVv0q3B1YoHR92Mm5Ck0FbFkfg9ySOWiEqaesIvtC8FafrpTnbVUrivYnjKOXGzvVBBeQR/Ri44rql9x+6WzjJ4p6/M+FqZEpHisx0I5AFYf2fQkL1Hztmv6yhQTrW3GOh9SVRYlZwEqjeDqm4wIFGZ6amaMr7xu2zxlTEMtz4Gd9zlZVN4Wr6qeYtkW7YLZcFECTzpwHgHJswzljhG5XTxevI/Tz4eKYOgyQCtPC/JS0HOMiTVc6d2XRs5NNvP2a4/LH1tHZRupMAibklwqiwLKfMwVl+tncb9hedxUSMPmo/CMrxw=="}],"signed":{"_type":"root","expires":"2021-05-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"2001b18089c9a865cebee793dbc23f9b1f5ce457f96b8d0b2c0909c26b00c643":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1LB2sQGelCEaKTKPzdim\n5V0RrdDOyZTSsZlWjzqZQn7lIRKG9Yjah//ReBdy3gmTwbZWUYzGFeclS+1+H05f\nvvxJUN1ttNgy6xsKql6s1ZhdwoBLbkjTqHjbRRQ2+fMJQdhusb1TXEP5Vut2jlyo\nSoGSa9mDC0VbGW9Xs/4HqfyH6m4dV6GeFYwDUX0ok6l6DHk28UIFyieKITFNkrKv\n5xoUPS3P49tX7wprXiFBKiP1Tr72O+GSTBFXuUhPASBVCXoxj7g5fB024P464ku/\nTHECfX1F5q7htz2zkgn7V9A9kedASwoqbrC5glHXfrfiQOctHkyKaGLswWe+8OAp\n5wIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"3f32d76cac38c9d87232ed7570132deb343a68bce4b12d365b8ab61085e1a633":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2usmq9K1PdMUEr2AUmC/\n1l8RxbAIhyKzoA0O7zEpIunjU58BP5Ht3APPGAXqg3/lyeTcn8/h+ADEZElrgXCl\nnbsR37R3zmj+/z/M1icp/1O6gaIpHEUz5U2ryPkj9vy5TVE+7uB12x7SBDg3w5mk\nHc0NVPhHBqD9tvXlzzZSHqNjRdM+g5OdCGVzKpt/2LrCIv6MSxoxsqNP3N8I8Tb/\nunwVfhjRjXG23mjLukGPjxJUoXO38WujVWER5ZafhyZDt9VFNdPoGl2kN23aQM4p\n/gyeUgwTfeVqlXYOeErfI9AznnJA12WHTmIMNWpz3NK+c3P4GGTOZcRjnfr0J9wa\ndQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"545c31fd615bbaa4c5424509a9305eb280e019996b043a576dc12b758aa0890a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzlxJStPfdjMERTUs2GH\nMKMPAflgMTId3rhKsyLGAoRraAE3+crZEkXz+sEgCSW7590qDofcZYFeS9QOebD2\nI1/PYbDqMOwWkRSta6BRJyhgGKmG8QuxiYQQEQSgBhTQap3jnxiduXiZ+6uTiNkS\n44/Z12GN+vXLDLCVBlxFZx2Am9QFVCyP7f9Dxj0EkaVKRGu6+utjaWGyQLq5splk\nNbFvMLYJLkzrk8dzLwr1E85NRCAVLnRJR4fYllglJmJi6laHdOgXf9GOL1vQ/qUh\nRXqYkGiZ/15vurMMyUaIdzLY95XHw6vsjOwV9kBs8z/cxBVLxpNWUiOBsfDpmBc3\nCwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kgU3v3SxYzm5J6P+GPP\nmy6toBnKYtTViAVmpUJiIEjdZ9NLpoJU0na9q0CD8sIgo2Js/W/owJUvSj6rm8us\nsu/Ve5KsoJN6zca2am1uZ5IKnc48i0mCv76WXawCxM+NFGqSCMJcltlhj3fC/GDS\ngu+BiIbrgR1PgJf6Jk6l7uMJdN3TL6JJQcEC4lz+2hj5zoVNYkq06ZC79j2tPDCI\nkTAYGF/TAAVLH08/kGH5ZeRPlVKJ7cwW3OniLM5NeFnS8+shRNb6AYr7xju3Ikbw\nDo14ipIghBI0iAxn6Lvr/iilc7TM7RWJ4OiTrmK3SQSJ+U6H2N2/I5OGEHBEKzbA\nOQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":1}} \ No newline at end of file +{"signatures":[{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"kmRKAh18iBSxTU20AlqCFYV5w4OgK72RGqN5sGkDy5I+xxKlMgq2xvlWH329bpRdtmajd6wozb6ibEhiijWei7DnQCkJPVw1Y5DdKyRAHjM8ZYeawVNaUCh2VH13is6cbzSPp30CKZ5whtuERAgkLsX/M0E6bterzhQR//PTNfO41/NOgXnyqGgOslzM46N86rCBPcQwHcyHV0voXX1zGpCSDLkODEbi6ILweJl0iNnaBF+lBzvW6N+oqmEUUzbH7tLSCsJVyj3tLSlPvbTO8BoWnkN1k67WNkBBfA9vD0s46j2hWGuTMApiUa5Iou6/N0JI9Sb2kZAle15TJQJvEA=="},{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"YNGnO9+vcnfwI0ELBdJZh1KEu62NIPZcV2TKfxEBaj7g/Fm1HO3ReAH36dew9MytDPRuIdCXYHVSOQfiBQCuJCF7k/hRQwEFlrJWHMuN2rz7YLqTUyBzkE/PbAEOTtl4C/Q8bxHZ6tHdOJAUIBsXTy4yRZVempUtIULjPNh2d6BPt7x61+3RwhhrPHKFxy2I1hVaZIMfO94Ofb4iwd0UJ1YuQdDqIP75+YtoYUsBFKee4AqvRgKrp5rqQvn0CGOOreOIXvTsszvuzxR26kWvOPPkS3zJRwTu7TW0pE0AsUgEKHKGDoShNdcmx+hGz8mn8BpAivxvJhqqJsz9nazkZA=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"X2FykukrMhf2qeK4bgOTy272VMFJeHAQYNGayckbjfdfToTfnRt+mwV1x5jUFTq39XsEPC6wgTs3ZWQ/3DJ1Wv7oyytN6QTPvblcFnAHNdCNGU2QceyG1N9efRbnpL+VzaWVmpwqrV2DjSHNRYMJsCfwbuC9ZCZ4HFL+bv/InZnM7Zxg7Yrl3Vzs6gOYnlZr19vgQOW/n7CCYgE2X9iS+Y3/8ALFtgU+CJEjAXK37N769H+kYG+IuuhSobdhBk/ie+oXTxm/Y5BjNBvBqetUVpCdqw/PpJ+vpN7KBGGVg3ij10wA2a1B+CA1dxjF6Tzg/HAnNRidZrbmWrkc8I69IA=="},{"keyid":"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c","sig":"wo6iQdse3ADk4SirmdjCdjOnm9sg6ztKEAFfi2BRZE1Z8FlnzUp8S+OztmgRqsVVfGEDAwgWJeimRjohznKBz0tS3bZjzLdHllw0ZHv1n+i8vaBVA5uvpZuzjpCdQbNEh4o9yrVv7hqyFVva5LEMJelOkWV6TvdgdPztHC7B7neyNm7I/0QI3mG8HHFen/CX2CHJu6OQ29XHjbe79VnTbo2ujK9b3ZIHivRMpND0/DBKxSWuXvQ2BSC1nYNDBoJ2AneOQ+aUM6WMUQst8ct9pGlZszyZX/8A1Pbj/e1ToPgkEDSqg2w+Bxty0allc4nyaijzBDo6SoKoWfXKi9wq0Q=="},{"keyid":"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6","sig":"OoK5e9uZ6xu4b6WQjbJge2hsJR10DJ70vEsFRY26C52m5WOrhOJeDxthy5wF01P3odB5hWAAKYDRzB+wUy/h05O33ZXxYrbtqDkwkBYOPRr0X24MDz2nD+etOXyed69V77xi62JYSbl9aP5ItKDGrrYDkOzkQcP2q87eaVJxRJEm0qrA4Jtz8oZ/nOZwX9vZRmd/qNorye/On8yxbtueqCkTVKULI0c/CwBw/rAr+THa1alPqn24djS3MqBst+DDRWR3996M9Cz5agWBASo6TSXNoUnIOGyza7zqoNsdrePLHCbInUWuJ+lN2ilGTgl6ERyYoc0+QFmRaVljG5pGcw=="}],"signed":{"_type":"root","expires":"2024-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApU5RHP0K+Fgkzm9L0yHR\n4CEqLLwHr7hQxjWOaq5K0UfaOKcsPQZ1SkJ/AMppz7ovzwOU4hcy0wJOV7ms6ACk\nS3hte2GlH/xp+OzWiRnI4qJ6GRrAe+ototj1ZMGvpLK4ifxkKaY6vuWFFAeS0fSe\nPHUGAl5v+PaJWgDNQTRmuAu5oCaYP6oT6VKHj6ulLAgAOqWsBSJiK3oIRcWPR+uI\nIW/9BV158wfmxAw1+7ch1RD44+1vV3+Eo94alvVZIAfcJqDS3XGr2Hfd/YWGj1d2\nD26eblBJoQt0L2E2EL8igu1sudVkMZ3NAIfmBrOWUxHEbIjYeKvXPbaSGdC+FoXD\nrwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5oDytiywLDOSpIBovZxx\nNlZJg5Gk3O9kpiOQ0XnD+L2LV+a2dJU1KmBOoGCUr2TNaGTPihAStjpFIsW4c7Ye\nB2RjUFUrXRf3mvc3n4fACayenxtnCleSR4gKkAdHqqPCiWHT5TAtybKSHuHAluUL\nkMvavUZjIPMj0YYB0R8Re7BjU+zxnipJosTbbPQ7fa3+x2VAHc066Y9qp1YucdpB\nMZ3UwtSVNK7aCbFZvKPwAm22fnDYmMbYFeTz/rrl8k+rKTM37d4D3mURC9xDJxIP\nXVaU2dBImYjoFcY0/5oBU5vr1sj2sdUH+3G5AUr6iCL+XJLiwA1x24jKA6mUjQ93\ndwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":4}} \ No newline at end of file diff --git a/tests/tiup-dm/root.json b/tests/tiup-dm/root.json index 45278e8382..6a57d89c25 100644 --- a/tests/tiup-dm/root.json +++ b/tests/tiup-dm/root.json @@ -1 +1 @@ -{"signatures":[{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"cHrebh9dB5z0ypRdAGKso4xBhCp6mY8pZ3ul6Ggzc5+WGU1rOGHEJPS3SP1F7FaBUu4A4aytvQ1fn0fzL20HyiwtSXu7nFzrO5MiGMNa3afyGYxGjHNWZZmYm/6+eZ9fqt7erTrtJgvuiV4VgmzCbQ3uIFEt89tRlsmkFIQ2bry4Z9ml06b/zT243pO7uInU2On+W3/ggluIoATubggzNxhB0OSqREwNfEUACq4N5UzqRwinCURISk/xUHU4/n/P9VraSocXjcMCryrsvaYHEq0AZMNNUPhSn5ow4kPqeELgb0NZxvG5wo276LngCQUqk7FvcxWSH9gMR3VcBc3OnQ=="},{"keyid":"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e","sig":"aFlunIdjZAnm2/tY9QqKGGM2XxVM/cvNpmHrs3Z9BoGzLhOoubhPi70cEfoE2/NQX43SDKr97KT6cPY3XpkNa7mQtVxXEX1/hxc0U6qRFwdAfnV0EzuJeBfn33pfhA/TKVd6FGOEOtrLYrzigLFOuPYrQrvvfWEJGL9merz6kpjXEtTDX+378TQ5wzvphNYDVI3Hp8S+cvatwn+85agzlc4zOrRkp9TMz+vnJZSwQ6eoYqrHFQkuACto+N500lizueeEOSt2Ke17TjxeZIka192XlojHp3iiIm0TsI04DJCAsQ7yliT22BkI/NO+DhWecruJIfb7KfaTmxSG+nddiA=="},{"keyid":"2001b18089c9a865cebee793dbc23f9b1f5ce457f96b8d0b2c0909c26b00c643","sig":"H2qSlXtLWHiECouClS86Enw7pCdbM1duEyG3IcblU8pDmiu72T8SNsz4nq3TZw0hFSqAVw5udVenQ1d3sxQDix1/DCYi6PhkM/ghhyWr6+Ko2mJMT+ejqcCYFvbrb2UoeDEeS85obzi2UPELNC5iBt8iJlRtLzRvpKN+0pTwKhusnLUgan9ZLnRJsZdw2U67W2u/dABxpYsbXDYGa/4M/MkA/NEZhJ53VCvxr8RweBdEeVfKmzF/Ipkxn49aB4hlPgH/2E015U9gu7UQffiWRf+ww3eHgzjp1ItJhclUTbI0Q7BBJ4A5oYWP9DLRab+07y8+iNZmj7wTPvCS+V0+Fw=="},{"keyid":"545c31fd615bbaa4c5424509a9305eb280e019996b043a576dc12b758aa0890a","sig":"PAK7AKXTx61/MKT7ml1QrDaPlbIYZ+UmG+6xgDN/P3ForyqvLgTiqif7ZqZMlUOEXEo/aOZIcJS5yt6xp+XrQT5Dj0OAemmn7kHaYuhl5A3HyMksm2TBGxQXRByyrqsD5OtzWKHXgOIByMBBFnJbPqp3cDU+SoRYizVW114iDo0PXPXQPeX/ffVWkw7kP3l4JBgcUhCrLCND6temGJT7hAMkfPWeDeuuNlyy3ajXH+ENm6DR/RthFi1ys1rAu2j6bDwOpOu3FIzFFdGTs0fJz8tJeLIUejoDJCOwSh7qnpeIBM7cDJlT9sZrVUL5Oluelj4tgoJCO1BN8o7myVCGDw=="},{"keyid":"3f32d76cac38c9d87232ed7570132deb343a68bce4b12d365b8ab61085e1a633","sig":"2UTi6cgCF/EELQtGWU2ENk458JrFymHn1S8aVv0q3B1YoHR92Mm5Ck0FbFkfg9ySOWiEqaesIvtC8FafrpTnbVUrivYnjKOXGzvVBBeQR/Ri44rql9x+6WzjJ4p6/M+FqZEpHisx0I5AFYf2fQkL1Hztmv6yhQTrW3GOh9SVRYlZwEqjeDqm4wIFGZ6amaMr7xu2zxlTEMtz4Gd9zlZVN4Wr6qeYtkW7YLZcFECTzpwHgHJswzljhG5XTxevI/Tz4eKYOgyQCtPC/JS0HOMiTVc6d2XRs5NNvP2a4/LH1tHZRupMAibklwqiwLKfMwVl+tncb9hedxUSMPmo/CMrxw=="}],"signed":{"_type":"root","expires":"2021-05-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"2001b18089c9a865cebee793dbc23f9b1f5ce457f96b8d0b2c0909c26b00c643":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1LB2sQGelCEaKTKPzdim\n5V0RrdDOyZTSsZlWjzqZQn7lIRKG9Yjah//ReBdy3gmTwbZWUYzGFeclS+1+H05f\nvvxJUN1ttNgy6xsKql6s1ZhdwoBLbkjTqHjbRRQ2+fMJQdhusb1TXEP5Vut2jlyo\nSoGSa9mDC0VbGW9Xs/4HqfyH6m4dV6GeFYwDUX0ok6l6DHk28UIFyieKITFNkrKv\n5xoUPS3P49tX7wprXiFBKiP1Tr72O+GSTBFXuUhPASBVCXoxj7g5fB024P464ku/\nTHECfX1F5q7htz2zkgn7V9A9kedASwoqbrC5glHXfrfiQOctHkyKaGLswWe+8OAp\n5wIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"3f32d76cac38c9d87232ed7570132deb343a68bce4b12d365b8ab61085e1a633":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2usmq9K1PdMUEr2AUmC/\n1l8RxbAIhyKzoA0O7zEpIunjU58BP5Ht3APPGAXqg3/lyeTcn8/h+ADEZElrgXCl\nnbsR37R3zmj+/z/M1icp/1O6gaIpHEUz5U2ryPkj9vy5TVE+7uB12x7SBDg3w5mk\nHc0NVPhHBqD9tvXlzzZSHqNjRdM+g5OdCGVzKpt/2LrCIv6MSxoxsqNP3N8I8Tb/\nunwVfhjRjXG23mjLukGPjxJUoXO38WujVWER5ZafhyZDt9VFNdPoGl2kN23aQM4p\n/gyeUgwTfeVqlXYOeErfI9AznnJA12WHTmIMNWpz3NK+c3P4GGTOZcRjnfr0J9wa\ndQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"545c31fd615bbaa4c5424509a9305eb280e019996b043a576dc12b758aa0890a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzlxJStPfdjMERTUs2GH\nMKMPAflgMTId3rhKsyLGAoRraAE3+crZEkXz+sEgCSW7590qDofcZYFeS9QOebD2\nI1/PYbDqMOwWkRSta6BRJyhgGKmG8QuxiYQQEQSgBhTQap3jnxiduXiZ+6uTiNkS\n44/Z12GN+vXLDLCVBlxFZx2Am9QFVCyP7f9Dxj0EkaVKRGu6+utjaWGyQLq5splk\nNbFvMLYJLkzrk8dzLwr1E85NRCAVLnRJR4fYllglJmJi6laHdOgXf9GOL1vQ/qUh\nRXqYkGiZ/15vurMMyUaIdzLY95XHw6vsjOwV9kBs8z/cxBVLxpNWUiOBsfDpmBc3\nCwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"b128ee6a42e2665bd45aa2fa4a7b6e098cfedb3911154f300634b2c056214b9e":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0kgU3v3SxYzm5J6P+GPP\nmy6toBnKYtTViAVmpUJiIEjdZ9NLpoJU0na9q0CD8sIgo2Js/W/owJUvSj6rm8us\nsu/Ve5KsoJN6zca2am1uZ5IKnc48i0mCv76WXawCxM+NFGqSCMJcltlhj3fC/GDS\ngu+BiIbrgR1PgJf6Jk6l7uMJdN3TL6JJQcEC4lz+2hj5zoVNYkq06ZC79j2tPDCI\nkTAYGF/TAAVLH08/kGH5ZeRPlVKJ7cwW3OniLM5NeFnS8+shRNb6AYr7xju3Ikbw\nDo14ipIghBI0iAxn6Lvr/iilc7TM7RWJ4OiTrmK3SQSJ+U6H2N2/I5OGEHBEKzbA\nOQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":1}} \ No newline at end of file +{"signatures":[{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"kmRKAh18iBSxTU20AlqCFYV5w4OgK72RGqN5sGkDy5I+xxKlMgq2xvlWH329bpRdtmajd6wozb6ibEhiijWei7DnQCkJPVw1Y5DdKyRAHjM8ZYeawVNaUCh2VH13is6cbzSPp30CKZ5whtuERAgkLsX/M0E6bterzhQR//PTNfO41/NOgXnyqGgOslzM46N86rCBPcQwHcyHV0voXX1zGpCSDLkODEbi6ILweJl0iNnaBF+lBzvW6N+oqmEUUzbH7tLSCsJVyj3tLSlPvbTO8BoWnkN1k67WNkBBfA9vD0s46j2hWGuTMApiUa5Iou6/N0JI9Sb2kZAle15TJQJvEA=="},{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"YNGnO9+vcnfwI0ELBdJZh1KEu62NIPZcV2TKfxEBaj7g/Fm1HO3ReAH36dew9MytDPRuIdCXYHVSOQfiBQCuJCF7k/hRQwEFlrJWHMuN2rz7YLqTUyBzkE/PbAEOTtl4C/Q8bxHZ6tHdOJAUIBsXTy4yRZVempUtIULjPNh2d6BPt7x61+3RwhhrPHKFxy2I1hVaZIMfO94Ofb4iwd0UJ1YuQdDqIP75+YtoYUsBFKee4AqvRgKrp5rqQvn0CGOOreOIXvTsszvuzxR26kWvOPPkS3zJRwTu7TW0pE0AsUgEKHKGDoShNdcmx+hGz8mn8BpAivxvJhqqJsz9nazkZA=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"X2FykukrMhf2qeK4bgOTy272VMFJeHAQYNGayckbjfdfToTfnRt+mwV1x5jUFTq39XsEPC6wgTs3ZWQ/3DJ1Wv7oyytN6QTPvblcFnAHNdCNGU2QceyG1N9efRbnpL+VzaWVmpwqrV2DjSHNRYMJsCfwbuC9ZCZ4HFL+bv/InZnM7Zxg7Yrl3Vzs6gOYnlZr19vgQOW/n7CCYgE2X9iS+Y3/8ALFtgU+CJEjAXK37N769H+kYG+IuuhSobdhBk/ie+oXTxm/Y5BjNBvBqetUVpCdqw/PpJ+vpN7KBGGVg3ij10wA2a1B+CA1dxjF6Tzg/HAnNRidZrbmWrkc8I69IA=="},{"keyid":"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c","sig":"wo6iQdse3ADk4SirmdjCdjOnm9sg6ztKEAFfi2BRZE1Z8FlnzUp8S+OztmgRqsVVfGEDAwgWJeimRjohznKBz0tS3bZjzLdHllw0ZHv1n+i8vaBVA5uvpZuzjpCdQbNEh4o9yrVv7hqyFVva5LEMJelOkWV6TvdgdPztHC7B7neyNm7I/0QI3mG8HHFen/CX2CHJu6OQ29XHjbe79VnTbo2ujK9b3ZIHivRMpND0/DBKxSWuXvQ2BSC1nYNDBoJ2AneOQ+aUM6WMUQst8ct9pGlZszyZX/8A1Pbj/e1ToPgkEDSqg2w+Bxty0allc4nyaijzBDo6SoKoWfXKi9wq0Q=="},{"keyid":"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6","sig":"OoK5e9uZ6xu4b6WQjbJge2hsJR10DJ70vEsFRY26C52m5WOrhOJeDxthy5wF01P3odB5hWAAKYDRzB+wUy/h05O33ZXxYrbtqDkwkBYOPRr0X24MDz2nD+etOXyed69V77xi62JYSbl9aP5ItKDGrrYDkOzkQcP2q87eaVJxRJEm0qrA4Jtz8oZ/nOZwX9vZRmd/qNorye/On8yxbtueqCkTVKULI0c/CwBw/rAr+THa1alPqn24djS3MqBst+DDRWR3996M9Cz5agWBASo6TSXNoUnIOGyza7zqoNsdrePLHCbInUWuJ+lN2ilGTgl6ERyYoc0+QFmRaVljG5pGcw=="}],"signed":{"_type":"root","expires":"2024-07-26T11:18:30+08:00","roles":{"index":{"keys":{"7fce7ec4f9c36d51dec7ec96065bb64958b743e46ea8141da668cd2ce58a9e61":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn5kVA7MlBfSe7EBaExjl\nKbwoDkn1aYi74s29mFgtRo8nejbrVvZQMCIUhvKc0pFa/l9JD/QY6/nAOCE1lpzi\nwwNkSntfOo3p3HQIR+Ut7hZ4Sxfe/5JagGo3LQ+Hd3EJWUxyEfQ/Bff07F3XAbqM\n5+cKNrdsKWZJcPiJDW621qGwCx52f+gzl9bnFe4/hx34OUgirwqh5DS+LhIO+/yt\nbOiN1AyjQKlnb8lUnblElS4Njd+F4io5VzSrZYi2+4AbTkO6wLwbsWHMzXfv9qwn\nvllufOHpB6EwiQ/xBOMuvJJymHnZvs8AH4SuydQIXLaJuv1ysFaBs0KB/ktbakSK\nLwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/index.json"},"root":{"keys":{"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyDwCfCl30vhyJW7fB1bs\npRYKtBKzl7o0qnJTm+IksjQ8RXxj8osUpMLmSvOzCaJ5Wxe+Pm1LpSTDbbubbgvd\nnmEFL6228sifviNIu2HlIl+agfzmXuJ9OBlzGUaI4gAd1Z6pF6+mjlcjz2PbWF84\nAbXZdK49uluqulp7HrGB/qNjGcIRUCHgDU4nnq0OkI1BZZSKm9ovonqDkIK76x/S\niAD9OjKsjQ/s57tE+5WTVObKpfrfK0JeHdpAUsA/2n4L1Z6FmZD4LZWqb0i+C7xj\nMElC99KtjlwRntcjeVWG9YjU8AcEN0n1gON9S2oRdyyAzDTgGb7WueDnn6qstt5w\nSQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"70033289cef8e5105914b22ecc7f15e271d0650d5216d1ab0bd67f8440411bb6":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApU5RHP0K+Fgkzm9L0yHR\n4CEqLLwHr7hQxjWOaq5K0UfaOKcsPQZ1SkJ/AMppz7ovzwOU4hcy0wJOV7ms6ACk\nS3hte2GlH/xp+OzWiRnI4qJ6GRrAe+ototj1ZMGvpLK4ifxkKaY6vuWFFAeS0fSe\nPHUGAl5v+PaJWgDNQTRmuAu5oCaYP6oT6VKHj6ulLAgAOqWsBSJiK3oIRcWPR+uI\nIW/9BV158wfmxAw1+7ch1RD44+1vV3+Eo94alvVZIAfcJqDS3XGr2Hfd/YWGj1d2\nD26eblBJoQt0L2E2EL8igu1sudVkMZ3NAIfmBrOWUxHEbIjYeKvXPbaSGdC+FoXD\nrwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOgQkwLOh31QV9OpbO9v\n6o83durJFGPOnVXZiab83pKaSk7HEK9WzXBq0BaPvtFwSfROVdpgtopri5lZi+uH\naMKLUn5F8XRnSMl/7m5vM4XpZZYa4aQId4TWdbFtTu31eHGZ3eEC5nDRJ5NhZOJd\nKLFBu/xmxrh/eNZt4QbdWLZayjHnzyoy5AnfNTR6nJgPAv+rBOqyqT/r14q4Pngh\n3z0I3pNFr5qmxsp013XV+kgOW1F7zT7IMU8xRIgo85UWUNhax0/bjY/2NI1Z+WjR\nyhZmUBMVYWvfw97xDUrvBvrJxZPgg0lGvxJC6LF2dM7wgLaNx9khT6HMBVxjxLMs\nDQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnayxhw6KeoKK+Ax9RW6v\n66YjrpRpGLewLmSSAzJGX8nL5/a2nEbXbeF9po265KcBSFWol8jLBsmG56ruwwxp\noWWhJPncqGqy8wMeRMmTf7ATGa+tk+To7UAQD0MYzt7rRlIdpqi9Us3J6076Z83k\n2sxFnX9sVflhOsotGWL7hmrn/CJWxKsO6OVCoqbIlnJV8xFazE2eCfaDTIEEEgnh\nLIGDsmv1AN8ImUIn/hyKcm1PfhDZrF5qhEVhfz5D8aX3cUcEJw8BvCaNloXyHf+y\nDKjqO/dJ7YFWVt7nPqOvaEkBQGMd54ETJ/BbO9r3WTsjXKleoPovBSQ/oOxApypb\nNQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"d499c8ca3c2018885037da89bdfa327e21a0e6a15e2ca8dabe5e78a3edf9c91c":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5oDytiywLDOSpIBovZxx\nNlZJg5Gk3O9kpiOQ0XnD+L2LV+a2dJU1KmBOoGCUr2TNaGTPihAStjpFIsW4c7Ye\nB2RjUFUrXRf3mvc3n4fACayenxtnCleSR4gKkAdHqqPCiWHT5TAtybKSHuHAluUL\nkMvavUZjIPMj0YYB0R8Re7BjU+zxnipJosTbbPQ7fa3+x2VAHc066Y9qp1YucdpB\nMZ3UwtSVNK7aCbFZvKPwAm22fnDYmMbYFeTz/rrl8k+rKTM37d4D3mURC9xDJxIP\nXVaU2dBImYjoFcY0/5oBU5vr1sj2sdUH+3G5AUr6iCL+XJLiwA1x24jKA6mUjQ93\ndwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":3,"url":"/root.json"},"snapshot":{"keys":{"8660a9f40687fb33e6f8ad563f21ee81b9ce7b91c90827cc7ae2416c5e0e94e9":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTZx29eJR5EumjqM4YTb\nFlKbim1GNYmtbCLH51BbU2lt46ddmfGvtGsxTD3mIZ/GEHVFv6Aei3xx5nIfhGP0\nrG78JRz394uU8Pd62DiIFWYizr5o+ZBZu29D2YK5ZtxoLFpgt0ibnINK2NcesDC8\nSqfIUbMiQFT6yB/MYD275SjfRGHOeYTPmKdjMJrhLL2cfIPYnQ0QFYIyMvXBG1Fj\nU0rc9UclYQHh9YheIDVYI9YCo/DWP3KFfRJpoTjQRGoPSK9TXcpCAEzQpEG3jOek\n9PdV9Ol6/O8JbrFwXWF3LhkUThg+zCjV4qHtP4oqp5QCqzTQTXGQ9qxWUSlHi4Eu\nIwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/snapshot.json"},"timestamp":{"keys":{"66d4ea1da00076c822a6e1b4df5eb1e529eb38f6edcedff323e62f2bfe3eaddd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzTgV5iKhMnunUDxt4PB\npYqTMPaJN/ZdOOsP6cS3DeCE/EcYGfgCjvP7KD3gjG98VDBTVcuwZClSy+/zvHhV\nIq7VWu+yxQL5c6oa1xpCyHoA96JiLIDPhmqEdscdRybcRQ2CYywzKA8jSwEQCnEK\nc8a74ceY352l/MEcOem0+AtKrOjqcjbXCayDwC9yTg/c78bkp+4T8AhSWgt6Tlrt\nY8jLE7zwojFtIYtMwobWRIW2O3nJDXiSBbTPG3M9kF1G43INshSdBcuq5Tmy8lpE\n/XiG/E7+hP63Hm+KAcdvl553Zs7pLhAZxV0kqlApqRRwhscw+JQci8sVONun5t9t\nNwIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"}},"threshold":1,"url":"/timestamp.json"}},"spec_version":"0.1.0","version":4}} \ No newline at end of file diff --git a/tests/tiup/test_tiup.sh b/tests/tiup/test_tiup.sh index f04fc7ffdf..9fb3b51270 100755 --- a/tests/tiup/test_tiup.sh +++ b/tests/tiup/test_tiup.sh @@ -27,6 +27,7 @@ tiup list tiup tiup help tiup install tidb:v5.2.2 +tiup install tidb:v3.0.13 tiup update tidb tiup update tidb --nightly tiup --binary tidb:nightly