mirror of https://github.com/docker/cli.git
70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
|
package client
|
||
|
|
||
|
import (
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/docker/notary/client/changelist"
|
||
|
"github.com/docker/notary/tuf"
|
||
|
"github.com/docker/notary/tuf/data"
|
||
|
)
|
||
|
|
||
|
// Witness creates change objects to witness (i.e. re-sign) the given
|
||
|
// roles on the next publish. One change is created per role
|
||
|
func (r *NotaryRepository) Witness(roles ...string) ([]string, error) {
|
||
|
cl, err := changelist.NewFileChangelist(filepath.Join(r.tufRepoPath, "changelist"))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer cl.Close()
|
||
|
|
||
|
successful := make([]string, 0, len(roles))
|
||
|
for _, role := range roles {
|
||
|
// scope is role
|
||
|
c := changelist.NewTUFChange(
|
||
|
changelist.ActionUpdate,
|
||
|
role,
|
||
|
changelist.TypeWitness,
|
||
|
"",
|
||
|
nil,
|
||
|
)
|
||
|
err = cl.Add(c)
|
||
|
if err != nil {
|
||
|
break
|
||
|
}
|
||
|
successful = append(successful, role)
|
||
|
}
|
||
|
return successful, err
|
||
|
}
|
||
|
|
||
|
func witnessTargets(repo *tuf.Repo, invalid *tuf.Repo, role string) error {
|
||
|
if r, ok := repo.Targets[role]; ok {
|
||
|
// role is already valid, mark for re-signing/updating
|
||
|
r.Dirty = true
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if roleObj, err := repo.GetDelegationRole(role); err == nil && invalid != nil {
|
||
|
// A role with a threshold > len(keys) is technically invalid, but we let it build in the builder because
|
||
|
// we want to be able to download the role (which may still have targets on it), add more keys, and then
|
||
|
// witness the role, thus bringing it back to valid. However, if no keys have been added before witnessing,
|
||
|
// then it is still an invalid role, and can't be witnessed because nothing can bring it back to valid.
|
||
|
if roleObj.Threshold > len(roleObj.Keys) {
|
||
|
return data.ErrInvalidRole{
|
||
|
Role: role,
|
||
|
Reason: "role does not specify enough valid signing keys to meet its required threshold",
|
||
|
}
|
||
|
}
|
||
|
if r, ok := invalid.Targets[role]; ok {
|
||
|
// role is recognized but invalid, move to valid data and mark for re-signing
|
||
|
repo.Targets[role] = r
|
||
|
r.Dirty = true
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
// role isn't recognized, even as invalid
|
||
|
return data.ErrInvalidRole{
|
||
|
Role: role,
|
||
|
Reason: "this role is not known",
|
||
|
}
|
||
|
}
|