// generateSnapshot generates a new snapshot from the previous one in the store - this assumes all // the other roles except timestamp have already been set on the repo, and will set the generated // snapshot on the repo as well func generateSnapshot(gun string, builder tuf.RepoBuilder, store storage.MetaStore) (*storage.MetaUpdate, error) { var prev *data.SignedSnapshot _, currentJSON, err := store.GetCurrent(gun, data.CanonicalSnapshotRole) if err == nil { prev = new(data.SignedSnapshot) if err = json.Unmarshal(currentJSON, prev); err != nil { logrus.Error("Failed to unmarshal existing snapshot for GUN ", gun) return nil, err } } if _, ok := err.(storage.ErrNotFound); !ok && err != nil { return nil, err } meta, ver, err := builder.GenerateSnapshot(prev) switch err.(type) { case nil: return &storage.MetaUpdate{ Role: data.CanonicalSnapshotRole, Version: ver, Data: meta, }, nil case signed.ErrInsufficientSignatures, signed.ErrNoKeys, signed.ErrRoleThreshold: // If we cannot sign the snapshot, then we don't have keys for the snapshot, // and the client should have submitted a snapshot return nil, validation.ErrBadHierarchy{ Missing: data.CanonicalSnapshotRole, Msg: "no snapshot was included in update and server does not hold current snapshot key for repository"} default: return nil, validation.ErrValidation{Msg: err.Error()} } }