diff --git a/cmd/mirror.go b/cmd/mirror.go index 411336156d..6b22ce47ba 100644 --- a/cmd/mirror.go +++ b/cmd/mirror.go @@ -26,7 +26,6 @@ import ( "strings" "time" - cjson "github.com/gibson042/canonicaljson-go" "github.com/pingcap/errors" "github.com/pingcap/tiup/pkg/cluster/spec" "github.com/pingcap/tiup/pkg/environment" @@ -94,32 +93,42 @@ func newMirrorSignCmd() *cobra.Command { privPath = env.Profile().Path(localdata.KeyInfoParentDir, localdata.DefaultPrivateKeyName) } - if !strings.HasPrefix(args[0], "http") { - return v1manifest.SignManifestFile(args[0], args[1:]...) - } - - client := utils.NewHTTPClient(time.Duration(timeout)*time.Second, nil) - data, err := client.Get(args[0]) + privKey, err := loadPrivKey(privPath) if err != nil { return err } - m := &v1manifest.Manifest{Signed: &v1manifest.Root{}} - if err := cjson.Unmarshal(data, m); err != nil { - return errors.Annotate(err, "unmarshal response") - } - m, err = sign(privPath, m.Signed) - if err != nil { - return err + if strings.HasPrefix(args[0], "http") { + client := utils.NewHTTPClient(time.Duration(timeout)*time.Second, nil) + data, err := client.Get(args[0]) + if err != nil { + return err + } + + if data, err = v1manifest.SignManifestData(data, privKey); err != nil { + return err + } + + if _, err = client.Post(args[0], bytes.NewBuffer(data)); err != nil { + return err + } + + return nil } - data, err = cjson.Marshal(m) + + data, err := ioutil.ReadFile(args[0]) if err != nil { - return errors.Annotate(err, "marshal manifest") + return errors.Annotatef(err, "open manifest file %s", args[0]) } - if _, err = client.Post(args[0], bytes.NewBuffer(data)); err != nil { + if data, err = v1manifest.SignManifestData(data, privKey); err != nil { return err } + + if err = ioutil.WriteFile(args[0], data, 0664); err != nil { + return errors.Annotatef(err, "write manifest file %s", args[0]) + } + return nil }, } @@ -626,7 +635,7 @@ current working directory (".") will be used.`, }, } - cmd.Flags().StringVarP(&keyDir, "", "i", "", "Path to write the private key file") + cmd.Flags().StringVarP(&keyDir, "key-dir", "k", "", "Path to write the private key file") return cmd } diff --git a/pkg/cluster/manager/deploy.go b/pkg/cluster/manager/deploy.go index a6053ea31f..14b5f20675 100644 --- a/pkg/cluster/manager/deploy.go +++ b/pkg/cluster/manager/deploy.go @@ -87,6 +87,23 @@ func (m *Manager) Deploy( return err } + instCnt := 0 + topo.IterInstance(func(inst spec.Instance) { + switch inst.ComponentName() { + // monitoring components are only useful when deployed with + // core components, we do not support deploying any bare + // monitoring system. + case spec.ComponentGrafana, + spec.ComponentPrometheus, + spec.ComponentAlertmanager: + return + } + instCnt++ + }) + if instCnt < 1 { + return fmt.Errorf("no valid instance found in the input topology, please check your config") + } + spec.ExpandRelativeDir(topo) base := topo.BaseTopo() diff --git a/pkg/repository/v1manifest/repo.go b/pkg/repository/v1manifest/repo.go index 00ee893112..38509e3a20 100644 --- a/pkg/repository/v1manifest/repo.go +++ b/pkg/repository/v1manifest/repo.go @@ -21,7 +21,6 @@ import ( stderrors "errors" "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -158,76 +157,52 @@ func GenAndSaveKeys(keys map[string][]*KeyInfo, ty string, num int, dir string) return nil } -// SignManifestFile add signatures to a manifest file -func SignManifestFile(mfile string, kfiles ...string) error { - type manifestT struct { - // Signatures value - Signatures []*Signature `json:"signatures"` - // Signed value - Signed interface{} `json:"signed"` +// SignManifestData add signatures to a manifest data +func SignManifestData(data []byte, ki *KeyInfo) ([]byte, error) { + m := RawManifest{} + + if err := json.Unmarshal(data, &m); err != nil { + return nil, errors.Annotate(err, "unmarshal manifest") } - fi, err := os.Open(mfile) - if err != nil { - return err + var signed interface{} + if err := json.Unmarshal(m.Signed, &signed); err != nil { + return nil, errors.Annotate(err, "unmarshal manifest.signed") } - defer fi.Close() - m := manifestT{} - content, err := ioutil.ReadFile(mfile) + payload, err := cjson.Marshal(signed) if err != nil { - return err + return nil, errors.Annotate(err, "marshal manifest.signed") } - if err := json.Unmarshal(content, &m); err != nil { - return err - } - payload, err := cjson.Marshal(m.Signed) + + id, err := ki.ID() if err != nil { - return err + return nil, err } -NextKey: - for _, kf := range kfiles { - f, err := os.Open(kf) - if err != nil { - return err - } - defer f.Close() - - ki := KeyInfo{} - if err := json.NewDecoder(f).Decode(&ki); err != nil { - return err - } - - id, err := ki.ID() - if err != nil { - return err - } - - sig, err := ki.Signature(payload) - if err != nil { - return err - } + sig, err := ki.Signature(payload) + if err != nil { + return nil, err + } - for _, s := range m.Signatures { - if s.KeyID == id { - s.Sig = sig - continue NextKey - } + for _, s := range m.Signatures { + if s.KeyID == id { + s.Sig = sig + return nil, errors.New("this manifest file has already been signed by specified key") } - - m.Signatures = append(m.Signatures, &Signature{ - KeyID: id, - Sig: sig, - }) } - content, err = cjson.Marshal(m) + m.Signatures = append(m.Signatures, Signature{ + KeyID: id, + Sig: sig, + }) + + content, err := cjson.Marshal(m) if err != nil { - return err + return nil, errors.Annotate(err, "marshal signed manifest") } - return ioutil.WriteFile(mfile, content, 0664) + return content, nil } // NewRoot creates a Root object