diff --git a/pkg/repository/model/model.go b/pkg/repository/model/model.go index af0cb1e93d..165767956e 100644 --- a/pkg/repository/model/model.go +++ b/pkg/repository/model/model.go @@ -353,9 +353,23 @@ func (m *model) readSnapshotManifest() (*v1manifest.Manifest, error) { return m.txn.ReadManifest(v1manifest.ManifestFilenameSnapshot, &v1manifest.Snapshot{}) } -// readRootManifest returns root.json +// readRootManifest returns newest root.json func (m *model) readRootManifest() (*v1manifest.Manifest, error) { - return m.txn.ReadManifest(v1manifest.ManifestFilenameRoot, &v1manifest.Root{}) + root, err := m.txn.ReadManifest(v1manifest.ManifestFilenameRoot, &v1manifest.Root{}) + if err != nil { + return root, err + } + + for { + last, err := m.txn.ReadManifest( + fmt.Sprintf("%d.%s", root.Signed.(*v1manifest.Root).Version+1, v1manifest.ManifestFilenameRoot), + &v1manifest.Root{}, + ) + if err != nil { + return root, nil + } + root = last + } } func (m *model) updateTimestampManifest(initTime time.Time) error { @@ -477,7 +491,11 @@ func verifyRootManifest(oldM *v1manifest.Manifest, newM *v1manifest.Manifest) er } if len(oldKeys.Intersection(newKeys).Slice()) < int(oldRoot.Roles[v1manifest.ManifestTypeRoot].Threshold) { - return ErrorWrongSignature + return errors.Annotatef(ErrorWrongSignature, + "need %d valid signatures, only got %d", + oldRoot.Roles[v1manifest.ManifestTypeRoot].Threshold, + len(oldKeys.Intersection(newKeys).Slice()), + ) } if newRoot.Version != oldRoot.Version+1 { diff --git a/pkg/repository/store/txn.go b/pkg/repository/store/txn.go index d714c32fa3..8a0d84d22e 100644 --- a/pkg/repository/store/txn.go +++ b/pkg/repository/store/txn.go @@ -25,7 +25,6 @@ import ( cjson "github.com/gibson042/canonicaljson-go" "github.com/pingcap/errors" "github.com/pingcap/tiup/pkg/localdata" - "github.com/pingcap/tiup/pkg/logger/log" "github.com/pingcap/tiup/pkg/repository/v1manifest" "github.com/pingcap/tiup/pkg/utils" ) @@ -169,8 +168,7 @@ func (t *localTxn) ReadManifest(filename string, role v1manifest.ValidManifest) } wc = resp.Body default: - log.Errorf("Error on read manifest: %s, upstream: %s", err.Error(), t.store.upstream) - return nil, errors.Annotate(err, "open file") + return nil, errors.Annotatef(err, "error on read manifest: %s, upstream %s", err.Error(), t.store.upstream) } defer wc.Close() diff --git a/server/rotate/rotate_server.go b/server/rotate/rotate_server.go index ec605a04b6..08adba0094 100644 --- a/server/rotate/rotate_server.go +++ b/server/rotate/rotate_server.go @@ -18,9 +18,9 @@ type statusRender struct { bars map[string]*progress.MultiBarItem } -func newStatusRender(manifest *v1manifest.Manifest) *statusRender { +func newStatusRender(manifest *v1manifest.Manifest, addr string) *statusRender { status := &statusRender{ - mbar: progress.NewMultiBar("Waiting all administrators to sign"), + mbar: progress.NewMultiBar(fmt.Sprintf("Waiting all administrators to sign %s", addr)), bars: make(map[string]*progress.MultiBarItem), } root := manifest.Signed.(*v1manifest.Root) @@ -67,14 +67,18 @@ func Serve(addr string, root *v1manifest.Root) (*v1manifest.Manifest, error) { srv := &http.Server{Addr: addr, Handler: r} go func() { - if err = srv.ListenAndServe(); err != http.ErrServerClosed { - close(sigCh) + err = srv.ListenAndServe() + if err == http.ErrServerClosed { + err = nil } + close(sigCh) }() manifest := &v1manifest.Manifest{Signed: root} - status := newStatusRender(manifest) + status := newStatusRender(manifest, fmt.Sprintf("%s/rotate/root.json", addr)) defer status.stop() + +SIGLOOP: for sig := range sigCh { k := root.Roles[v1manifest.ManifestTypeRoot].Keys[sig.KeyID] if k == nil { @@ -88,7 +92,7 @@ func Serve(addr string, root *v1manifest.Root) (*v1manifest.Manifest, error) { for _, s := range manifest.Signatures { if s.KeyID == sig.KeyID { // Duplicate signature - continue + continue SIGLOOP } } manifest.Signatures = append(manifest.Signatures, sig)