diff --git a/commands.go b/commands.go index 1d782bf96c..4e512d8dda 100644 --- a/commands.go +++ b/commands.go @@ -389,7 +389,7 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri // Optionally register the image at REPO/TAG if repository := cmd.Arg(1); repository != "" { tag := cmd.Arg(2) // Repository will handle an empty tag properly - if err := srv.runtime.repositories.Set(repository, tag, img.Id); err != nil { + if err := srv.runtime.repositories.Set(repository, tag, img.Id, true); err != nil { return err } } @@ -760,6 +760,19 @@ func (p *ports) Set(value string) error { return nil } +func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string) error { + cmd := rcli.Subcmd(stdout, "tag", "[OPTIONS] IMAGE REPOSITORY [TAG]", "Tag an image into a repository") + force := cmd.Bool("f", false, "Force") + if err := cmd.Parse(args); err != nil { + return nil + } + if cmd.NArg() < 2 { + cmd.Usage() + return nil + } + return srv.runtime.repositories.Set(cmd.Arg(1), cmd.Arg(2), cmd.Arg(0), *force) +} + func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error { cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container") fl_user := cmd.String("u", "", "Username or UID") diff --git a/registry.go b/registry.go index da1186ee54..96c32ea2ef 100644 --- a/registry.go +++ b/registry.go @@ -175,7 +175,7 @@ func (graph *Graph) PullRepository(user, repoName, askedTag string, repositories if err = graph.PullImage(rev, authConfig); err != nil { return err } - if err = repositories.Set(repoName, tag, rev); err != nil { + if err = repositories.Set(repoName, tag, rev, true); err != nil { return err } } diff --git a/runtime.go b/runtime.go index bb59c7787a..21e1466f51 100644 --- a/runtime.go +++ b/runtime.go @@ -201,7 +201,7 @@ func (runtime *Runtime) Commit(id, repository, tag string) (*Image, error) { } // Register the image if needed if repository != "" { - if err := runtime.repositories.Set(repository, tag, img.Id); err != nil { + if err := runtime.repositories.Set(repository, tag, img.Id, true); err != nil { return img, err } } diff --git a/tags.go b/tags.go index ae8c1030cd..9f0a215b46 100644 --- a/tags.go +++ b/tags.go @@ -83,7 +83,11 @@ func (store *TagStore) LookupImage(name string) (*Image, error) { return img, nil } -func (store *TagStore) Set(repoName, tag, revision string) error { +func (store *TagStore) Set(repoName, tag, imageName string, force bool) error { + img, err := store.LookupImage(imageName) + if err != nil { + return err + } if tag == "" { tag = DEFAULT_TAG } @@ -101,9 +105,12 @@ func (store *TagStore) Set(repoName, tag, revision string) error { repo = r } else { repo = make(map[string]string) + if old, exists := store.Repositories[repoName]; exists && !force { + return fmt.Errorf("Tag %s:%s is already set to %s", repoName, tag, old) + } store.Repositories[repoName] = repo } - repo[tag] = revision + repo[tag] = img.Id return store.Save() }