github.com/jwhonce/docker@v0.6.7-0.20190327063223-da823cf3a5a3/api/server/backend/build/tag.go (about) 1 package build // import "github.com/docker/docker/api/server/backend/build" 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/docker/distribution/reference" 8 "github.com/docker/docker/image" 9 "github.com/pkg/errors" 10 ) 11 12 // Tagger is responsible for tagging an image created by a builder 13 type Tagger struct { 14 imageComponent ImageComponent 15 stdout io.Writer 16 repoAndTags []reference.Named 17 } 18 19 // NewTagger returns a new Tagger for tagging the images of a build. 20 // If any of the names are invalid tags an error is returned. 21 func NewTagger(backend ImageComponent, stdout io.Writer, names []string) (*Tagger, error) { 22 reposAndTags, err := sanitizeRepoAndTags(names) 23 if err != nil { 24 return nil, err 25 } 26 return &Tagger{ 27 imageComponent: backend, 28 stdout: stdout, 29 repoAndTags: reposAndTags, 30 }, nil 31 } 32 33 // TagImages creates image tags for the imageID 34 func (bt *Tagger) TagImages(imageID image.ID) error { 35 for _, rt := range bt.repoAndTags { 36 if err := bt.imageComponent.TagImageWithReference(imageID, rt); err != nil { 37 return err 38 } 39 fmt.Fprintf(bt.stdout, "Successfully tagged %s\n", reference.FamiliarString(rt)) 40 } 41 return nil 42 } 43 44 // sanitizeRepoAndTags parses the raw "t" parameter received from the client 45 // to a slice of repoAndTag. 46 // It also validates each repoName and tag. 47 func sanitizeRepoAndTags(names []string) ([]reference.Named, error) { 48 var ( 49 repoAndTags []reference.Named 50 // This map is used for deduplicating the "-t" parameter. 51 uniqNames = make(map[string]struct{}) 52 ) 53 for _, repo := range names { 54 if repo == "" { 55 continue 56 } 57 58 ref, err := reference.ParseNormalizedNamed(repo) 59 if err != nil { 60 return nil, err 61 } 62 63 if _, isCanonical := ref.(reference.Canonical); isCanonical { 64 return nil, errors.New("build tag cannot contain a digest") 65 } 66 67 ref = reference.TagNameOnly(ref) 68 69 nameWithTag := ref.String() 70 71 if _, exists := uniqNames[nameWithTag]; !exists { 72 uniqNames[nameWithTag] = struct{}{} 73 repoAndTags = append(repoAndTags, ref) 74 } 75 } 76 return repoAndTags, nil 77 }