From 3b92a56737b38bc53fe35e56d414230ba6497e36 Mon Sep 17 00:00:00 2001 From: JaySon Date: Thu, 25 Jul 2024 15:49:58 +0800 Subject: [PATCH 1/8] tiflash: Add example of setting the tiflash-proxy configs (#2444) Signed-off-by: JaySon-Huang --- embed/examples/cluster/topology.example.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/embed/examples/cluster/topology.example.yaml b/embed/examples/cluster/topology.example.yaml index 0af84a658e..ce9953c783 100644 --- a/embed/examples/cluster/topology.example.yaml +++ b/embed/examples/cluster/topology.example.yaml @@ -248,6 +248,12 @@ tiflash_servers: data_dir: /data1/tidb-data/tiflash-9000 # # TiFlash Server log file storage directory. log_dir: /data1/tidb-deploy/tiflash-9000/log + # # The following configs are used to overwrite the `server_configs.tiflash` values. + # config: + # logger.level: info + # # The following configs are used to overwrite the `server_configs.tiflash-learner` values. + # learner_config: + # log.level: info - host: 10.0.1.19 # ssh_port: 22 tcp_port: 9001 From 9c5ad9aaaaec76e6abd896cd175df862ef964ccc Mon Sep 17 00:00:00 2001 From: Hu# Date: Thu, 25 Jul 2024 22:51:05 +0800 Subject: [PATCH 2/8] pdms(playground, cluster): add name to start pdms (#2438) --- components/playground/instance/pd.go | 16 +++- embed/templates/scripts/run_scheduling.sh.tpl | 3 + embed/templates/scripts/run_tso.sh.tpl | 3 + pkg/cluster/manager/manager_test.go | 15 ++++ pkg/cluster/manager/transfer_test.go | 28 +++++++ pkg/cluster/spec/scheduling.go | 38 +++++---- pkg/cluster/spec/spec.go | 10 +++ pkg/cluster/spec/tso.go | 38 +++++---- pkg/cluster/spec/validate.go | 34 ++++++++ pkg/cluster/template/scripts/pdms_test.go | 80 +++++++++++++++++++ pkg/cluster/template/scripts/scheduling.go | 1 + pkg/cluster/template/scripts/tso.go | 1 + pkg/tidbver/tidbver.go | 5 ++ 13 files changed, 239 insertions(+), 33 deletions(-) create mode 100644 pkg/cluster/template/scripts/pdms_test.go diff --git a/components/playground/instance/pd.go b/components/playground/instance/pd.go index 3c1d6f8636..67b2e53ed2 100644 --- a/components/playground/instance/pd.go +++ b/components/playground/instance/pd.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/pingcap/errors" + "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) @@ -83,7 +84,14 @@ func (inst *PDInstance) InitCluster(pds []*PDInstance) *PDInstance { // Name return the name of pd. func (inst *PDInstance) Name() string { - return fmt.Sprintf("pd-%d", inst.ID) + switch inst.Role { + case PDRoleTSO: + return fmt.Sprintf("tso-%d", inst.ID) + case PDRoleScheduling: + return fmt.Sprintf("scheduling-%d", inst.ID) + default: + return fmt.Sprintf("pd-%d", inst.ID) + } } // Start calls set inst.cmd and Start @@ -142,6 +150,9 @@ func (inst *PDInstance) Start(ctx context.Context) error { fmt.Sprintf("--log-file=%s", inst.LogFile()), fmt.Sprintf("--config=%s", configPath), } + if tidbver.PDSupportMicroServicesWithName(inst.Version.String()) { + args = append(args, fmt.Sprintf("--name=%s", uid)) + } case PDRoleScheduling: endpoints := pdEndpoints(inst.pds, true) args = []string{ @@ -153,6 +164,9 @@ func (inst *PDInstance) Start(ctx context.Context) error { fmt.Sprintf("--log-file=%s", inst.LogFile()), fmt.Sprintf("--config=%s", configPath), } + if tidbver.PDSupportMicroServicesWithName(inst.Version.String()) { + args = append(args, fmt.Sprintf("--name=%s", uid)) + } } inst.Process = &process{cmd: PrepareCommand(ctx, inst.BinPath, args, nil, inst.Dir)} diff --git a/embed/templates/scripts/run_scheduling.sh.tpl b/embed/templates/scripts/run_scheduling.sh.tpl index a15b1ba4f7..2ba72fed0f 100644 --- a/embed/templates/scripts/run_scheduling.sh.tpl +++ b/embed/templates/scripts/run_scheduling.sh.tpl @@ -11,6 +11,9 @@ cd "${DEPLOY_DIR}" || exit 1 exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=madvdontneed=1 bin/pd-server services scheduling\ {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services scheduling \ +{{- end}} +{{- if .Name}} + --name="{{.Name}}" \ {{- end}} --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ diff --git a/embed/templates/scripts/run_tso.sh.tpl b/embed/templates/scripts/run_tso.sh.tpl index 0d6486d73e..177b676aff 100644 --- a/embed/templates/scripts/run_tso.sh.tpl +++ b/embed/templates/scripts/run_tso.sh.tpl @@ -11,6 +11,9 @@ cd "${DEPLOY_DIR}" || exit 1 exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=madvdontneed=1 bin/pd-server services tso\ {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services tso \ +{{- end}} +{{- if .Name}} + --name="{{.Name}}" \ {{- end}} --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ diff --git a/pkg/cluster/manager/manager_test.go b/pkg/cluster/manager/manager_test.go index e80d1d1c64..b82b6eb785 100644 --- a/pkg/cluster/manager/manager_test.go +++ b/pkg/cluster/manager/manager_test.go @@ -85,6 +85,21 @@ pd_servers: assert.Nil(err) err = validateNewTopo(&topo) assert.NotNil(err) + + topo = spec.Specification{} + err = yaml.Unmarshal([]byte(` +global: + user: "test4" + deploy_dir: "test-deploy" + data_dir: "test-data" +tso_servers: + - host: 172.16.5.53 +scheduling_servers: + - host: 172.16.5.54 +`), &topo) + assert.Nil(err) + err = validateNewTopo(&topo) + assert.Nil(err) } func TestDeduplicateCheckResult(t *testing.T) { diff --git a/pkg/cluster/manager/transfer_test.go b/pkg/cluster/manager/transfer_test.go index bef179dd0b..d4b4581f6a 100644 --- a/pkg/cluster/manager/transfer_test.go +++ b/pkg/cluster/manager/transfer_test.go @@ -53,4 +53,32 @@ func TestRenderSpec(t *testing.T) { dir, err = renderSpec("{{.DataDir}}", s, "test-pd") assert.Nil(t, err) assert.NotEmpty(t, dir) + + s = &spec.TSOInstance{BaseInstance: spec.BaseInstance{ + InstanceSpec: &spec.TSOSpec{ + Host: "172.16.5.140", + SSHPort: 22, + Name: "tso-1", + DeployDir: "/home/test/deploy/tso-3379", + DataDir: "/home/test/deploy/tso-3379/data", + }, + }} + // s.BaseInstance.InstanceSpec + dir, err = renderSpec("{{.DataDir}}", s, "test-tso") + assert.Nil(t, err) + assert.NotEmpty(t, dir) + + s = &spec.SchedulingInstance{BaseInstance: spec.BaseInstance{ + InstanceSpec: &spec.SchedulingSpec{ + Host: "172.16.5.140", + SSHPort: 22, + Name: "scheduling-1", + DeployDir: "/home/test/deploy/scheduling-3379", + DataDir: "/home/test/deploy/scheduling-3379/data", + }, + }} + // s.BaseInstance.InstanceSpec + dir, err = renderSpec("{{.DataDir}}", s, "test-scheduling") + assert.Nil(t, err) + assert.NotEmpty(t, dir) } diff --git a/pkg/cluster/spec/scheduling.go b/pkg/cluster/spec/scheduling.go index efbe7def00..3da3975f2d 100644 --- a/pkg/cluster/spec/scheduling.go +++ b/pkg/cluster/spec/scheduling.go @@ -25,26 +25,29 @@ import ( "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/template/scripts" "github.com/pingcap/tiup/pkg/meta" + "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) // SchedulingSpec represents the scheduling topology specification in topology.yaml type SchedulingSpec struct { - Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` - ListenHost string `yaml:"listen_host,omitempty"` - AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` - SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` - IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` - Port int `yaml:"port" default:"3379"` - 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"` - Arch string `yaml:"arch,omitempty"` - OS string `yaml:"os,omitempty"` + Host string `yaml:"host"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + ListenHost string `yaml:"listen_host,omitempty"` + AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` + SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` + // Use Name to get the name with a default value if it's empty. + Name string `yaml:"name,omitempty"` + Port int `yaml:"port" default:"3379"` + 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"` + Arch string `yaml:"arch,omitempty"` + OS string `yaml:"os,omitempty"` } // Status queries current status of the instance @@ -200,7 +203,6 @@ func (c *SchedulingComponent) Instances() []Instance { // SchedulingInstance represent the scheduling instance type SchedulingInstance struct { - Name string BaseInstance topo Topology } @@ -229,6 +231,7 @@ func (i *SchedulingInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.SchedulingScript{ + Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), @@ -237,6 +240,9 @@ func (i *SchedulingInstance) InitConfig( LogDir: paths.Log, NumaNode: spec.NumaNode, } + if !tidbver.PDSupportMicroServicesWithName(version) { + cfg.Name = "" + } fp := filepath.Join(paths.Cache, fmt.Sprintf("run_scheduling_%s_%d.sh", i.GetHost(), i.GetPort())) if err := cfg.ConfigToFile(fp); err != nil { diff --git a/pkg/cluster/spec/spec.go b/pkg/cluster/spec/spec.go index ffef492dda..99bd0e87dd 100644 --- a/pkg/cluster/spec/spec.go +++ b/pkg/cluster/spec/spec.go @@ -679,10 +679,20 @@ func setCustomDefaults(globalOptions *GlobalOptions, field reflect.Value) error } field.Field(j).Set(reflect.ValueOf(globalOptions.SSHPort)) case "Name": + // Only PD related components have `Name` field, if field.Field(j).String() != "" { continue } host := reflect.Indirect(field).FieldByName("Host").String() + // `TSO` and `Scheduling` components use `Port` filed + if reflect.Indirect(field).FieldByName("Port").IsValid() { + port := reflect.Indirect(field).FieldByName("Port").Int() + // field.String() is + role := strings.Split(strings.Split(field.Type().String(), ".")[1], "Spec")[0] + component := strings.ToLower(role) + field.Field(j).Set(reflect.ValueOf(fmt.Sprintf("%s-%s-%d", component, host, port))) + continue + } clientPort := reflect.Indirect(field).FieldByName("ClientPort").Int() field.Field(j).Set(reflect.ValueOf(fmt.Sprintf("pd-%s-%d", host, clientPort))) case "DataDir": diff --git a/pkg/cluster/spec/tso.go b/pkg/cluster/spec/tso.go index a84069f6ee..e309f1d652 100644 --- a/pkg/cluster/spec/tso.go +++ b/pkg/cluster/spec/tso.go @@ -25,26 +25,29 @@ import ( "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/template/scripts" "github.com/pingcap/tiup/pkg/meta" + "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) // TSOSpec represents the TSO topology specification in topology.yaml type TSOSpec struct { - Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` - ListenHost string `yaml:"listen_host,omitempty"` - AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` - SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` - IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` - Port int `yaml:"port" default:"3379"` - 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"` - Arch string `yaml:"arch,omitempty"` - OS string `yaml:"os,omitempty"` + Host string `yaml:"host"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + ListenHost string `yaml:"listen_host,omitempty"` + AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` + SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` + // Use Name to get the name with a default value if it's empty. + Name string `yaml:"name,omitempty"` + Port int `yaml:"port" default:"3379"` + 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"` + Arch string `yaml:"arch,omitempty"` + OS string `yaml:"os,omitempty"` } // Status queries current status of the instance @@ -200,7 +203,6 @@ func (c *TSOComponent) Instances() []Instance { // TSOInstance represent the TSO instance type TSOInstance struct { - Name string BaseInstance topo Topology } @@ -229,6 +231,7 @@ func (i *TSOInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.TSOScript{ + Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), @@ -237,6 +240,9 @@ func (i *TSOInstance) InitConfig( LogDir: paths.Log, NumaNode: spec.NumaNode, } + if !tidbver.PDSupportMicroServicesWithName(version) { + cfg.Name = "" + } fp := filepath.Join(paths.Cache, fmt.Sprintf("run_tso_%s_%d.sh", i.GetHost(), i.GetPort())) if err := cfg.ConfigToFile(fp); err != nil { diff --git a/pkg/cluster/spec/validate.go b/pkg/cluster/spec/validate.go index 99384cbec7..ce73682c01 100644 --- a/pkg/cluster/spec/validate.go +++ b/pkg/cluster/spec/validate.go @@ -984,6 +984,38 @@ func (s *Specification) validatePDNames() error { return nil } +func (s *Specification) validateTSONames() error { + // check tso server name + tsoNames := set.NewStringSet() + for _, tso := range s.TSOServers { + if tso.Name == "" { + continue + } + + if tsoNames.Exist(tso.Name) { + return errors.Errorf("component tso_servers.name is not supported duplicated, the name %s is duplicated", tso.Name) + } + tsoNames.Insert(tso.Name) + } + return nil +} + +func (s *Specification) validateSchedulingNames() error { + // check scheduling server name + schedulingNames := set.NewStringSet() + for _, scheduling := range s.SchedulingServers { + if scheduling.Name == "" { + continue + } + + if schedulingNames.Exist(scheduling.Name) { + return errors.Errorf("component scheduling_servers.name is not supported duplicated, the name %s is duplicated", scheduling.Name) + } + schedulingNames.Insert(scheduling.Name) + } + return nil +} + func (s *Specification) validateTiFlashConfigs() error { c := FindComponent(s, ComponentTiFlash) for _, ins := range c.Instances() { @@ -1063,6 +1095,8 @@ func (s *Specification) Validate() error { s.dirConflictsDetect, s.validateUserGroup, s.validatePDNames, + s.validateTSONames, + s.validateSchedulingNames, s.validateTiSparkSpec, s.validateTiFlashConfigs, s.validateMonitorAgent, diff --git a/pkg/cluster/template/scripts/pdms_test.go b/pkg/cluster/template/scripts/pdms_test.go new file mode 100644 index 0000000000..414f693f1f --- /dev/null +++ b/pkg/cluster/template/scripts/pdms_test.go @@ -0,0 +1,80 @@ +// Copyright 2024 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package scripts + +import ( + "os" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestScheduling(t *testing.T) { + assert := require.New(t) + conf, err := os.CreateTemp("", "scheduling.conf") + assert.Nil(err) + defer os.Remove(conf.Name()) + + cfg := &SchedulingScript{ + Name: "scheduling-0", + ListenURL: "127.0.0.1", + AdvertiseListenURL: "127.0.0.2", + BackendEndpoints: "127.0.0.3", + DeployDir: "/deploy", + DataDir: "/data", + LogDir: "/log", + } + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err := os.ReadFile(conf.Name()) + assert.Nil(err) + assert.True(strings.Contains(string(content), "--name")) + + cfg.Name = "" + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err = os.ReadFile(conf.Name()) + assert.Nil(err) + assert.False(strings.Contains(string(content), "--name")) +} + +func TestTSO(t *testing.T) { + assert := require.New(t) + conf, err := os.CreateTemp("", "tso.conf") + assert.Nil(err) + defer os.Remove(conf.Name()) + + cfg := &TSOScript{ + Name: "tso-0", + ListenURL: "127.0.0.1", + AdvertiseListenURL: "127.0.0.2", + BackendEndpoints: "127.0.0.3", + DeployDir: "/deploy", + DataDir: "/data", + LogDir: "/log", + } + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err := os.ReadFile(conf.Name()) + assert.Nil(err) + assert.True(strings.Contains(string(content), "--name")) + + cfg.Name = "" + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err = os.ReadFile(conf.Name()) + assert.Nil(err) + assert.False(strings.Contains(string(content), "--name")) +} diff --git a/pkg/cluster/template/scripts/scheduling.go b/pkg/cluster/template/scripts/scheduling.go index 6167d9336e..76142485a2 100644 --- a/pkg/cluster/template/scripts/scheduling.go +++ b/pkg/cluster/template/scripts/scheduling.go @@ -24,6 +24,7 @@ import ( // SchedulingScript represent the data to generate scheduling config type SchedulingScript struct { + Name string ListenURL string AdvertiseListenURL string BackendEndpoints string diff --git a/pkg/cluster/template/scripts/tso.go b/pkg/cluster/template/scripts/tso.go index 0197b82c38..91c3bfe1d0 100644 --- a/pkg/cluster/template/scripts/tso.go +++ b/pkg/cluster/template/scripts/tso.go @@ -24,6 +24,7 @@ import ( // TSOScript represent the data to generate tso config type TSOScript struct { + Name string ListenURL string AdvertiseListenURL string BackendEndpoints string diff --git a/pkg/tidbver/tidbver.go b/pkg/tidbver/tidbver.go index c659304a85..c811510cfc 100644 --- a/pkg/tidbver/tidbver.go +++ b/pkg/tidbver/tidbver.go @@ -104,6 +104,11 @@ func PDSupportMicroServices(version string) bool { return semver.Compare(version, "v7.3.0") >= 0 || strings.Contains(version, "nightly") } +// PDSupportMicroServicesWithName return if the given version of PD supports micro services with name. +func PDSupportMicroServicesWithName(version string) bool { + return semver.Compare(version, "v8.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 From 61c9724efc10e598a874ae2afd5fe150eed2afef Mon Sep 17 00:00:00 2001 From: kaaaaaaang Date: Tue, 30 Jul 2024 16:09:50 +0800 Subject: [PATCH 3/8] Revert "pdms(playground, cluster): add name to start pdms (#2438)" (#2446) This reverts commit 9c5ad9aaaaec76e6abd896cd175df862ef964ccc. --- components/playground/instance/pd.go | 16 +--- embed/templates/scripts/run_scheduling.sh.tpl | 3 - embed/templates/scripts/run_tso.sh.tpl | 3 - pkg/cluster/manager/manager_test.go | 15 ---- pkg/cluster/manager/transfer_test.go | 28 ------- pkg/cluster/spec/scheduling.go | 38 ++++----- pkg/cluster/spec/spec.go | 10 --- pkg/cluster/spec/tso.go | 38 ++++----- pkg/cluster/spec/validate.go | 34 -------- pkg/cluster/template/scripts/pdms_test.go | 80 ------------------- pkg/cluster/template/scripts/scheduling.go | 1 - pkg/cluster/template/scripts/tso.go | 1 - pkg/tidbver/tidbver.go | 5 -- 13 files changed, 33 insertions(+), 239 deletions(-) delete mode 100644 pkg/cluster/template/scripts/pdms_test.go diff --git a/components/playground/instance/pd.go b/components/playground/instance/pd.go index 67b2e53ed2..3c1d6f8636 100644 --- a/components/playground/instance/pd.go +++ b/components/playground/instance/pd.go @@ -20,7 +20,6 @@ import ( "strings" "github.com/pingcap/errors" - "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) @@ -84,14 +83,7 @@ func (inst *PDInstance) InitCluster(pds []*PDInstance) *PDInstance { // Name return the name of pd. func (inst *PDInstance) Name() string { - switch inst.Role { - case PDRoleTSO: - return fmt.Sprintf("tso-%d", inst.ID) - case PDRoleScheduling: - return fmt.Sprintf("scheduling-%d", inst.ID) - default: - return fmt.Sprintf("pd-%d", inst.ID) - } + return fmt.Sprintf("pd-%d", inst.ID) } // Start calls set inst.cmd and Start @@ -150,9 +142,6 @@ func (inst *PDInstance) Start(ctx context.Context) error { fmt.Sprintf("--log-file=%s", inst.LogFile()), fmt.Sprintf("--config=%s", configPath), } - if tidbver.PDSupportMicroServicesWithName(inst.Version.String()) { - args = append(args, fmt.Sprintf("--name=%s", uid)) - } case PDRoleScheduling: endpoints := pdEndpoints(inst.pds, true) args = []string{ @@ -164,9 +153,6 @@ func (inst *PDInstance) Start(ctx context.Context) error { fmt.Sprintf("--log-file=%s", inst.LogFile()), fmt.Sprintf("--config=%s", configPath), } - if tidbver.PDSupportMicroServicesWithName(inst.Version.String()) { - args = append(args, fmt.Sprintf("--name=%s", uid)) - } } inst.Process = &process{cmd: PrepareCommand(ctx, inst.BinPath, args, nil, inst.Dir)} diff --git a/embed/templates/scripts/run_scheduling.sh.tpl b/embed/templates/scripts/run_scheduling.sh.tpl index 2ba72fed0f..a15b1ba4f7 100644 --- a/embed/templates/scripts/run_scheduling.sh.tpl +++ b/embed/templates/scripts/run_scheduling.sh.tpl @@ -11,9 +11,6 @@ cd "${DEPLOY_DIR}" || exit 1 exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=madvdontneed=1 bin/pd-server services scheduling\ {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services scheduling \ -{{- end}} -{{- if .Name}} - --name="{{.Name}}" \ {{- end}} --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ diff --git a/embed/templates/scripts/run_tso.sh.tpl b/embed/templates/scripts/run_tso.sh.tpl index 177b676aff..0d6486d73e 100644 --- a/embed/templates/scripts/run_tso.sh.tpl +++ b/embed/templates/scripts/run_tso.sh.tpl @@ -11,9 +11,6 @@ cd "${DEPLOY_DIR}" || exit 1 exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=madvdontneed=1 bin/pd-server services tso\ {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services tso \ -{{- end}} -{{- if .Name}} - --name="{{.Name}}" \ {{- end}} --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ diff --git a/pkg/cluster/manager/manager_test.go b/pkg/cluster/manager/manager_test.go index b82b6eb785..e80d1d1c64 100644 --- a/pkg/cluster/manager/manager_test.go +++ b/pkg/cluster/manager/manager_test.go @@ -85,21 +85,6 @@ pd_servers: assert.Nil(err) err = validateNewTopo(&topo) assert.NotNil(err) - - topo = spec.Specification{} - err = yaml.Unmarshal([]byte(` -global: - user: "test4" - deploy_dir: "test-deploy" - data_dir: "test-data" -tso_servers: - - host: 172.16.5.53 -scheduling_servers: - - host: 172.16.5.54 -`), &topo) - assert.Nil(err) - err = validateNewTopo(&topo) - assert.Nil(err) } func TestDeduplicateCheckResult(t *testing.T) { diff --git a/pkg/cluster/manager/transfer_test.go b/pkg/cluster/manager/transfer_test.go index d4b4581f6a..bef179dd0b 100644 --- a/pkg/cluster/manager/transfer_test.go +++ b/pkg/cluster/manager/transfer_test.go @@ -53,32 +53,4 @@ func TestRenderSpec(t *testing.T) { dir, err = renderSpec("{{.DataDir}}", s, "test-pd") assert.Nil(t, err) assert.NotEmpty(t, dir) - - s = &spec.TSOInstance{BaseInstance: spec.BaseInstance{ - InstanceSpec: &spec.TSOSpec{ - Host: "172.16.5.140", - SSHPort: 22, - Name: "tso-1", - DeployDir: "/home/test/deploy/tso-3379", - DataDir: "/home/test/deploy/tso-3379/data", - }, - }} - // s.BaseInstance.InstanceSpec - dir, err = renderSpec("{{.DataDir}}", s, "test-tso") - assert.Nil(t, err) - assert.NotEmpty(t, dir) - - s = &spec.SchedulingInstance{BaseInstance: spec.BaseInstance{ - InstanceSpec: &spec.SchedulingSpec{ - Host: "172.16.5.140", - SSHPort: 22, - Name: "scheduling-1", - DeployDir: "/home/test/deploy/scheduling-3379", - DataDir: "/home/test/deploy/scheduling-3379/data", - }, - }} - // s.BaseInstance.InstanceSpec - dir, err = renderSpec("{{.DataDir}}", s, "test-scheduling") - assert.Nil(t, err) - assert.NotEmpty(t, dir) } diff --git a/pkg/cluster/spec/scheduling.go b/pkg/cluster/spec/scheduling.go index 3da3975f2d..efbe7def00 100644 --- a/pkg/cluster/spec/scheduling.go +++ b/pkg/cluster/spec/scheduling.go @@ -25,29 +25,26 @@ import ( "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/template/scripts" "github.com/pingcap/tiup/pkg/meta" - "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) // SchedulingSpec represents the scheduling topology specification in topology.yaml type SchedulingSpec struct { - Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` - ListenHost string `yaml:"listen_host,omitempty"` - AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` - SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` - IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` - // Use Name to get the name with a default value if it's empty. - Name string `yaml:"name,omitempty"` - Port int `yaml:"port" default:"3379"` - 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"` - Arch string `yaml:"arch,omitempty"` - OS string `yaml:"os,omitempty"` + Host string `yaml:"host"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + ListenHost string `yaml:"listen_host,omitempty"` + AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` + SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` + Port int `yaml:"port" default:"3379"` + 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"` + Arch string `yaml:"arch,omitempty"` + OS string `yaml:"os,omitempty"` } // Status queries current status of the instance @@ -203,6 +200,7 @@ func (c *SchedulingComponent) Instances() []Instance { // SchedulingInstance represent the scheduling instance type SchedulingInstance struct { + Name string BaseInstance topo Topology } @@ -231,7 +229,6 @@ func (i *SchedulingInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.SchedulingScript{ - Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), @@ -240,9 +237,6 @@ func (i *SchedulingInstance) InitConfig( LogDir: paths.Log, NumaNode: spec.NumaNode, } - if !tidbver.PDSupportMicroServicesWithName(version) { - cfg.Name = "" - } fp := filepath.Join(paths.Cache, fmt.Sprintf("run_scheduling_%s_%d.sh", i.GetHost(), i.GetPort())) if err := cfg.ConfigToFile(fp); err != nil { diff --git a/pkg/cluster/spec/spec.go b/pkg/cluster/spec/spec.go index 99bd0e87dd..ffef492dda 100644 --- a/pkg/cluster/spec/spec.go +++ b/pkg/cluster/spec/spec.go @@ -679,20 +679,10 @@ func setCustomDefaults(globalOptions *GlobalOptions, field reflect.Value) error } field.Field(j).Set(reflect.ValueOf(globalOptions.SSHPort)) case "Name": - // Only PD related components have `Name` field, if field.Field(j).String() != "" { continue } host := reflect.Indirect(field).FieldByName("Host").String() - // `TSO` and `Scheduling` components use `Port` filed - if reflect.Indirect(field).FieldByName("Port").IsValid() { - port := reflect.Indirect(field).FieldByName("Port").Int() - // field.String() is - role := strings.Split(strings.Split(field.Type().String(), ".")[1], "Spec")[0] - component := strings.ToLower(role) - field.Field(j).Set(reflect.ValueOf(fmt.Sprintf("%s-%s-%d", component, host, port))) - continue - } clientPort := reflect.Indirect(field).FieldByName("ClientPort").Int() field.Field(j).Set(reflect.ValueOf(fmt.Sprintf("pd-%s-%d", host, clientPort))) case "DataDir": diff --git a/pkg/cluster/spec/tso.go b/pkg/cluster/spec/tso.go index e309f1d652..a84069f6ee 100644 --- a/pkg/cluster/spec/tso.go +++ b/pkg/cluster/spec/tso.go @@ -25,29 +25,26 @@ import ( "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/template/scripts" "github.com/pingcap/tiup/pkg/meta" - "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) // TSOSpec represents the TSO topology specification in topology.yaml type TSOSpec struct { - Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` - ListenHost string `yaml:"listen_host,omitempty"` - AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` - SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` - IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` - // Use Name to get the name with a default value if it's empty. - Name string `yaml:"name,omitempty"` - Port int `yaml:"port" default:"3379"` - 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"` - Arch string `yaml:"arch,omitempty"` - OS string `yaml:"os,omitempty"` + Host string `yaml:"host"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + ListenHost string `yaml:"listen_host,omitempty"` + AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` + SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` + Port int `yaml:"port" default:"3379"` + 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"` + Arch string `yaml:"arch,omitempty"` + OS string `yaml:"os,omitempty"` } // Status queries current status of the instance @@ -203,6 +200,7 @@ func (c *TSOComponent) Instances() []Instance { // TSOInstance represent the TSO instance type TSOInstance struct { + Name string BaseInstance topo Topology } @@ -231,7 +229,6 @@ func (i *TSOInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.TSOScript{ - Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), @@ -240,9 +237,6 @@ func (i *TSOInstance) InitConfig( LogDir: paths.Log, NumaNode: spec.NumaNode, } - if !tidbver.PDSupportMicroServicesWithName(version) { - cfg.Name = "" - } fp := filepath.Join(paths.Cache, fmt.Sprintf("run_tso_%s_%d.sh", i.GetHost(), i.GetPort())) if err := cfg.ConfigToFile(fp); err != nil { diff --git a/pkg/cluster/spec/validate.go b/pkg/cluster/spec/validate.go index ce73682c01..99384cbec7 100644 --- a/pkg/cluster/spec/validate.go +++ b/pkg/cluster/spec/validate.go @@ -984,38 +984,6 @@ func (s *Specification) validatePDNames() error { return nil } -func (s *Specification) validateTSONames() error { - // check tso server name - tsoNames := set.NewStringSet() - for _, tso := range s.TSOServers { - if tso.Name == "" { - continue - } - - if tsoNames.Exist(tso.Name) { - return errors.Errorf("component tso_servers.name is not supported duplicated, the name %s is duplicated", tso.Name) - } - tsoNames.Insert(tso.Name) - } - return nil -} - -func (s *Specification) validateSchedulingNames() error { - // check scheduling server name - schedulingNames := set.NewStringSet() - for _, scheduling := range s.SchedulingServers { - if scheduling.Name == "" { - continue - } - - if schedulingNames.Exist(scheduling.Name) { - return errors.Errorf("component scheduling_servers.name is not supported duplicated, the name %s is duplicated", scheduling.Name) - } - schedulingNames.Insert(scheduling.Name) - } - return nil -} - func (s *Specification) validateTiFlashConfigs() error { c := FindComponent(s, ComponentTiFlash) for _, ins := range c.Instances() { @@ -1095,8 +1063,6 @@ func (s *Specification) Validate() error { s.dirConflictsDetect, s.validateUserGroup, s.validatePDNames, - s.validateTSONames, - s.validateSchedulingNames, s.validateTiSparkSpec, s.validateTiFlashConfigs, s.validateMonitorAgent, diff --git a/pkg/cluster/template/scripts/pdms_test.go b/pkg/cluster/template/scripts/pdms_test.go deleted file mode 100644 index 414f693f1f..0000000000 --- a/pkg/cluster/template/scripts/pdms_test.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2024 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -package scripts - -import ( - "os" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestScheduling(t *testing.T) { - assert := require.New(t) - conf, err := os.CreateTemp("", "scheduling.conf") - assert.Nil(err) - defer os.Remove(conf.Name()) - - cfg := &SchedulingScript{ - Name: "scheduling-0", - ListenURL: "127.0.0.1", - AdvertiseListenURL: "127.0.0.2", - BackendEndpoints: "127.0.0.3", - DeployDir: "/deploy", - DataDir: "/data", - LogDir: "/log", - } - err = cfg.ConfigToFile(conf.Name()) - assert.Nil(err) - content, err := os.ReadFile(conf.Name()) - assert.Nil(err) - assert.True(strings.Contains(string(content), "--name")) - - cfg.Name = "" - err = cfg.ConfigToFile(conf.Name()) - assert.Nil(err) - content, err = os.ReadFile(conf.Name()) - assert.Nil(err) - assert.False(strings.Contains(string(content), "--name")) -} - -func TestTSO(t *testing.T) { - assert := require.New(t) - conf, err := os.CreateTemp("", "tso.conf") - assert.Nil(err) - defer os.Remove(conf.Name()) - - cfg := &TSOScript{ - Name: "tso-0", - ListenURL: "127.0.0.1", - AdvertiseListenURL: "127.0.0.2", - BackendEndpoints: "127.0.0.3", - DeployDir: "/deploy", - DataDir: "/data", - LogDir: "/log", - } - err = cfg.ConfigToFile(conf.Name()) - assert.Nil(err) - content, err := os.ReadFile(conf.Name()) - assert.Nil(err) - assert.True(strings.Contains(string(content), "--name")) - - cfg.Name = "" - err = cfg.ConfigToFile(conf.Name()) - assert.Nil(err) - content, err = os.ReadFile(conf.Name()) - assert.Nil(err) - assert.False(strings.Contains(string(content), "--name")) -} diff --git a/pkg/cluster/template/scripts/scheduling.go b/pkg/cluster/template/scripts/scheduling.go index 76142485a2..6167d9336e 100644 --- a/pkg/cluster/template/scripts/scheduling.go +++ b/pkg/cluster/template/scripts/scheduling.go @@ -24,7 +24,6 @@ import ( // SchedulingScript represent the data to generate scheduling config type SchedulingScript struct { - Name string ListenURL string AdvertiseListenURL string BackendEndpoints string diff --git a/pkg/cluster/template/scripts/tso.go b/pkg/cluster/template/scripts/tso.go index 91c3bfe1d0..0197b82c38 100644 --- a/pkg/cluster/template/scripts/tso.go +++ b/pkg/cluster/template/scripts/tso.go @@ -24,7 +24,6 @@ import ( // TSOScript represent the data to generate tso config type TSOScript struct { - Name string ListenURL string AdvertiseListenURL string BackendEndpoints string diff --git a/pkg/tidbver/tidbver.go b/pkg/tidbver/tidbver.go index c811510cfc..c659304a85 100644 --- a/pkg/tidbver/tidbver.go +++ b/pkg/tidbver/tidbver.go @@ -104,11 +104,6 @@ func PDSupportMicroServices(version string) bool { return semver.Compare(version, "v7.3.0") >= 0 || strings.Contains(version, "nightly") } -// PDSupportMicroServicesWithName return if the given version of PD supports micro services with name. -func PDSupportMicroServicesWithName(version string) bool { - return semver.Compare(version, "v8.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 From ac3a39e8210df49258f0b0e5cf0817d7e9853b2f Mon Sep 17 00:00:00 2001 From: xhe Date: Thu, 1 Aug 2024 17:13:55 +0800 Subject: [PATCH 4/8] cluster: remove systemd and interrupts collector (#2445) * cluster: remove systemd collector Signed-off-by: xhe * delete interupts too Signed-off-by: xhe * fix ut Signed-off-by: xhe --------- Signed-off-by: xhe Co-authored-by: ti-chi-bot[bot] <108142056+ti-chi-bot[bot]@users.noreply.github.com> --- embed/templates/scripts/run_node_exporter.sh.tpl | 4 ++-- pkg/repository/testdata/manifests/root.json | 2 +- pkg/repository/testdata/polluted/bin/root.json | 2 +- pkg/repository/v1manifest/testdata/polluted/bin/root.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embed/templates/scripts/run_node_exporter.sh.tpl b/embed/templates/scripts/run_node_exporter.sh.tpl index 9634eed2bc..02acb1491e 100644 --- a/embed/templates/scripts/run_node_exporter.sh.tpl +++ b/embed/templates/scripts/run_node_exporter.sh.tpl @@ -21,10 +21,10 @@ exec $EXPORTER_BIN \ {{- end}} --web.listen-address=":{{.Port}}" \ --collector.tcpstat \ - --collector.systemd \ --collector.mountstats \ --collector.meminfo_numa \ - --collector.interrupts \ --collector.buddyinfo \ --collector.vmstat.fields="^.*" \ --log.level="info" + #--collector.systemd \ + #--collector.interrupts \ diff --git a/pkg/repository/testdata/manifests/root.json b/pkg/repository/testdata/manifests/root.json index ca16fcc0cb..0af4b4c619 100644 --- a/pkg/repository/testdata/manifests/root.json +++ b/pkg/repository/testdata/manifests/root.json @@ -1 +1 @@ -{"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 +{"signatures":[{"keyid":"18007f60ccfdf9fa5bc79b09464880c054ce34289e97ad93696b85cc43aed314","sig":"fNbhxgGrR/opxc1gaYZtyaDYAYfpq52eGB8v5lT8s1OoboOCTMC975DOYH1P3cC43qCtwwYOtJviBKG7SQ3lxzIR3wSaEqnJMtZx6VFsn7k8znFKRQBU0Tw5veHtjRxtX3SdudQ+qQPvgVBbTwxWRLVZiPH5D7aFzo7ylBauOlrx+DdhURM29JmU/fcXUcLsjFxp/A6oguQWoUWiGDfT7LqdBUxKDNU0wk+AUX2UEeGavIz/L0Ja6/VVKPwzI2C9iPYYezuUlKKi6PR9XDX/X1+CGuEHlpYeITY/Ipgy3zhY2svXHCvgvXBAx5bqJPyReNDaQAx9QnBzrij3k1Vpuw=="},{"keyid":"ef644d810a1f1dcce7078ae5b2821cba346a2eac0a371e56feea9e07a5eade37","sig":"ldOj6IMwRc/ANElR9ZHfAInFYJfZ+eqzcdehfdYPU4GgpQBK8vKe/Vi7oYyaAWM+oRi7KlIUPWSsnxd5aB0J0hznERPtQzoBg/pNVX5f2ls3EU+21YdSJ7TrD6uud+oqo4tumkjmE7SYSIY4064colPeevob+uJSt2w4MgKa3LCBSsE+vltBo/m5GYz2vKifOL1j2eXRtcBr8PiAasANfZkm+uAlBgKCt+ZSZawGQ3LyuxSimvdTHd40og2ugG03GBMTwOP4igubKodFI+gzNvFXy1BfD8wd7Aa8GQ25EAH6NUARDmyunlW7s6qG+rWivFouvWC3iCTErKYDP1XP0w=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"V+ab8aZ7CQtDqZLDlFEB2V6bL6EGpjsoeFNimMftDXpjAel81JvR/F6ta1f0daatpHky+Zefh5jnVNE2CbezM5lymIhfXKbGBgPY6UrXY5NmMEjv4miVg/t0trkzNqHnOsX+4jvz81dbu9BUhvCEP96wh3O+SltIhToPsleTJuAOSSU9eptS5wCYTQqMjClrpurivs8XRgXeryRorGjWCs8DxhHZqe/hvivcHp9YefvkLw9VQzjZlaH3SCHShLlkaZpn2qssCmzuSt4PLD97VZW89QD/kOqlbHVCqZNzzHp1i6UG6hccN/hnhiYo1v4hOgeX6QT5R8/rlwF8M/RZeQ=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"TVbpxEpaobzt/ODTm+aC9YlhPRvr8NaEREJ4sOoGZCllNxeDaAeSB16VuzmoOfE7esDZBwPuZ8jN1HgdSz33H85/2KRg8EDllCo9fKgKbYhIxr4WgJDoqf3y9ejrjMHRJW8ReCntpobeajuKTxOvgZEvi9wJJ9DagDk9V2u+62jQpMNJdswa6tRH/WsVjNFQ5FMmuf4UasuwhkSupZHjwtFx0B63Jc//hVC/mgCdP30oChq7dkI63tX7eJDu4L07V/MOUl2LBemX5z5OWXDFq5AykIn6re/uzna92EPINh3waa+0Wr0VK70Znj1cDBxb1q6aijIMVpnuXA+P5BeB1A=="},{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"kzFOjJlBSJtADdze6nmpXe6fgnz46rXBWgfACInRldm1pr7sO/Exugwa4qBn0yp2a0N+mDhXvxEi+CuYYOqSNJe5z3TjqiBpTBo2fvOsb6HxNV3dhb24D465rzBFEqi8VxU/KoU/nhlCcGUev+knYJ+oYySjrfJpnxSXmoWYYJiCM/lNcuySqUzeH2WO69pKGDwtEmCXZaRuKwXt3B2HUjLny7aRmLV9Z28pCGobmpEAUIDM2/sU9BWicWSzTD8OAEkX1WPCIAm6I2Q/T0T7ImDbeL8nX4ctzbUuW7uoXM7aM9eq26kaYJ+mqwqQMBNuMYGDq5tShzTsRk9KNpkhrw=="}],"signed":{"_type":"root","expires":"2025-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":{"18007f60ccfdf9fa5bc79b09464880c054ce34289e97ad93696b85cc43aed314":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4DYlVfoIQTlyJij0ynjh\njqUkayqXX5c9VXw1Ud3mWCOdThy6V0bmsohgSBeHrfVroSCfsAc5VCUlaSteZeFl\nQEZxpRWDCmSYGslOQZqe2cJi5aqyQOYeU7JLjlfAausLCR9636SfEvQoaCEuGsUI\n67yCVWW2oQ756egUNmOrOSd7Qh6IGuuj9FQb9vExPXTxQw7j95ENOsc1V2lAXCEG\nS1+Nh4NIKdpLOXAohbcpq/HLjddmEAj2GXHo+asITlHCVUQvf574Vh5yLkFWnqj0\nviyRq0jJa9P+qA2oy80a3dk3FBCPu0sov6GfUIC+NtkDfjOkKfluBF9WapqR9wt0\noQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"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"},"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"},"ef644d810a1f1dcce7078ae5b2821cba346a2eac0a371e56feea9e07a5eade37":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsL5sV9dhPqnkc3dU2xH\nVRPVuH1bebET64bJya96IXjR3Um/IbIikmIpAL8KbY35h44hR4nNwUQZcQggo854\n5SxDi5LiAkMqdr9uq5mXp7sZXb0HcuHX97BqTUvTvr+t05KaON81ikdVGyRw+Qus\nFFXZO2Pj0w0I4QD87nISAuK0wQJhD8robDzO+Qf2K5cHXjEu5DGNc+wq66pJWCwt\nDl2BAvkF86Y3kZVuEQ6zp5PPQh0l++0PtzY/NNNHiLm7JUSlmpXyis7f+FaCEGl0\n4JWs5ImJg1XjUo2AsSnlFZ3adrPJ4NHFo64ui0/JsEAhn1TBWLL4AhT9kVIBMXI4\n0wIDAQAB\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":5}} \ 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 ca16fcc0cb..0af4b4c619 100644 --- a/pkg/repository/testdata/polluted/bin/root.json +++ b/pkg/repository/testdata/polluted/bin/root.json @@ -1 +1 @@ -{"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 +{"signatures":[{"keyid":"18007f60ccfdf9fa5bc79b09464880c054ce34289e97ad93696b85cc43aed314","sig":"fNbhxgGrR/opxc1gaYZtyaDYAYfpq52eGB8v5lT8s1OoboOCTMC975DOYH1P3cC43qCtwwYOtJviBKG7SQ3lxzIR3wSaEqnJMtZx6VFsn7k8znFKRQBU0Tw5veHtjRxtX3SdudQ+qQPvgVBbTwxWRLVZiPH5D7aFzo7ylBauOlrx+DdhURM29JmU/fcXUcLsjFxp/A6oguQWoUWiGDfT7LqdBUxKDNU0wk+AUX2UEeGavIz/L0Ja6/VVKPwzI2C9iPYYezuUlKKi6PR9XDX/X1+CGuEHlpYeITY/Ipgy3zhY2svXHCvgvXBAx5bqJPyReNDaQAx9QnBzrij3k1Vpuw=="},{"keyid":"ef644d810a1f1dcce7078ae5b2821cba346a2eac0a371e56feea9e07a5eade37","sig":"ldOj6IMwRc/ANElR9ZHfAInFYJfZ+eqzcdehfdYPU4GgpQBK8vKe/Vi7oYyaAWM+oRi7KlIUPWSsnxd5aB0J0hznERPtQzoBg/pNVX5f2ls3EU+21YdSJ7TrD6uud+oqo4tumkjmE7SYSIY4064colPeevob+uJSt2w4MgKa3LCBSsE+vltBo/m5GYz2vKifOL1j2eXRtcBr8PiAasANfZkm+uAlBgKCt+ZSZawGQ3LyuxSimvdTHd40og2ugG03GBMTwOP4igubKodFI+gzNvFXy1BfD8wd7Aa8GQ25EAH6NUARDmyunlW7s6qG+rWivFouvWC3iCTErKYDP1XP0w=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"V+ab8aZ7CQtDqZLDlFEB2V6bL6EGpjsoeFNimMftDXpjAel81JvR/F6ta1f0daatpHky+Zefh5jnVNE2CbezM5lymIhfXKbGBgPY6UrXY5NmMEjv4miVg/t0trkzNqHnOsX+4jvz81dbu9BUhvCEP96wh3O+SltIhToPsleTJuAOSSU9eptS5wCYTQqMjClrpurivs8XRgXeryRorGjWCs8DxhHZqe/hvivcHp9YefvkLw9VQzjZlaH3SCHShLlkaZpn2qssCmzuSt4PLD97VZW89QD/kOqlbHVCqZNzzHp1i6UG6hccN/hnhiYo1v4hOgeX6QT5R8/rlwF8M/RZeQ=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"TVbpxEpaobzt/ODTm+aC9YlhPRvr8NaEREJ4sOoGZCllNxeDaAeSB16VuzmoOfE7esDZBwPuZ8jN1HgdSz33H85/2KRg8EDllCo9fKgKbYhIxr4WgJDoqf3y9ejrjMHRJW8ReCntpobeajuKTxOvgZEvi9wJJ9DagDk9V2u+62jQpMNJdswa6tRH/WsVjNFQ5FMmuf4UasuwhkSupZHjwtFx0B63Jc//hVC/mgCdP30oChq7dkI63tX7eJDu4L07V/MOUl2LBemX5z5OWXDFq5AykIn6re/uzna92EPINh3waa+0Wr0VK70Znj1cDBxb1q6aijIMVpnuXA+P5BeB1A=="},{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"kzFOjJlBSJtADdze6nmpXe6fgnz46rXBWgfACInRldm1pr7sO/Exugwa4qBn0yp2a0N+mDhXvxEi+CuYYOqSNJe5z3TjqiBpTBo2fvOsb6HxNV3dhb24D465rzBFEqi8VxU/KoU/nhlCcGUev+knYJ+oYySjrfJpnxSXmoWYYJiCM/lNcuySqUzeH2WO69pKGDwtEmCXZaRuKwXt3B2HUjLny7aRmLV9Z28pCGobmpEAUIDM2/sU9BWicWSzTD8OAEkX1WPCIAm6I2Q/T0T7ImDbeL8nX4ctzbUuW7uoXM7aM9eq26kaYJ+mqwqQMBNuMYGDq5tShzTsRk9KNpkhrw=="}],"signed":{"_type":"root","expires":"2025-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":{"18007f60ccfdf9fa5bc79b09464880c054ce34289e97ad93696b85cc43aed314":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4DYlVfoIQTlyJij0ynjh\njqUkayqXX5c9VXw1Ud3mWCOdThy6V0bmsohgSBeHrfVroSCfsAc5VCUlaSteZeFl\nQEZxpRWDCmSYGslOQZqe2cJi5aqyQOYeU7JLjlfAausLCR9636SfEvQoaCEuGsUI\n67yCVWW2oQ756egUNmOrOSd7Qh6IGuuj9FQb9vExPXTxQw7j95ENOsc1V2lAXCEG\nS1+Nh4NIKdpLOXAohbcpq/HLjddmEAj2GXHo+asITlHCVUQvf574Vh5yLkFWnqj0\nviyRq0jJa9P+qA2oy80a3dk3FBCPu0sov6GfUIC+NtkDfjOkKfluBF9WapqR9wt0\noQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"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"},"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"},"ef644d810a1f1dcce7078ae5b2821cba346a2eac0a371e56feea9e07a5eade37":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsL5sV9dhPqnkc3dU2xH\nVRPVuH1bebET64bJya96IXjR3Um/IbIikmIpAL8KbY35h44hR4nNwUQZcQggo854\n5SxDi5LiAkMqdr9uq5mXp7sZXb0HcuHX97BqTUvTvr+t05KaON81ikdVGyRw+Qus\nFFXZO2Pj0w0I4QD87nISAuK0wQJhD8robDzO+Qf2K5cHXjEu5DGNc+wq66pJWCwt\nDl2BAvkF86Y3kZVuEQ6zp5PPQh0l++0PtzY/NNNHiLm7JUSlmpXyis7f+FaCEGl0\n4JWs5ImJg1XjUo2AsSnlFZ3adrPJ4NHFo64ui0/JsEAhn1TBWLL4AhT9kVIBMXI4\n0wIDAQAB\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":5}} \ 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 ca16fcc0cb..0af4b4c619 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":"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 +{"signatures":[{"keyid":"18007f60ccfdf9fa5bc79b09464880c054ce34289e97ad93696b85cc43aed314","sig":"fNbhxgGrR/opxc1gaYZtyaDYAYfpq52eGB8v5lT8s1OoboOCTMC975DOYH1P3cC43qCtwwYOtJviBKG7SQ3lxzIR3wSaEqnJMtZx6VFsn7k8znFKRQBU0Tw5veHtjRxtX3SdudQ+qQPvgVBbTwxWRLVZiPH5D7aFzo7ylBauOlrx+DdhURM29JmU/fcXUcLsjFxp/A6oguQWoUWiGDfT7LqdBUxKDNU0wk+AUX2UEeGavIz/L0Ja6/VVKPwzI2C9iPYYezuUlKKi6PR9XDX/X1+CGuEHlpYeITY/Ipgy3zhY2svXHCvgvXBAx5bqJPyReNDaQAx9QnBzrij3k1Vpuw=="},{"keyid":"ef644d810a1f1dcce7078ae5b2821cba346a2eac0a371e56feea9e07a5eade37","sig":"ldOj6IMwRc/ANElR9ZHfAInFYJfZ+eqzcdehfdYPU4GgpQBK8vKe/Vi7oYyaAWM+oRi7KlIUPWSsnxd5aB0J0hznERPtQzoBg/pNVX5f2ls3EU+21YdSJ7TrD6uud+oqo4tumkjmE7SYSIY4064colPeevob+uJSt2w4MgKa3LCBSsE+vltBo/m5GYz2vKifOL1j2eXRtcBr8PiAasANfZkm+uAlBgKCt+ZSZawGQ3LyuxSimvdTHd40og2ugG03GBMTwOP4igubKodFI+gzNvFXy1BfD8wd7Aa8GQ25EAH6NUARDmyunlW7s6qG+rWivFouvWC3iCTErKYDP1XP0w=="},{"keyid":"5607181203a2fb60b9d725109388ccb19ccdc236a4b1d1441fbea7ad07616c4a","sig":"V+ab8aZ7CQtDqZLDlFEB2V6bL6EGpjsoeFNimMftDXpjAel81JvR/F6ta1f0daatpHky+Zefh5jnVNE2CbezM5lymIhfXKbGBgPY6UrXY5NmMEjv4miVg/t0trkzNqHnOsX+4jvz81dbu9BUhvCEP96wh3O+SltIhToPsleTJuAOSSU9eptS5wCYTQqMjClrpurivs8XRgXeryRorGjWCs8DxhHZqe/hvivcHp9YefvkLw9VQzjZlaH3SCHShLlkaZpn2qssCmzuSt4PLD97VZW89QD/kOqlbHVCqZNzzHp1i6UG6hccN/hnhiYo1v4hOgeX6QT5R8/rlwF8M/RZeQ=="},{"keyid":"9b3cea98f6f23cc11813b12d0526a1b6cfb3761008f0882c9caa8db742d63002","sig":"TVbpxEpaobzt/ODTm+aC9YlhPRvr8NaEREJ4sOoGZCllNxeDaAeSB16VuzmoOfE7esDZBwPuZ8jN1HgdSz33H85/2KRg8EDllCo9fKgKbYhIxr4WgJDoqf3y9ejrjMHRJW8ReCntpobeajuKTxOvgZEvi9wJJ9DagDk9V2u+62jQpMNJdswa6tRH/WsVjNFQ5FMmuf4UasuwhkSupZHjwtFx0B63Jc//hVC/mgCdP30oChq7dkI63tX7eJDu4L07V/MOUl2LBemX5z5OWXDFq5AykIn6re/uzna92EPINh3waa+0Wr0VK70Znj1cDBxb1q6aijIMVpnuXA+P5BeB1A=="},{"keyid":"a61b695e2b86097d993e94e99fd15ec6d8fc8e9522948c9ff21c2f2c881093ae","sig":"kzFOjJlBSJtADdze6nmpXe6fgnz46rXBWgfACInRldm1pr7sO/Exugwa4qBn0yp2a0N+mDhXvxEi+CuYYOqSNJe5z3TjqiBpTBo2fvOsb6HxNV3dhb24D465rzBFEqi8VxU/KoU/nhlCcGUev+knYJ+oYySjrfJpnxSXmoWYYJiCM/lNcuySqUzeH2WO69pKGDwtEmCXZaRuKwXt3B2HUjLny7aRmLV9Z28pCGobmpEAUIDM2/sU9BWicWSzTD8OAEkX1WPCIAm6I2Q/T0T7ImDbeL8nX4ctzbUuW7uoXM7aM9eq26kaYJ+mqwqQMBNuMYGDq5tShzTsRk9KNpkhrw=="}],"signed":{"_type":"root","expires":"2025-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":{"18007f60ccfdf9fa5bc79b09464880c054ce34289e97ad93696b85cc43aed314":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4DYlVfoIQTlyJij0ynjh\njqUkayqXX5c9VXw1Ud3mWCOdThy6V0bmsohgSBeHrfVroSCfsAc5VCUlaSteZeFl\nQEZxpRWDCmSYGslOQZqe2cJi5aqyQOYeU7JLjlfAausLCR9636SfEvQoaCEuGsUI\n67yCVWW2oQ756egUNmOrOSd7Qh6IGuuj9FQb9vExPXTxQw7j95ENOsc1V2lAXCEG\nS1+Nh4NIKdpLOXAohbcpq/HLjddmEAj2GXHo+asITlHCVUQvf574Vh5yLkFWnqj0\nviyRq0jJa9P+qA2oy80a3dk3FBCPu0sov6GfUIC+NtkDfjOkKfluBF9WapqR9wt0\noQIDAQAB\n-----END PUBLIC KEY-----\n"},"scheme":"rsassa-pss-sha256"},"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"},"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"},"ef644d810a1f1dcce7078ae5b2821cba346a2eac0a371e56feea9e07a5eade37":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsL5sV9dhPqnkc3dU2xH\nVRPVuH1bebET64bJya96IXjR3Um/IbIikmIpAL8KbY35h44hR4nNwUQZcQggo854\n5SxDi5LiAkMqdr9uq5mXp7sZXb0HcuHX97BqTUvTvr+t05KaON81ikdVGyRw+Qus\nFFXZO2Pj0w0I4QD87nISAuK0wQJhD8robDzO+Qf2K5cHXjEu5DGNc+wq66pJWCwt\nDl2BAvkF86Y3kZVuEQ6zp5PPQh0l++0PtzY/NNNHiLm7JUSlmpXyis7f+FaCEGl0\n4JWs5ImJg1XjUo2AsSnlFZ3adrPJ4NHFo64ui0/JsEAhn1TBWLL4AhT9kVIBMXI4\n0wIDAQAB\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":5}} \ No newline at end of file From 9c22e674026dd7c01c9f6a73a796eb6b4d4506fa Mon Sep 17 00:00:00 2001 From: Hu# Date: Wed, 7 Aug 2024 16:59:12 +0800 Subject: [PATCH 5/8] pdms(playground, cluster): add name to start pdms (#2447) Signed-off-by: husharp --- components/playground/instance/pd.go | 16 +++- embed/templates/scripts/run_scheduling.sh.tpl | 3 + embed/templates/scripts/run_tso.sh.tpl | 3 + pkg/cluster/manager/manager_test.go | 15 ++++ pkg/cluster/manager/transfer_test.go | 28 +++++++ pkg/cluster/spec/scheduling.go | 38 +++++---- pkg/cluster/spec/spec.go | 10 +++ pkg/cluster/spec/tso.go | 38 +++++---- pkg/cluster/spec/validate.go | 34 ++++++++ pkg/cluster/template/scripts/pdms_test.go | 80 +++++++++++++++++++ pkg/cluster/template/scripts/scheduling.go | 1 + pkg/cluster/template/scripts/tso.go | 1 + pkg/tidbver/tidbver.go | 5 ++ 13 files changed, 239 insertions(+), 33 deletions(-) create mode 100644 pkg/cluster/template/scripts/pdms_test.go diff --git a/components/playground/instance/pd.go b/components/playground/instance/pd.go index 3c1d6f8636..67b2e53ed2 100644 --- a/components/playground/instance/pd.go +++ b/components/playground/instance/pd.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/pingcap/errors" + "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) @@ -83,7 +84,14 @@ func (inst *PDInstance) InitCluster(pds []*PDInstance) *PDInstance { // Name return the name of pd. func (inst *PDInstance) Name() string { - return fmt.Sprintf("pd-%d", inst.ID) + switch inst.Role { + case PDRoleTSO: + return fmt.Sprintf("tso-%d", inst.ID) + case PDRoleScheduling: + return fmt.Sprintf("scheduling-%d", inst.ID) + default: + return fmt.Sprintf("pd-%d", inst.ID) + } } // Start calls set inst.cmd and Start @@ -142,6 +150,9 @@ func (inst *PDInstance) Start(ctx context.Context) error { fmt.Sprintf("--log-file=%s", inst.LogFile()), fmt.Sprintf("--config=%s", configPath), } + if tidbver.PDSupportMicroServicesWithName(inst.Version.String()) { + args = append(args, fmt.Sprintf("--name=%s", uid)) + } case PDRoleScheduling: endpoints := pdEndpoints(inst.pds, true) args = []string{ @@ -153,6 +164,9 @@ func (inst *PDInstance) Start(ctx context.Context) error { fmt.Sprintf("--log-file=%s", inst.LogFile()), fmt.Sprintf("--config=%s", configPath), } + if tidbver.PDSupportMicroServicesWithName(inst.Version.String()) { + args = append(args, fmt.Sprintf("--name=%s", uid)) + } } inst.Process = &process{cmd: PrepareCommand(ctx, inst.BinPath, args, nil, inst.Dir)} diff --git a/embed/templates/scripts/run_scheduling.sh.tpl b/embed/templates/scripts/run_scheduling.sh.tpl index a15b1ba4f7..2ba72fed0f 100644 --- a/embed/templates/scripts/run_scheduling.sh.tpl +++ b/embed/templates/scripts/run_scheduling.sh.tpl @@ -11,6 +11,9 @@ cd "${DEPLOY_DIR}" || exit 1 exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=madvdontneed=1 bin/pd-server services scheduling\ {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services scheduling \ +{{- end}} +{{- if .Name}} + --name="{{.Name}}" \ {{- end}} --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ diff --git a/embed/templates/scripts/run_tso.sh.tpl b/embed/templates/scripts/run_tso.sh.tpl index 0d6486d73e..177b676aff 100644 --- a/embed/templates/scripts/run_tso.sh.tpl +++ b/embed/templates/scripts/run_tso.sh.tpl @@ -11,6 +11,9 @@ cd "${DEPLOY_DIR}" || exit 1 exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=madvdontneed=1 bin/pd-server services tso\ {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services tso \ +{{- end}} +{{- if .Name}} + --name="{{.Name}}" \ {{- end}} --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ diff --git a/pkg/cluster/manager/manager_test.go b/pkg/cluster/manager/manager_test.go index e80d1d1c64..b82b6eb785 100644 --- a/pkg/cluster/manager/manager_test.go +++ b/pkg/cluster/manager/manager_test.go @@ -85,6 +85,21 @@ pd_servers: assert.Nil(err) err = validateNewTopo(&topo) assert.NotNil(err) + + topo = spec.Specification{} + err = yaml.Unmarshal([]byte(` +global: + user: "test4" + deploy_dir: "test-deploy" + data_dir: "test-data" +tso_servers: + - host: 172.16.5.53 +scheduling_servers: + - host: 172.16.5.54 +`), &topo) + assert.Nil(err) + err = validateNewTopo(&topo) + assert.Nil(err) } func TestDeduplicateCheckResult(t *testing.T) { diff --git a/pkg/cluster/manager/transfer_test.go b/pkg/cluster/manager/transfer_test.go index bef179dd0b..d4b4581f6a 100644 --- a/pkg/cluster/manager/transfer_test.go +++ b/pkg/cluster/manager/transfer_test.go @@ -53,4 +53,32 @@ func TestRenderSpec(t *testing.T) { dir, err = renderSpec("{{.DataDir}}", s, "test-pd") assert.Nil(t, err) assert.NotEmpty(t, dir) + + s = &spec.TSOInstance{BaseInstance: spec.BaseInstance{ + InstanceSpec: &spec.TSOSpec{ + Host: "172.16.5.140", + SSHPort: 22, + Name: "tso-1", + DeployDir: "/home/test/deploy/tso-3379", + DataDir: "/home/test/deploy/tso-3379/data", + }, + }} + // s.BaseInstance.InstanceSpec + dir, err = renderSpec("{{.DataDir}}", s, "test-tso") + assert.Nil(t, err) + assert.NotEmpty(t, dir) + + s = &spec.SchedulingInstance{BaseInstance: spec.BaseInstance{ + InstanceSpec: &spec.SchedulingSpec{ + Host: "172.16.5.140", + SSHPort: 22, + Name: "scheduling-1", + DeployDir: "/home/test/deploy/scheduling-3379", + DataDir: "/home/test/deploy/scheduling-3379/data", + }, + }} + // s.BaseInstance.InstanceSpec + dir, err = renderSpec("{{.DataDir}}", s, "test-scheduling") + assert.Nil(t, err) + assert.NotEmpty(t, dir) } diff --git a/pkg/cluster/spec/scheduling.go b/pkg/cluster/spec/scheduling.go index efbe7def00..3da3975f2d 100644 --- a/pkg/cluster/spec/scheduling.go +++ b/pkg/cluster/spec/scheduling.go @@ -25,26 +25,29 @@ import ( "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/template/scripts" "github.com/pingcap/tiup/pkg/meta" + "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) // SchedulingSpec represents the scheduling topology specification in topology.yaml type SchedulingSpec struct { - Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` - ListenHost string `yaml:"listen_host,omitempty"` - AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` - SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` - IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` - Port int `yaml:"port" default:"3379"` - 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"` - Arch string `yaml:"arch,omitempty"` - OS string `yaml:"os,omitempty"` + Host string `yaml:"host"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + ListenHost string `yaml:"listen_host,omitempty"` + AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` + SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` + // Use Name to get the name with a default value if it's empty. + Name string `yaml:"name,omitempty"` + Port int `yaml:"port" default:"3379"` + 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"` + Arch string `yaml:"arch,omitempty"` + OS string `yaml:"os,omitempty"` } // Status queries current status of the instance @@ -200,7 +203,6 @@ func (c *SchedulingComponent) Instances() []Instance { // SchedulingInstance represent the scheduling instance type SchedulingInstance struct { - Name string BaseInstance topo Topology } @@ -229,6 +231,7 @@ func (i *SchedulingInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.SchedulingScript{ + Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), @@ -237,6 +240,9 @@ func (i *SchedulingInstance) InitConfig( LogDir: paths.Log, NumaNode: spec.NumaNode, } + if !tidbver.PDSupportMicroServicesWithName(version) { + cfg.Name = "" + } fp := filepath.Join(paths.Cache, fmt.Sprintf("run_scheduling_%s_%d.sh", i.GetHost(), i.GetPort())) if err := cfg.ConfigToFile(fp); err != nil { diff --git a/pkg/cluster/spec/spec.go b/pkg/cluster/spec/spec.go index ffef492dda..99bd0e87dd 100644 --- a/pkg/cluster/spec/spec.go +++ b/pkg/cluster/spec/spec.go @@ -679,10 +679,20 @@ func setCustomDefaults(globalOptions *GlobalOptions, field reflect.Value) error } field.Field(j).Set(reflect.ValueOf(globalOptions.SSHPort)) case "Name": + // Only PD related components have `Name` field, if field.Field(j).String() != "" { continue } host := reflect.Indirect(field).FieldByName("Host").String() + // `TSO` and `Scheduling` components use `Port` filed + if reflect.Indirect(field).FieldByName("Port").IsValid() { + port := reflect.Indirect(field).FieldByName("Port").Int() + // field.String() is + role := strings.Split(strings.Split(field.Type().String(), ".")[1], "Spec")[0] + component := strings.ToLower(role) + field.Field(j).Set(reflect.ValueOf(fmt.Sprintf("%s-%s-%d", component, host, port))) + continue + } clientPort := reflect.Indirect(field).FieldByName("ClientPort").Int() field.Field(j).Set(reflect.ValueOf(fmt.Sprintf("pd-%s-%d", host, clientPort))) case "DataDir": diff --git a/pkg/cluster/spec/tso.go b/pkg/cluster/spec/tso.go index a84069f6ee..e309f1d652 100644 --- a/pkg/cluster/spec/tso.go +++ b/pkg/cluster/spec/tso.go @@ -25,26 +25,29 @@ import ( "github.com/pingcap/tiup/pkg/cluster/ctxt" "github.com/pingcap/tiup/pkg/cluster/template/scripts" "github.com/pingcap/tiup/pkg/meta" + "github.com/pingcap/tiup/pkg/tidbver" "github.com/pingcap/tiup/pkg/utils" ) // TSOSpec represents the TSO topology specification in topology.yaml type TSOSpec struct { - Host string `yaml:"host"` - ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` - ListenHost string `yaml:"listen_host,omitempty"` - AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` - SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` - IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` - Port int `yaml:"port" default:"3379"` - 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"` - Arch string `yaml:"arch,omitempty"` - OS string `yaml:"os,omitempty"` + Host string `yaml:"host"` + ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` + ListenHost string `yaml:"listen_host,omitempty"` + AdvertiseListenAddr string `yaml:"advertise_listen_addr,omitempty"` + SSHPort int `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"` + IgnoreExporter bool `yaml:"ignore_exporter,omitempty"` + // Use Name to get the name with a default value if it's empty. + Name string `yaml:"name,omitempty"` + Port int `yaml:"port" default:"3379"` + 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"` + Arch string `yaml:"arch,omitempty"` + OS string `yaml:"os,omitempty"` } // Status queries current status of the instance @@ -200,7 +203,6 @@ func (c *TSOComponent) Instances() []Instance { // TSOInstance represent the TSO instance type TSOInstance struct { - Name string BaseInstance topo Topology } @@ -229,6 +231,7 @@ func (i *TSOInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.TSOScript{ + Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), @@ -237,6 +240,9 @@ func (i *TSOInstance) InitConfig( LogDir: paths.Log, NumaNode: spec.NumaNode, } + if !tidbver.PDSupportMicroServicesWithName(version) { + cfg.Name = "" + } fp := filepath.Join(paths.Cache, fmt.Sprintf("run_tso_%s_%d.sh", i.GetHost(), i.GetPort())) if err := cfg.ConfigToFile(fp); err != nil { diff --git a/pkg/cluster/spec/validate.go b/pkg/cluster/spec/validate.go index 99384cbec7..ce73682c01 100644 --- a/pkg/cluster/spec/validate.go +++ b/pkg/cluster/spec/validate.go @@ -984,6 +984,38 @@ func (s *Specification) validatePDNames() error { return nil } +func (s *Specification) validateTSONames() error { + // check tso server name + tsoNames := set.NewStringSet() + for _, tso := range s.TSOServers { + if tso.Name == "" { + continue + } + + if tsoNames.Exist(tso.Name) { + return errors.Errorf("component tso_servers.name is not supported duplicated, the name %s is duplicated", tso.Name) + } + tsoNames.Insert(tso.Name) + } + return nil +} + +func (s *Specification) validateSchedulingNames() error { + // check scheduling server name + schedulingNames := set.NewStringSet() + for _, scheduling := range s.SchedulingServers { + if scheduling.Name == "" { + continue + } + + if schedulingNames.Exist(scheduling.Name) { + return errors.Errorf("component scheduling_servers.name is not supported duplicated, the name %s is duplicated", scheduling.Name) + } + schedulingNames.Insert(scheduling.Name) + } + return nil +} + func (s *Specification) validateTiFlashConfigs() error { c := FindComponent(s, ComponentTiFlash) for _, ins := range c.Instances() { @@ -1063,6 +1095,8 @@ func (s *Specification) Validate() error { s.dirConflictsDetect, s.validateUserGroup, s.validatePDNames, + s.validateTSONames, + s.validateSchedulingNames, s.validateTiSparkSpec, s.validateTiFlashConfigs, s.validateMonitorAgent, diff --git a/pkg/cluster/template/scripts/pdms_test.go b/pkg/cluster/template/scripts/pdms_test.go new file mode 100644 index 0000000000..414f693f1f --- /dev/null +++ b/pkg/cluster/template/scripts/pdms_test.go @@ -0,0 +1,80 @@ +// Copyright 2024 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package scripts + +import ( + "os" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestScheduling(t *testing.T) { + assert := require.New(t) + conf, err := os.CreateTemp("", "scheduling.conf") + assert.Nil(err) + defer os.Remove(conf.Name()) + + cfg := &SchedulingScript{ + Name: "scheduling-0", + ListenURL: "127.0.0.1", + AdvertiseListenURL: "127.0.0.2", + BackendEndpoints: "127.0.0.3", + DeployDir: "/deploy", + DataDir: "/data", + LogDir: "/log", + } + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err := os.ReadFile(conf.Name()) + assert.Nil(err) + assert.True(strings.Contains(string(content), "--name")) + + cfg.Name = "" + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err = os.ReadFile(conf.Name()) + assert.Nil(err) + assert.False(strings.Contains(string(content), "--name")) +} + +func TestTSO(t *testing.T) { + assert := require.New(t) + conf, err := os.CreateTemp("", "tso.conf") + assert.Nil(err) + defer os.Remove(conf.Name()) + + cfg := &TSOScript{ + Name: "tso-0", + ListenURL: "127.0.0.1", + AdvertiseListenURL: "127.0.0.2", + BackendEndpoints: "127.0.0.3", + DeployDir: "/deploy", + DataDir: "/data", + LogDir: "/log", + } + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err := os.ReadFile(conf.Name()) + assert.Nil(err) + assert.True(strings.Contains(string(content), "--name")) + + cfg.Name = "" + err = cfg.ConfigToFile(conf.Name()) + assert.Nil(err) + content, err = os.ReadFile(conf.Name()) + assert.Nil(err) + assert.False(strings.Contains(string(content), "--name")) +} diff --git a/pkg/cluster/template/scripts/scheduling.go b/pkg/cluster/template/scripts/scheduling.go index 6167d9336e..76142485a2 100644 --- a/pkg/cluster/template/scripts/scheduling.go +++ b/pkg/cluster/template/scripts/scheduling.go @@ -24,6 +24,7 @@ import ( // SchedulingScript represent the data to generate scheduling config type SchedulingScript struct { + Name string ListenURL string AdvertiseListenURL string BackendEndpoints string diff --git a/pkg/cluster/template/scripts/tso.go b/pkg/cluster/template/scripts/tso.go index 0197b82c38..91c3bfe1d0 100644 --- a/pkg/cluster/template/scripts/tso.go +++ b/pkg/cluster/template/scripts/tso.go @@ -24,6 +24,7 @@ import ( // TSOScript represent the data to generate tso config type TSOScript struct { + Name string ListenURL string AdvertiseListenURL string BackendEndpoints string diff --git a/pkg/tidbver/tidbver.go b/pkg/tidbver/tidbver.go index c659304a85..c811510cfc 100644 --- a/pkg/tidbver/tidbver.go +++ b/pkg/tidbver/tidbver.go @@ -104,6 +104,11 @@ func PDSupportMicroServices(version string) bool { return semver.Compare(version, "v7.3.0") >= 0 || strings.Contains(version, "nightly") } +// PDSupportMicroServicesWithName return if the given version of PD supports micro services with name. +func PDSupportMicroServicesWithName(version string) bool { + return semver.Compare(version, "v8.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 From 853c6a28fa36d214e58242caa80910a4724e4a98 Mon Sep 17 00:00:00 2001 From: djshow832 Date: Fri, 16 Aug 2024 15:21:48 +0800 Subject: [PATCH 6/8] cluster: fix that scaled nodes don't respect `component_versions` (#2451) * fix component_versions * update logs * add more debug logs * update log place * final commit * use NewPart * fix Signed-off-by: xhe * fix Signed-off-by: xhe * try fix Signed-off-by: xhe * try fix Signed-off-by: xhe * try fix Signed-off-by: xhe * try another version * try fix Signed-off-by: xhe * try fix Signed-off-by: xhe * try Signed-off-by: xhe * use tiproxy.yaml * component_versions * update number --------- Signed-off-by: xhe Co-authored-by: xhe --- .github/workflows/integrate-cluster-cmd.yaml | 5 +- .../workflows/integrate-cluster-scale.yaml | 2 + .github/workflows/integrate-dm.yaml | 2 +- docker/up.sh | 9 +-- pkg/cluster/spec/parse_topology_test.go | 31 +++++++++ pkg/cluster/spec/spec.go | 7 +- tests/tiup-cluster/script/detect_error.sh | 2 - tests/tiup-cluster/script/pull_log.sh | 3 +- tests/tiup-cluster/script/scale_tiproxy.sh | 66 ++++++++----------- tests/tiup-cluster/test_scale_tiproxy.sh | 4 +- tests/tiup-cluster/topo/tiproxy.yaml | 23 +++++++ 11 files changed, 100 insertions(+), 54 deletions(-) create mode 100644 tests/tiup-cluster/topo/tiproxy.yaml diff --git a/.github/workflows/integrate-cluster-cmd.yaml b/.github/workflows/integrate-cluster-cmd.yaml index db14720d69..9bac1e5702 100644 --- a/.github/workflows/integrate-cluster-cmd.yaml +++ b/.github/workflows/integrate-cluster-cmd.yaml @@ -84,6 +84,7 @@ jobs: - name: Collect component log working-directory: ${{ env.working-directory }} + if: ${{ failure() }} # if: always() run: | docker exec tiup-cluster-control bash /tiup-cluster/tests/tiup-cluster/script/pull_log.sh /tiup-cluster/logs @@ -91,6 +92,7 @@ jobs: - name: Detect error log working-directory: ${{ env.working-directory }} + if: ${{ failure() }} # if: always() run: | bash ./tests/tiup-cluster/script/detect_error.sh ./logs/ @@ -105,7 +107,8 @@ jobs: - name: Output cluster debug log working-directory: ${{ env.working-directory }} - if: always() + if: ${{ failure() }} + # if: always() run: | pwd docker ps diff --git a/.github/workflows/integrate-cluster-scale.yaml b/.github/workflows/integrate-cluster-scale.yaml index 7ce19a5f37..78d4b76580 100644 --- a/.github/workflows/integrate-cluster-scale.yaml +++ b/.github/workflows/integrate-cluster-scale.yaml @@ -84,6 +84,7 @@ jobs: - name: Collect component log working-directory: ${{ env.working-directory }} + if: ${{ failure() }} # if: always() run: | docker exec tiup-cluster-control bash /tiup-cluster/tests/tiup-cluster/script/pull_log.sh /tiup-cluster/logs @@ -91,6 +92,7 @@ jobs: - name: Detect error log working-directory: ${{ env.working-directory }} + if: ${{ failure() }} # if: always() run: | bash ./tests/tiup-cluster/script/detect_error.sh ./logs/ diff --git a/.github/workflows/integrate-dm.yaml b/.github/workflows/integrate-dm.yaml index 37ef609075..dd898379eb 100644 --- a/.github/workflows/integrate-dm.yaml +++ b/.github/workflows/integrate-dm.yaml @@ -87,8 +87,8 @@ jobs: - name: Collect component log working-directory: ${{ env.working-directory }} + if: ${{ failure() }} # if: ${{ failure() }} - if: always() run: | docker exec tiup-cluster-control bash -c 'mkdir -p /tiup-cluster/logs; [[ -d ~/.tiup/logs ]] && find ~/.tiup/logs -type f -name "*.log" -exec cp {} /tiup-cluster/logs \; || true' ls ${{ env.working-directory }} diff --git a/docker/up.sh b/docker/up.sh index 468a05a90a..dc7097a4b4 100755 --- a/docker/up.sh +++ b/docker/up.sh @@ -182,9 +182,6 @@ exists python || exists docker || { ERROR "Please install docker (https://docs.docker.com/engine/installation/)"; exit 1; } -exists docker-compose || - { ERROR "Please install docker-compose (https://docs.docker.com/compose/install/)"; - exit 1; } exists pip || { @@ -233,17 +230,17 @@ echo "TIUP_TEST_IP_PREFIX=$ipprefix" >> ./secret/control.env INFO "Running \`docker-compose build\`" # shellcheck disable=SC2086 -docker-compose -f docker-compose.yml ${COMPOSE} ${DEV} build +docker compose -f docker-compose.yml ${COMPOSE} ${DEV} build INFO "Running \`docker-compose up\`" if [ "${RUN_AS_DAEMON}" -eq 1 ]; then # shellcheck disable=SC2086 - docker-compose -f docker-compose.yml ${COMPOSE} ${DEV} up -d + docker compose -f docker-compose.yml ${COMPOSE} ${DEV} up -d INFO "All containers started, run \`docker ps\` to view" else INFO "Please run \`docker exec -it tiup-cluster-control bash\` in another terminal to proceed" # shellcheck disable=SC2086 - docker-compose -f docker-compose.yml ${COMPOSE} ${DEV} up + docker compose -f docker-compose.yml ${COMPOSE} ${DEV} up fi popd diff --git a/pkg/cluster/spec/parse_topology_test.go b/pkg/cluster/spec/parse_topology_test.go index 51d0adfb74..4b544da329 100644 --- a/pkg/cluster/spec/parse_topology_test.go +++ b/pkg/cluster/spec/parse_topology_test.go @@ -540,6 +540,37 @@ tiflash_servers: }) } +func (s *topoSuite) TestMergeComponentVersions(c *check.C) { + // test component version overwrite + with2TempFile(` +component_versions: + tidb: v8.0.0 + tikv: v8.0.0 +tidb_servers: + - host: 172.16.5.139 +`, ` +component_versions: + tikv: v8.1.0 + pd: v8.0.0 +tidb_servers: + - host: 172.16.5.134 +`, func(base, scale string) { + baseTopo := Specification{} + c.Assert(ParseTopologyYaml(base, &baseTopo), check.IsNil) + + scaleTopo := baseTopo.NewPart() + c.Assert(ParseTopologyYaml(scale, scaleTopo), check.IsNil) + + mergedTopo := baseTopo.MergeTopo(scaleTopo) + c.Assert(mergedTopo.Validate(), check.IsNil) + + c.Assert(scaleTopo.(*Specification).ComponentVersions, check.Equals, mergedTopo.(*Specification).ComponentVersions) + c.Assert(scaleTopo.(*Specification).ComponentVersions.TiDB, check.Equals, "v8.0.0") + c.Assert(scaleTopo.(*Specification).ComponentVersions.TiKV, check.Equals, "v8.1.0") + c.Assert(scaleTopo.(*Specification).ComponentVersions.PD, check.Equals, "v8.0.0") + }) +} + func (s *topoSuite) TestFixRelativePath(c *check.C) { // base test topo := Specification{ diff --git a/pkg/cluster/spec/spec.go b/pkg/cluster/spec/spec.go index 99bd0e87dd..f00ae02db3 100644 --- a/pkg/cluster/spec/spec.go +++ b/pkg/cluster/spec/spec.go @@ -270,9 +270,10 @@ type UpgradableMetadata interface { // NewPart implements ScaleOutTopology interface. func (s *Specification) NewPart() Topology { return &Specification{ - GlobalOptions: s.GlobalOptions, - MonitoredOptions: s.MonitoredOptions, - ServerConfigs: s.ServerConfigs, + GlobalOptions: s.GlobalOptions, + MonitoredOptions: s.MonitoredOptions, + ServerConfigs: s.ServerConfigs, + ComponentVersions: s.ComponentVersions, } } diff --git a/tests/tiup-cluster/script/detect_error.sh b/tests/tiup-cluster/script/detect_error.sh index b22c02397c..2fc9b82c3e 100755 --- a/tests/tiup-cluster/script/detect_error.sh +++ b/tests/tiup-cluster/script/detect_error.sh @@ -4,13 +4,11 @@ set -eu err_num=$(find $1 -name "*.log" -exec grep "\[ERROR\]" {} \; | wc -l) if [ ${err_num} != "0" ]; then echo "detect ${err_num} [ERROR] log" - exit 1 fi err_num=$(find $1 -name "*stderr.log" -exec cat {} \; | wc -l) if [ ${err_num} != "0" ]; then echo "detect ${err_num} stderr log" - exit 1 fi echo "no error log found" diff --git a/tests/tiup-cluster/script/pull_log.sh b/tests/tiup-cluster/script/pull_log.sh index c8744df590..b6f131ecd2 100755 --- a/tests/tiup-cluster/script/pull_log.sh +++ b/tests/tiup-cluster/script/pull_log.sh @@ -17,7 +17,8 @@ do logs=$(ssh -o "StrictHostKeyChecking no" root@$h "find /home/tidb | grep '.*log/.*\.log'") for log in $logs do - scp -o "StrictHostKeyChecking no" -r root@$h:$log "$out_dir/$h/" + scp -o "StrictHostKeyChecking no" -pr root@$h:$log "$out_dir/$h/" done fi done +chmod -R 777 $out_dir diff --git a/tests/tiup-cluster/script/scale_tiproxy.sh b/tests/tiup-cluster/script/scale_tiproxy.sh index 91a28cf1dd..eab2e9cf93 100644 --- a/tests/tiup-cluster/script/scale_tiproxy.sh +++ b/tests/tiup-cluster/script/scale_tiproxy.sh @@ -6,87 +6,77 @@ function scale_tiproxy() { mkdir -p ~/.tiup/bin/ version=$1 - test_tls=$2 - native_ssh=$3 + native_ssh=$2 - client="" + common_args="--wait-timeout=360" if [ $native_ssh == true ]; then - client="--ssh=system" + common_args="$common_args --ssh=system" fi name="test_scale_tiproxy_$RANDOM" - if [ $test_tls = true ]; then - topo=./topo/full_tls.yaml - else - topo=./topo/full.yaml - fi + topo=./topo/tiproxy.yaml check_cert_file="ls /home/tidb/deploy/tidb-4000/tls/tiproxy-session.crt /home/tidb/deploy/tidb-4000/tls/tiproxy-session.key" check_cert_config="grep -q session-token-signing-key /home/tidb/deploy/tidb-4000/conf/tidb.toml" - tiup-cluster $client --yes deploy $name $version $topo -i ~/.ssh/id_rsa + tiup-cluster $common_args --yes deploy $name $version $topo -i ~/.ssh/id_rsa # the session certs exist - tiup-cluster $client exec $name -N n1 --command "$check_cert_file" + tiup-cluster $common_args exec $name -N n1 --command "$check_cert_file" # the configurations are updated - tiup-cluster $client exec $name -N n1 --command "$check_cert_config" + tiup-cluster $common_args exec $name -N n1 --command "$check_cert_config" - tiup-cluster $client list | grep "$name" + tiup-cluster $common_args list | grep "$name" - tiup-cluster $client --yes start $name + tiup-cluster $common_args --yes start $name - tiup-cluster $client _test $name writable + tiup-cluster $common_args _test $name writable - tiup-cluster $client display $name + tiup-cluster $common_args display $name - tiup-cluster $client --yes reload $name --skip-restart + tiup-cluster $common_args --yes reload $name --skip-restart - if [ $test_tls = true ]; then - total_sub_one=18 - total=19 - else - total_sub_one=23 - total=24 - fi + total_sub_one=7 + total=8 # disable tiproxy echo "start scale in tiproxy" - tiup-cluster $client --yes scale-in $name -N n1:6000 + tiup-cluster $common_args --yes scale-in $name -N n1:6000 wait_instance_num_reach $name $total $native_ssh # scale in tidb and scale out again echo "start scale in tidb" - tiup-cluster $client --yes scale-in $name -N n2:4000 + tiup-cluster $common_args --yes scale-in $name -N n2:4000 wait_instance_num_reach $name $total_sub_one $native_ssh echo "start scale out tidb" topo=./topo/full_scale_in_tidb_2nd.yaml - tiup-cluster $client --yes scale-out $name $topo + tiup-cluster $common_args --yes scale-out $name $topo # the session certs don't exist on the new tidb - ! tiup-cluster $client exec $name -N n2 --command "$check_cert_file" + ! tiup-cluster $common_args exec $name -N n2 --command "$check_cert_file" # the configurations are not updated on the new tidb - ! tiup-cluster $client exec $name -N n2 --command "$check_cert_config" + ! tiup-cluster $common_args exec $name -N n2 --command "$check_cert_config" # enable tiproxy again echo "start scale out tiproxy" topo=./topo/full_scale_in_tiproxy.yaml - tiup-cluster $client --yes scale-out $name $topo + tiup-cluster $common_args --yes scale-out $name $topo # the session certs exist on the new tidb - tiup-cluster $client exec $name -N n2 --command "$check_cert_file" + tiup-cluster $common_args exec $name -N n2 --command "$check_cert_file" # the configurations are updated on the new tidb - tiup-cluster $client exec $name -N n2 --command "$check_cert_config" + tiup-cluster $common_args exec $name -N n2 --command "$check_cert_config" # scale in tidb and scale out again echo "start scale in tidb" - tiup-cluster $client --yes scale-in $name -N n2:4000 + tiup-cluster $common_args --yes scale-in $name -N n2:4000 wait_instance_num_reach $name $total $native_ssh echo "start scale out tidb" topo=./topo/full_scale_in_tidb_2nd.yaml - tiup-cluster $client --yes scale-out $name $topo + tiup-cluster $common_args --yes scale-out $name $topo # the session certs exist on the new tidb - tiup-cluster $client exec $name -N n2 --command "$check_cert_file" + tiup-cluster $common_args exec $name -N n2 --command "$check_cert_file" # the configurations are updated on the new tidb - tiup-cluster $client exec $name -N n2 --command "$check_cert_config" + tiup-cluster $common_args exec $name -N n2 --command "$check_cert_config" - tiup-cluster $client _test $name writable - tiup-cluster $client --yes destroy $name + tiup-cluster $common_args _test $name writable + tiup-cluster $common_args --yes destroy $name } diff --git a/tests/tiup-cluster/test_scale_tiproxy.sh b/tests/tiup-cluster/test_scale_tiproxy.sh index d5f6124070..db251e545b 100644 --- a/tests/tiup-cluster/test_scale_tiproxy.sh +++ b/tests/tiup-cluster/test_scale_tiproxy.sh @@ -4,5 +4,5 @@ set -eu source script/scale_tiproxy.sh -echo "test scaling of tidb and tiproxy in cluster for version v8.1.0, via easy ssh" -scale_tiproxy v8.1.0 false false +echo "test scaling of tidb and tiproxy in cluster for version v8.2.0, via easy ssh" +scale_tiproxy v8.2.0 false diff --git a/tests/tiup-cluster/topo/tiproxy.yaml b/tests/tiup-cluster/topo/tiproxy.yaml new file mode 100644 index 0000000000..6788506982 --- /dev/null +++ b/tests/tiup-cluster/topo/tiproxy.yaml @@ -0,0 +1,23 @@ +global: + user: tidb + group: pingcap + +component_versions: + tiproxy: v1.2.0 + +tidb_servers: + - host: n1 + - host: n2 + +pd_servers: + - host: n3 + - host: n4 + - host: n5 + +tikv_servers: + - host: n3 + - host: n4 + - host: n5 + +tiproxy_servers: + - host: n1 From b5bd3bbbc2b359b1aaa3481c5cf446c5bb8e9ea2 Mon Sep 17 00:00:00 2001 From: Wenxuan Date: Tue, 20 Aug 2024 13:34:32 +0800 Subject: [PATCH 7/8] playground: Allow specifying port offset (#2453) Signed-off-by: Wish --- components/playground/grafana.go | 8 +--- components/playground/instance/drainer.go | 4 +- components/playground/instance/instance.go | 5 ++- components/playground/instance/pd.go | 6 +-- components/playground/instance/pump.go | 4 +- components/playground/instance/ticdc.go | 4 +- components/playground/instance/tidb.go | 6 +-- components/playground/instance/tiflash.go | 14 +++---- components/playground/instance/tikv.go | 6 +-- components/playground/instance/tikv_cdc.go | 4 +- components/playground/instance/tiproxy.go | 6 +-- components/playground/main.go | 19 +++++---- components/playground/monitor.go | 8 ++-- components/playground/ngmonitoring.go | 8 +--- components/playground/playground.go | 45 +++++++++++----------- pkg/proxy/proxy.go | 6 +-- pkg/proxy/tcp_proxy.go | 6 +-- pkg/utils/freeport.go | 10 ++--- pkg/utils/freeport_test.go | 4 +- 19 files changed, 78 insertions(+), 95 deletions(-) diff --git a/components/playground/grafana.go b/components/playground/grafana.go index bccae98c76..1a5573f3f7 100644 --- a/components/playground/grafana.go +++ b/components/playground/grafana.go @@ -151,12 +151,8 @@ var clusterName = "Test-Cluster" // dir should contains files untar the grafana. // return not error iff the Cmd is started successfully. -func (g *grafana) start(ctx context.Context, dir string, p8sURL string) (err error) { - g.port, err = utils.GetFreePort(g.host, g.port) - if err != nil { - return err - } - +func (g *grafana) start(ctx context.Context, dir string, portOffset int, p8sURL string) (err error) { + g.port = utils.MustGetFreePort(g.host, g.port, portOffset) fname := filepath.Join(dir, "conf", "provisioning", "dashboards", "dashboard.yml") err = writeDashboardConfig(fname, clusterName, filepath.Join(dir, "dashboards")) if err != nil { diff --git a/components/playground/instance/drainer.go b/components/playground/instance/drainer.go index f72aa4523f..30bf937871 100644 --- a/components/playground/instance/drainer.go +++ b/components/playground/instance/drainer.go @@ -32,14 +32,14 @@ type Drainer struct { var _ Instance = &Drainer{} // NewDrainer create a Drainer instance. -func NewDrainer(binPath string, dir, host, configPath string, id int, pds []*PDInstance) *Drainer { +func NewDrainer(binPath string, dir, host, configPath string, portOffset int, id int, pds []*PDInstance) *Drainer { d := &Drainer{ instance: instance{ BinPath: binPath, ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, 8250), + Port: utils.MustGetFreePort(host, 8250, portOffset), ConfigPath: configPath, }, pds: pds, diff --git a/components/playground/instance/instance.go b/components/playground/instance/instance.go index 9766fd67f2..1a97e4c6d2 100644 --- a/components/playground/instance/instance.go +++ b/components/playground/instance/instance.go @@ -24,6 +24,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tiup/pkg/cluster/spec" tiupexec "github.com/pingcap/tiup/pkg/exec" + "github.com/pingcap/tiup/pkg/tui/colorstr" "github.com/pingcap/tiup/pkg/utils" ) @@ -98,9 +99,9 @@ func (inst *instance) PrepareBinary(componentName string, version utils.Version) } // distinguish whether the instance is started by specific binary path. if inst.BinPath == "" { - fmt.Printf("Start %s instance:%s\n", componentName, version) + colorstr.Printf("[dark_gray]Start %s instance: %s[reset]\n", componentName, version) } else { - fmt.Printf("Start %s instance:%s\n", componentName, instanceBinPath) + colorstr.Printf("[dark_gray]Start %s instance: %s[reset]\n", componentName, instanceBinPath) } inst.Version = version inst.BinPath = instanceBinPath diff --git a/components/playground/instance/pd.go b/components/playground/instance/pd.go index 67b2e53ed2..8c699b990c 100644 --- a/components/playground/instance/pd.go +++ b/components/playground/instance/pd.go @@ -50,7 +50,7 @@ type PDInstance struct { } // NewPDInstance return a PDInstance -func NewPDInstance(role PDRole, binPath, dir, host, configPath string, id int, pds []*PDInstance, port int, isCSEMode bool) *PDInstance { +func NewPDInstance(role PDRole, binPath, dir, host, configPath string, portOffset int, id int, pds []*PDInstance, port int, isCSEMode bool) *PDInstance { if port <= 0 { port = 2379 } @@ -60,8 +60,8 @@ func NewPDInstance(role PDRole, binPath, dir, host, configPath string, id int, p ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, 2380), - StatusPort: utils.MustGetFreePort(host, port), + Port: utils.MustGetFreePort(host, 2380, portOffset), + StatusPort: utils.MustGetFreePort(host, port, portOffset), ConfigPath: configPath, }, Role: role, diff --git a/components/playground/instance/pump.go b/components/playground/instance/pump.go index e4ca34b9cd..a5880fb7b4 100644 --- a/components/playground/instance/pump.go +++ b/components/playground/instance/pump.go @@ -34,14 +34,14 @@ type Pump struct { var _ Instance = &Pump{} // NewPump create a Pump instance. -func NewPump(binPath string, dir, host, configPath string, id int, pds []*PDInstance) *Pump { +func NewPump(binPath string, dir, host, configPath string, portOffset int, id int, pds []*PDInstance) *Pump { pump := &Pump{ instance: instance{ BinPath: binPath, ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, 8249), + Port: utils.MustGetFreePort(host, 8249, portOffset), ConfigPath: configPath, }, pds: pds, diff --git a/components/playground/instance/ticdc.go b/components/playground/instance/ticdc.go index b233e8622f..62288f3525 100644 --- a/components/playground/instance/ticdc.go +++ b/components/playground/instance/ticdc.go @@ -33,7 +33,7 @@ type TiCDC struct { var _ Instance = &TiCDC{} // NewTiCDC create a TiCDC instance. -func NewTiCDC(binPath string, dir, host, configPath string, id int, port int, pds []*PDInstance) *TiCDC { +func NewTiCDC(binPath string, dir, host, configPath string, portOffset int, id int, port int, pds []*PDInstance) *TiCDC { if port <= 0 { port = 8300 } @@ -43,7 +43,7 @@ func NewTiCDC(binPath string, dir, host, configPath string, id int, port int, pd ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, port), + Port: utils.MustGetFreePort(host, port, portOffset), ConfigPath: configPath, }, pds: pds, diff --git a/components/playground/instance/tidb.go b/components/playground/instance/tidb.go index 20b89e92a2..b5496ffca1 100644 --- a/components/playground/instance/tidb.go +++ b/components/playground/instance/tidb.go @@ -34,7 +34,7 @@ type TiDBInstance struct { } // NewTiDBInstance return a TiDBInstance -func NewTiDBInstance(binPath string, dir, host, configPath string, id, port int, pds []*PDInstance, tiproxyCertDir string, enableBinlog bool, isCSEMode bool) *TiDBInstance { +func NewTiDBInstance(binPath string, dir, host, configPath string, portOffset int, id, port int, pds []*PDInstance, tiproxyCertDir string, enableBinlog bool, isCSEMode bool) *TiDBInstance { if port <= 0 { port = 4000 } @@ -44,8 +44,8 @@ func NewTiDBInstance(binPath string, dir, host, configPath string, id, port int, ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, port), - StatusPort: utils.MustGetFreePort("0.0.0.0", 10080), + Port: utils.MustGetFreePort(host, port, portOffset), + StatusPort: utils.MustGetFreePort("0.0.0.0", 10080, portOffset), ConfigPath: configPath, }, tiproxyCertDir: tiproxyCertDir, diff --git a/components/playground/instance/tiflash.go b/components/playground/instance/tiflash.go index 995c7df3b1..6a35d8a3d9 100644 --- a/components/playground/instance/tiflash.go +++ b/components/playground/instance/tiflash.go @@ -53,14 +53,14 @@ type TiFlashInstance struct { } // NewTiFlashInstance return a TiFlashInstance -func NewTiFlashInstance(role TiFlashRole, cseOptions CSEOptions, binPath, dir, host, configPath string, id int, pds []*PDInstance, dbs []*TiDBInstance, version string) *TiFlashInstance { +func NewTiFlashInstance(role TiFlashRole, cseOptions CSEOptions, binPath, dir, host, configPath string, portOffset int, id int, pds []*PDInstance, dbs []*TiDBInstance, version string) *TiFlashInstance { if role != TiFlashRoleNormal && role != TiFlashRoleDisaggWrite && role != TiFlashRoleDisaggCompute { panic(fmt.Sprintf("Unknown TiFlash role %s", role)) } httpPort := 8123 if !tidbver.TiFlashNotNeedHTTPPortConfig(version) { - httpPort = utils.MustGetFreePort(host, httpPort) + httpPort = utils.MustGetFreePort(host, httpPort, portOffset) } return &TiFlashInstance{ instance: instance{ @@ -69,15 +69,15 @@ func NewTiFlashInstance(role TiFlashRole, cseOptions CSEOptions, binPath, dir, h Dir: dir, Host: host, Port: httpPort, - StatusPort: utils.MustGetFreePort(host, 8234), + StatusPort: utils.MustGetFreePort(host, 8234, portOffset), ConfigPath: configPath, }, Role: role, cseOpts: cseOptions, - TCPPort: utils.MustGetFreePort(host, 9100), // 9000 for default object store port - ServicePort: utils.MustGetFreePort(host, 3930), - ProxyPort: utils.MustGetFreePort(host, 20170), - ProxyStatusPort: utils.MustGetFreePort(host, 20292), + TCPPort: utils.MustGetFreePort(host, 9100, portOffset), // 9000 for default object store port + ServicePort: utils.MustGetFreePort(host, 3930, portOffset), + ProxyPort: utils.MustGetFreePort(host, 20170, portOffset), + ProxyStatusPort: utils.MustGetFreePort(host, 20292, portOffset), pds: pds, dbs: dbs, } diff --git a/components/playground/instance/tikv.go b/components/playground/instance/tikv.go index f70ec1bd96..8c97acd018 100644 --- a/components/playground/instance/tikv.go +++ b/components/playground/instance/tikv.go @@ -36,7 +36,7 @@ type TiKVInstance struct { } // NewTiKVInstance return a TiKVInstance -func NewTiKVInstance(binPath string, dir, host, configPath string, id int, port int, pds []*PDInstance, tsos []*PDInstance, isCSEMode bool, cseOptions CSEOptions, isPDMSMode bool) *TiKVInstance { +func NewTiKVInstance(binPath string, dir, host, configPath string, portOffset int, id int, port int, pds []*PDInstance, tsos []*PDInstance, isCSEMode bool, cseOptions CSEOptions, isPDMSMode bool) *TiKVInstance { if port <= 0 { port = 20160 } @@ -46,8 +46,8 @@ func NewTiKVInstance(binPath string, dir, host, configPath string, id int, port ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, port), - StatusPort: utils.MustGetFreePort(host, 20180), + Port: utils.MustGetFreePort(host, port, portOffset), + StatusPort: utils.MustGetFreePort(host, 20180, portOffset), ConfigPath: configPath, }, pds: pds, diff --git a/components/playground/instance/tikv_cdc.go b/components/playground/instance/tikv_cdc.go index cbacb23b2e..8fd717dc32 100644 --- a/components/playground/instance/tikv_cdc.go +++ b/components/playground/instance/tikv_cdc.go @@ -32,14 +32,14 @@ type TiKVCDC struct { var _ Instance = &TiKVCDC{} // NewTiKVCDC create a TiKVCDC instance. -func NewTiKVCDC(binPath string, dir, host, configPath string, id int, pds []*PDInstance) *TiKVCDC { +func NewTiKVCDC(binPath string, dir, host, configPath string, portOffset int, id int, pds []*PDInstance) *TiKVCDC { tikvCdc := &TiKVCDC{ instance: instance{ BinPath: binPath, ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, 8600), + Port: utils.MustGetFreePort(host, 8600, portOffset), ConfigPath: configPath, }, pds: pds, diff --git a/components/playground/instance/tiproxy.go b/components/playground/instance/tiproxy.go index c0ed180c90..db43d9284c 100644 --- a/components/playground/instance/tiproxy.go +++ b/components/playground/instance/tiproxy.go @@ -68,7 +68,7 @@ func GenTiProxySessionCerts(dir string) error { } // NewTiProxy create a TiProxy instance. -func NewTiProxy(binPath string, dir, host, configPath string, id int, port int, pds []*PDInstance) *TiProxy { +func NewTiProxy(binPath string, dir, host, configPath string, portOffset int, id int, port int, pds []*PDInstance) *TiProxy { if port <= 0 { port = 6000 } @@ -78,8 +78,8 @@ func NewTiProxy(binPath string, dir, host, configPath string, id int, port int, ID: id, Dir: dir, Host: host, - Port: utils.MustGetFreePort(host, port), - StatusPort: utils.MustGetFreePort(host, 3080), + Port: utils.MustGetFreePort(host, port, portOffset), + StatusPort: utils.MustGetFreePort(host, 3080, portOffset), ConfigPath: configPath, }, pds: pds, diff --git a/components/playground/main.go b/components/playground/main.go index 47531897a6..ad0429e258 100644 --- a/components/playground/main.go +++ b/components/playground/main.go @@ -75,6 +75,7 @@ type BootOptions struct { Monitor bool `yaml:"monitor"` CSEOpts instance.CSEOptions `yaml:"cse"` // Only available when mode == tidb-cse GrafanaPort int `yaml:"grafana_port"` + PortOffset int `yaml:"port_offset"` } var ( @@ -175,11 +176,8 @@ Examples: return err } - port, err := utils.GetFreePort("0.0.0.0", 9527) - if err != nil { - return err - } - err = dumpPort(filepath.Join(dataDir, "port"), port) + port := utils.MustGetFreePort("0.0.0.0", 9527, options.PortOffset) + err := dumpPort(filepath.Join(dataDir, "port"), port) p := NewPlayground(dataDir, port) if err != nil { return err @@ -207,7 +205,7 @@ Examples: sig := (<-sc).(syscall.Signal) atomic.StoreInt32(&p.curSig, int32(sig)) - fmt.Println("Playground receive signal: ", sig) + colorstr.Printf("\n[red][bold]Playground receive signal: %s[reset]\n", sig) // if bootCluster is not done we just cancel context to make it // clean up and return ASAP and exit directly after timeout. @@ -283,6 +281,7 @@ Note: Version constraint [bold]%s[reset] is resolved to [green][bold]%s[reset]. rootCmd.Flags().BoolVar(&options.Monitor, "monitor", true, "Start prometheus and grafana component") _ = rootCmd.Flags().MarkDeprecated("monitor", "Please use --without-monitor to control whether to disable monitor.") rootCmd.Flags().IntVar(&options.GrafanaPort, "grafana.port", 3000, "grafana port. If not provided, grafana will use 3000 as its port.") + rootCmd.Flags().IntVar(&options.PortOffset, "port-offset", 0, "If specified, all components will use default_port+port_offset as the port. This argument is useful when you want to start multiple playgrounds on the same host. Recommend to set to 10000, 20000, etc.") // NOTE: Do not set default values if they may be changed in different modes. @@ -347,10 +346,10 @@ Note: Version constraint [bold]%s[reset] is resolved to [green][bold]%s[reset]. rootCmd.Flags().StringVar(&options.TiKVCDC.Version, "kvcdc.version", "", "TiKV-CDC instance version") - rootCmd.Flags().StringVar(&options.CSEOpts.S3Endpoint, "cse.s3_endpoint", "http://127.0.0.1:9000", "Object store URL for the disaggregated TiFlash, available when --mode=tidb-cse") - rootCmd.Flags().StringVar(&options.CSEOpts.Bucket, "cse.bucket", "tiflash", "Object store bucket for the disaggregated TiFlash, available when --mode=tidb-cse") - rootCmd.Flags().StringVar(&options.CSEOpts.AccessKey, "cse.access_key", "minioadmin", "Object store access key, available when --mode=tidb-cse") - rootCmd.Flags().StringVar(&options.CSEOpts.SecretKey, "cse.secret_key", "minioadmin", "Object store secret key, available when --mode=tidb-cse") + rootCmd.Flags().StringVar(&options.CSEOpts.S3Endpoint, "cse.s3_endpoint", "http://127.0.0.1:9000", "Object store URL for --mode=tidb-cse") + rootCmd.Flags().StringVar(&options.CSEOpts.Bucket, "cse.bucket", "tiflash", "Object store bucket for --mode=tidb-cse") + rootCmd.Flags().StringVar(&options.CSEOpts.AccessKey, "cse.access_key", "minioadmin", "Object store access key for --mode=tidb-cse") + rootCmd.Flags().StringVar(&options.CSEOpts.SecretKey, "cse.secret_key", "minioadmin", "Object store secret key for --mode=tidb-cse") rootCmd.AddCommand(newDisplay()) rootCmd.AddCommand(newScaleOut()) diff --git a/components/playground/monitor.go b/components/playground/monitor.go index 3d17a7edae..94c52a09af 100644 --- a/components/playground/monitor.go +++ b/components/playground/monitor.go @@ -78,15 +78,12 @@ func (m *monitor) wait() error { } // the cmd is not started after return -func newMonitor(ctx context.Context, version string, host, dir string) (*monitor, error) { +func newMonitor(ctx context.Context, version string, host, dir string, portOffset int) (*monitor, error) { if err := utils.MkdirAll(dir, 0755); err != nil { return nil, errors.AddStack(err) } - port, err := utils.GetFreePort(host, 9090) - if err != nil { - return nil, err - } + port := utils.MustGetFreePort(host, 9090, portOffset) addr := utils.JoinHostPort(host, port) tmpl := ` @@ -132,6 +129,7 @@ scrape_configs: } var binPath string + var err error if binPath, err = tiupexec.PrepareBinary("prometheus", utils.Version(version), binPath); err != nil { return nil, err } diff --git a/components/playground/ngmonitoring.go b/components/playground/ngmonitoring.go index beb7a58552..851435b53a 100644 --- a/components/playground/ngmonitoring.go +++ b/components/playground/ngmonitoring.go @@ -45,16 +45,12 @@ func (m *ngMonitoring) wait() error { } // the cmd is not started after return -func newNGMonitoring(ctx context.Context, version string, host, dir string, pds []*instance.PDInstance) (*ngMonitoring, error) { +func newNGMonitoring(ctx context.Context, version string, host, dir string, portOffset int, pds []*instance.PDInstance) (*ngMonitoring, error) { if err := utils.MkdirAll(dir, 0755); err != nil { return nil, errors.AddStack(err) } - port, err := utils.GetFreePort(host, 12020) - if err != nil { - return nil, err - } - + port := utils.MustGetFreePort(host, 12020, portOffset) m := new(ngMonitoring) var endpoints []string for _, pd := range pds { diff --git a/components/playground/playground.go b/components/playground/playground.go index 9fa18b1cf4..17c08ef3c9 100644 --- a/components/playground/playground.go +++ b/components/playground/playground.go @@ -41,6 +41,7 @@ import ( "github.com/pingcap/tiup/pkg/environment" logprinter "github.com/pingcap/tiup/pkg/logger/printer" "github.com/pingcap/tiup/pkg/tidbver" + "github.com/pingcap/tiup/pkg/tui/colorstr" "github.com/pingcap/tiup/pkg/tui/progress" "github.com/pingcap/tiup/pkg/utils" "golang.org/x/mod/semver" @@ -722,7 +723,7 @@ func (p *Playground) addInstance(componentID string, pdRole instance.PDRole, tif switch componentID { case spec.ComponentPD: - inst := instance.NewPDInstance(pdRole, cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds, cfg.Port, p.bootOptions.Mode == "tidb-cse") + inst := instance.NewPDInstance(pdRole, cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds, cfg.Port, p.bootOptions.Mode == "tidb-cse") ins = inst if pdRole == instance.PDRoleNormal || pdRole == instance.PDRoleAPI { if p.booted { @@ -740,46 +741,46 @@ func (p *Playground) addInstance(componentID string, pdRole instance.PDRole, tif p.schedulings = append(p.schedulings, inst) } case spec.ComponentTSO: - inst := instance.NewPDInstance(instance.PDRoleTSO, cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds, cfg.Port, p.bootOptions.Mode == "tidb-cse") + inst := instance.NewPDInstance(instance.PDRoleTSO, cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds, cfg.Port, p.bootOptions.Mode == "tidb-cse") ins = inst p.tsos = append(p.tsos, inst) case spec.ComponentScheduling: - inst := instance.NewPDInstance(instance.PDRoleScheduling, cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds, cfg.Port, p.bootOptions.Mode == "tidb-cse") + inst := instance.NewPDInstance(instance.PDRoleScheduling, cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds, cfg.Port, p.bootOptions.Mode == "tidb-cse") ins = inst p.schedulings = append(p.schedulings, inst) case spec.ComponentTiDB: - inst := instance.NewTiDBInstance(cfg.BinPath, dir, host, cfg.ConfigPath, id, cfg.Port, p.pds, dataDir, p.enableBinlog(), p.bootOptions.Mode == "tidb-cse") + inst := instance.NewTiDBInstance(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, cfg.Port, p.pds, dataDir, p.enableBinlog(), p.bootOptions.Mode == "tidb-cse") ins = inst p.tidbs = append(p.tidbs, inst) case spec.ComponentTiKV: - inst := instance.NewTiKVInstance(cfg.BinPath, dir, host, cfg.ConfigPath, id, cfg.Port, p.pds, p.tsos, p.bootOptions.Mode == "tidb-cse", p.bootOptions.CSEOpts, p.bootOptions.PDMode == "ms") + inst := instance.NewTiKVInstance(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, cfg.Port, p.pds, p.tsos, p.bootOptions.Mode == "tidb-cse", p.bootOptions.CSEOpts, p.bootOptions.PDMode == "ms") ins = inst p.tikvs = append(p.tikvs, inst) case spec.ComponentTiFlash: - inst := instance.NewTiFlashInstance(tiflashRole, p.bootOptions.CSEOpts, cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds, p.tidbs, cfg.Version) + inst := instance.NewTiFlashInstance(tiflashRole, p.bootOptions.CSEOpts, cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds, p.tidbs, cfg.Version) ins = inst p.tiflashs = append(p.tiflashs, inst) case spec.ComponentTiProxy: if err := instance.GenTiProxySessionCerts(dataDir); err != nil { return nil, err } - inst := instance.NewTiProxy(cfg.BinPath, dir, host, cfg.ConfigPath, id, cfg.Port, p.pds) + inst := instance.NewTiProxy(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, cfg.Port, p.pds) ins = inst p.tiproxys = append(p.tiproxys, inst) case spec.ComponentCDC: - inst := instance.NewTiCDC(cfg.BinPath, dir, host, cfg.ConfigPath, id, cfg.Port, p.pds) + inst := instance.NewTiCDC(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, cfg.Port, p.pds) ins = inst p.ticdcs = append(p.ticdcs, inst) case spec.ComponentTiKVCDC: - inst := instance.NewTiKVCDC(cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds) + inst := instance.NewTiKVCDC(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds) ins = inst p.tikvCdcs = append(p.tikvCdcs, inst) case spec.ComponentPump: - inst := instance.NewPump(cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds) + inst := instance.NewPump(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds) ins = inst p.pumps = append(p.pumps, inst) case spec.ComponentDrainer: - inst := instance.NewDrainer(cfg.BinPath, dir, host, cfg.ConfigPath, id, p.pds) + inst := instance.NewDrainer(cfg.BinPath, dir, host, cfg.ConfigPath, options.PortOffset, id, p.pds) ins = inst p.drainers = append(p.drainers, inst) default: @@ -797,13 +798,13 @@ func (p *Playground) waitAllDBUp() ([]string, []string) { var tidbMu, tiproxyMu sync.Mutex var bars *progress.MultiBar if len(p.tiproxys) > 0 { - bars = progress.NewMultiBar(color.YellowString("Waiting for tidb and tiproxy instances ready")) + bars = progress.NewMultiBar(colorstr.Sprintf("[dark_gray]Waiting for tidb and tiproxy instances ready")) } else { - bars = progress.NewMultiBar(color.YellowString("Waiting for tidb instances ready")) + bars = progress.NewMultiBar(colorstr.Sprintf("[dark_gray]Waiting for tidb instances ready")) } for _, db := range p.tidbs { wg.Add(1) - prefix := color.YellowString(db.Addr()) + prefix := db.Addr() bar := bars.AddBar(prefix) go func(dbInst *instance.TiDBInstance) { defer wg.Done() @@ -868,10 +869,10 @@ func (p *Playground) waitAllTiFlashUp() { ) var wg sync.WaitGroup - bars := progress.NewMultiBar(color.YellowString("Waiting for tiflash instances ready")) + bars := progress.NewMultiBar(colorstr.Sprintf("[dark_gray]Waiting for tiflash instances ready")) for _, flash := range p.tiflashs { wg.Add(1) - prefix := color.YellowString(flash.Addr()) + prefix := flash.Addr() bar := bars.AddBar(prefix) go func(flashInst *instance.TiFlashInstance) { defer wg.Done() @@ -1014,7 +1015,7 @@ func (p *Playground) bootCluster(ctx context.Context, env *environment.Environme // Try to create bucket. err := s3Client.MakeBucket(ctxCheck, options.CSEOpts.Bucket, minio.MakeBucketOptions{}) if err != nil { - return fmt.Errorf("CSE mode preflight check failed: Bucket %s doesn't exist", options.CSEOpts.Bucket) + return fmt.Errorf("CSE mode preflight check failed: Bucket %s doesn't exist and fail to create automatically (your bucket name may be invalid?)", options.CSEOpts.Bucket) } } @@ -1228,9 +1229,9 @@ func (p *Playground) wait() error { func (p *Playground) terminate(sig syscall.Signal) { kill := func(name string, pid int, wait func() error) { if sig == syscall.SIGKILL { - fmt.Printf("Force %s(%d) to quit...\n", name, pid) + colorstr.Printf("[dark_gray]Force %s(%d) to quit...\n", name, pid) } else if atomic.LoadInt32(&p.curSig) == int32(sig) { // In case of double ctr+c - fmt.Printf("Wait %s(%d) to quit...\n", name, pid) + colorstr.Printf("[dark_gray]Wait %s(%d) to quit...\n", name, pid) } _ = syscall.Kill(pid, sig) @@ -1346,7 +1347,7 @@ func (p *Playground) bootMonitor(ctx context.Context, env *environment.Environme dataDir := p.dataDir promDir := filepath.Join(dataDir, "prometheus") - monitor, err := newMonitor(ctx, options.Version, options.Host, promDir) + monitor, err := newMonitor(ctx, options.Version, options.Host, promDir, options.PortOffset) if err != nil { return nil, nil, err } @@ -1390,7 +1391,7 @@ func (p *Playground) bootNGMonitoring(ctx context.Context, env *environment.Envi dataDir := p.dataDir promDir := filepath.Join(dataDir, "prometheus") - ngm, err := newNGMonitoring(ctx, options.Version, options.Host, promDir, p.pds) + ngm, err := newNGMonitoring(ctx, options.Version, options.Host, promDir, options.PortOffset, p.pds) if err != nil { return nil, err } @@ -1469,7 +1470,7 @@ func (p *Playground) bootGrafana(ctx context.Context, env *environment.Environme grafana := newGrafana(options.Version, options.Host, options.GrafanaPort) // fmt.Println("Start Grafana instance...") - err = grafana.start(ctx, grafanaDir, "http://"+utils.JoinHostPort(monitorInfo.IP, monitorInfo.Port)) + err = grafana.start(ctx, grafanaDir, options.PortOffset, "http://"+utils.JoinHostPort(monitorInfo.IP, monitorInfo.Port)) if err != nil { return nil, err } diff --git a/pkg/proxy/proxy.go b/pkg/proxy/proxy.go index e83df39df6..63b1dd6384 100644 --- a/pkg/proxy/proxy.go +++ b/pkg/proxy/proxy.go @@ -49,11 +49,7 @@ func MaybeStartProxy( return err } - httpPort, err := utils.GetFreePort("127.0.0.1", 12345) - if err != nil { - return err - } - + httpPort := utils.MustGetFreePort("127.0.0.1", 12345, 0) addr := fmt.Sprintf("127.0.0.1:%d", httpPort) // TODO: Using environment variables to share data may not be a good idea diff --git a/pkg/proxy/tcp_proxy.go b/pkg/proxy/tcp_proxy.go index d758c06506..6250e9fd7f 100644 --- a/pkg/proxy/tcp_proxy.go +++ b/pkg/proxy/tcp_proxy.go @@ -66,11 +66,7 @@ func NewTCPProxy( p.config.Password = password } - port, err := utils.GetFreePort("127.0.0.1", 22345) - if err != nil { - logger.Errorf("get free port error: %v", err) - return nil - } + port = utils.MustGetFreePort("127.0.0.1", 22345, 0) p.endpoint = fmt.Sprintf("127.0.0.1:%d", port) listener, err := net.Listen("tcp", p.endpoint) diff --git a/pkg/utils/freeport.go b/pkg/utils/freeport.go index 24b6f30e19..b5d6bbd685 100644 --- a/pkg/utils/freeport.go +++ b/pkg/utils/freeport.go @@ -22,9 +22,8 @@ import ( // To avoid the same port be generated twice in a short time var portCache sync.Map -// GetFreePort asks the kernel for a free open port that is ready to use. -func GetFreePort(host string, priority int) (int, error) { - if port, err := getPort(host, priority); err == nil { +func getFreePort(host string, defaultPort int) (int, error) { + if port, err := getPort(host, defaultPort); err == nil { return port, nil } else if port, err := getPort(host, 0); err == nil { return port, nil @@ -34,8 +33,9 @@ func GetFreePort(host string, priority int) (int, error) { } // MustGetFreePort asks the kernel for a free open port that is ready to use, if fail, panic -func MustGetFreePort(host string, priority int) int { - if port, err := GetFreePort(host, priority); err == nil { +func MustGetFreePort(host string, defaultPort int, portOffset int) int { + bestPort := defaultPort + portOffset + if port, err := getFreePort(host, bestPort); err == nil { return port } panic("can't get a free port") diff --git a/pkg/utils/freeport_test.go b/pkg/utils/freeport_test.go index c32b1d3cfa..23ab8a1f64 100644 --- a/pkg/utils/freeport_test.go +++ b/pkg/utils/freeport_test.go @@ -10,11 +10,11 @@ type TestFreePortSuite struct{} func (s *TestFreePortSuite) TestGetFreePort(c *C) { expected := 22334 - port, err := GetFreePort("127.0.0.1", expected) + port, err := getFreePort("127.0.0.1", expected) c.Assert(err, IsNil) c.Assert(port, Equals, expected, Commentf("expect port %s", expected)) - port, err = GetFreePort("127.0.0.1", expected) + port, err = getFreePort("127.0.0.1", expected) c.Assert(err, IsNil) c.Assert(port == expected, IsFalse, Commentf("should not return same port twice")) } From a16d04fccb22106a5c8b2d7d074b7ab94a1dd677 Mon Sep 17 00:00:00 2001 From: bb7133 Date: Tue, 27 Aug 2024 23:21:14 -0700 Subject: [PATCH 8/8] pkg/crypto: replace 'math/rand' with 'crypto/rand' (#2455) --- pkg/crypto/rand/rand.go | 55 ++++++++++++++++++++++------------------- pkg/telemetry/meta.go | 2 +- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/pkg/crypto/rand/rand.go b/pkg/crypto/rand/rand.go index ebf77edbe6..aad1108dbb 100644 --- a/pkg/crypto/rand/rand.go +++ b/pkg/crypto/rand/rand.go @@ -14,42 +14,45 @@ package rand import ( - cr "crypto/rand" - "encoding/binary" - "fmt" - "math/rand" + "crypto/rand" + "io" + "math/big" ) -var ( - // Reader is a global random number source - Reader *rand.Rand -) +// rand provides a simple wrap of "crypto/rand". -func init() { - src := make([]byte, 8) - if _, err := cr.Read(src); err != nil { - panic(fmt.Sprintf("initial random: %s", err.Error())) - } - seed := binary.BigEndian.Uint64(src) - Reader = rand.New(rand.NewSource(int64(seed))) +// Reader is a global random number source +var Reader io.Reader = &cryptoRandReader{} + +type cryptoRandReader struct{} + +func (c *cryptoRandReader) Read(b []byte) (int, error) { + return rand.Read(b) } -// Int wraps Rand.Int +// Int wraps Int63n func Int() int { - return Reader.Int() + val := Int63n(int64(int(^uint(0) >> 1))) + return int(val) } -// Intn wraps Rand.Intn +// Intn wraps Int63n func Intn(n int) int { - return Reader.Intn(n) + if n <= 0 { + panic("argument to Intn must be positive") + } + val := Int63n(int64(n)) + return int(val) } -// Int63n wraps Rand.Int63n +// Int63n wraps rand.Int func Int63n(n int64) int64 { - return Reader.Int63n(n) -} - -// Read wraps Rand.Read -func Read(b []byte) (int, error) { - return Reader.Read(b) + if n <= 0 { + panic("argument to Int63n must be positive") + } + val, err := rand.Int(rand.Reader, big.NewInt(n)) + if err != nil { + panic(err) + } + return val.Int64() } diff --git a/pkg/telemetry/meta.go b/pkg/telemetry/meta.go index 04228c3b7f..495f21755f 100644 --- a/pkg/telemetry/meta.go +++ b/pkg/telemetry/meta.go @@ -14,13 +14,13 @@ package telemetry import ( + "crypto/rand" "fmt" "os" "path/filepath" "github.com/google/uuid" "github.com/pingcap/errors" - "github.com/pingcap/tiup/pkg/crypto/rand" "github.com/pingcap/tiup/pkg/environment" "github.com/pingcap/tiup/pkg/localdata" "github.com/pingcap/tiup/pkg/utils"