Skip to content

Commit

Permalink
Update daemon and docker core to use new content addressable storage
Browse files Browse the repository at this point in the history
Add distribution package for managing pulls and pushes. This is based on
the old code in the graph package, with major changes to work with the
new image/layer model.

Add v1 migration code.

Update registry, api/*, and daemon packages to use the reference
package's types where applicable.

Update daemon package to use image/layer/tag stores instead of the graph
package

Signed-off-by: Aaron Lehmann <[email protected]>
Signed-off-by: Tonis Tiigi <[email protected]>
  • Loading branch information
tonistiigi authored and aaronlehmann committed Nov 24, 2015
1 parent 5fc0e1f commit 4352da7
Show file tree
Hide file tree
Showing 70 changed files with 2,026 additions and 1,271 deletions.
55 changes: 31 additions & 24 deletions api/client/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ import (
"strconv"
"strings"

"github.com/docker/distribution/reference"
"github.com/docker/docker/api"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/graph/tags"
"github.com/docker/docker/opts"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/httputils"
"github.com/docker/docker/pkg/jsonmessage"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/ulimit"
"github.com/docker/docker/pkg/units"
"github.com/docker/docker/pkg/urlutil"
"github.com/docker/docker/registry"
"github.com/docker/docker/runconfig"
tagpkg "github.com/docker/docker/tag"
"github.com/docker/docker/utils"
)

Expand Down Expand Up @@ -323,7 +323,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
// Since the build was successful, now we must tag any of the resolved
// images from the above Dockerfile rewrite.
for _, resolved := range resolvedTags {
if err := cli.tagTrusted(resolved.repoInfo, resolved.digestRef, resolved.tagRef); err != nil {
if err := cli.tagTrusted(resolved.digestRef, resolved.tagRef); err != nil {
return err
}
}
Expand All @@ -333,16 +333,12 @@ func (cli *DockerCli) CmdBuild(args ...string) error {

// validateTag checks if the given image name can be resolved.
func validateTag(rawRepo string) (string, error) {
repository, tag := parsers.ParseRepositoryTag(rawRepo)
if err := registry.ValidateRepositoryName(repository); err != nil {
ref, err := reference.ParseNamed(rawRepo)
if err != nil {
return "", err
}

if len(tag) == 0 {
return rawRepo, nil
}

if err := tags.ValidateTagName(tag); err != nil {
if err := registry.ValidateRepositoryName(ref); err != nil {
return "", err
}

Expand Down Expand Up @@ -565,15 +561,16 @@ func (td *trustedDockerfile) Close() error {
// resolvedTag records the repository, tag, and resolved digest reference
// from a Dockerfile rewrite.
type resolvedTag struct {
repoInfo *registry.RepositoryInfo
digestRef, tagRef registry.Reference
repoInfo *registry.RepositoryInfo
digestRef reference.Canonical
tagRef reference.NamedTagged
}

// rewriteDockerfileFrom rewrites the given Dockerfile by resolving images in
// "FROM <image>" instructions to a digest reference. `translator` is a
// function that takes a repository name and tag reference and returns a
// trusted digest reference.
func rewriteDockerfileFrom(dockerfileName string, translator func(string, registry.Reference) (registry.Reference, error)) (newDockerfile *trustedDockerfile, resolvedTags []*resolvedTag, err error) {
func rewriteDockerfileFrom(dockerfileName string, translator func(reference.NamedTagged) (reference.Canonical, error)) (newDockerfile *trustedDockerfile, resolvedTags []*resolvedTag, err error) {
dockerfile, err := os.Open(dockerfileName)
if err != nil {
return nil, nil, fmt.Errorf("unable to open Dockerfile: %v", err)
Expand Down Expand Up @@ -607,29 +604,39 @@ func rewriteDockerfileFrom(dockerfileName string, translator func(string, regist
matches := dockerfileFromLinePattern.FindStringSubmatch(line)
if matches != nil && matches[1] != "scratch" {
// Replace the line with a resolved "FROM repo@digest"
repo, tag := parsers.ParseRepositoryTag(matches[1])
if tag == "" {
tag = tags.DefaultTag
ref, err := reference.ParseNamed(matches[1])
if err != nil {
return nil, nil, err
}

repoInfo, err := registry.ParseRepositoryInfo(repo)
if err != nil {
return nil, nil, fmt.Errorf("unable to parse repository info %q: %v", repo, err)
digested := false
switch ref.(type) {
case reference.Tagged:
case reference.Digested:
digested = true
default:
ref, err = reference.WithTag(ref, tagpkg.DefaultTag)
if err != nil {
return nil, nil, err
}
}

ref := registry.ParseReference(tag)
repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil {
return nil, nil, fmt.Errorf("unable to parse repository info %q: %v", ref.String(), err)
}

if !ref.HasDigest() && isTrusted() {
trustedRef, err := translator(repo, ref)
if !digested && isTrusted() {
trustedRef, err := translator(ref.(reference.NamedTagged))
if err != nil {
return nil, nil, err
}

line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, fmt.Sprintf("FROM %s", trustedRef.ImageName(repo)))
line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, fmt.Sprintf("FROM %s", trustedRef.String()))
resolvedTags = append(resolvedTags, &resolvedTag{
repoInfo: repoInfo,
digestRef: trustedRef,
tagRef: ref,
tagRef: ref.(reference.NamedTagged),
})
}
}
Expand Down
28 changes: 22 additions & 6 deletions api/client/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package client

import (
"encoding/json"
"errors"
"fmt"
"net/url"

"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/registry"
"github.com/docker/docker/runconfig"
)
Expand All @@ -32,20 +33,35 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
cmd.ParseFlags(args, true)

var (
name = cmd.Arg(0)
repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
name = cmd.Arg(0)
repositoryAndTag = cmd.Arg(1)
repositoryName string
tag string
)

//Check if the given image name can be resolved
if repository != "" {
if err := registry.ValidateRepositoryName(repository); err != nil {
if repositoryAndTag != "" {
ref, err := reference.ParseNamed(repositoryAndTag)
if err != nil {
return err
}
if err := registry.ValidateRepositoryName(ref); err != nil {
return err
}

repositoryName = ref.Name()

switch x := ref.(type) {
case reference.Digested:
return errors.New("cannot commit to digest reference")
case reference.Tagged:
tag = x.Tag()
}
}

v := url.Values{}
v.Set("container", name)
v.Set("repo", repository)
v.Set("repo", repositoryName)
v.Set("tag", tag)
v.Set("comment", *flComment)
v.Set("author", *flAuthor)
Expand Down
65 changes: 42 additions & 23 deletions api/client/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import (
"os"
"strings"

"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/graph/tags"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/registry"
"github.com/docker/docker/runconfig"
tagpkg "github.com/docker/docker/tag"
)

func (cli *DockerCli) pullImage(image string) error {
Expand All @@ -23,16 +23,28 @@ func (cli *DockerCli) pullImage(image string) error {

func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error {
v := url.Values{}
repos, tag := parsers.ParseRepositoryTag(image)
// pull only the image tagged 'latest' if no tag was specified
if tag == "" {
tag = tags.DefaultTag

ref, err := reference.ParseNamed(image)
if err != nil {
return err
}

var tag string
switch x := ref.(type) {
case reference.Digested:
tag = x.Digest().String()
case reference.Tagged:
tag = x.Tag()
default:
// pull only the image tagged 'latest' if no tag was specified
tag = tagpkg.DefaultTag
}
v.Set("fromImage", repos)

v.Set("fromImage", ref.Name())
v.Set("tag", tag)

// Resolve the Repository name from fqn to RepositoryInfo
repoInfo, err := registry.ParseRepositoryInfo(repos)
repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil {
return err
}
Expand Down Expand Up @@ -94,39 +106,46 @@ func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runc
defer containerIDFile.Close()
}

repo, tag := parsers.ParseRepositoryTag(config.Image)
if tag == "" {
tag = tags.DefaultTag
ref, err := reference.ParseNamed(config.Image)
if err != nil {
return nil, err
}

ref := registry.ParseReference(tag)
var trustedRef registry.Reference
isDigested := false
switch ref.(type) {
case reference.Tagged:
case reference.Digested:
isDigested = true
default:
ref, err = reference.WithTag(ref, tagpkg.DefaultTag)
if err != nil {
return nil, err
}
}

if isTrusted() && !ref.HasDigest() {
var trustedRef reference.Canonical

if isTrusted() && !isDigested {
var err error
trustedRef, err = cli.trustedReference(repo, ref)
trustedRef, err = cli.trustedReference(ref.(reference.NamedTagged))
if err != nil {
return nil, err
}
config.Image = trustedRef.ImageName(repo)
config.Image = trustedRef.String()
}

//create the container
serverResp, err := cli.call("POST", "/containers/create?"+containerValues.Encode(), mergedConfig, nil)
//if image not found try to pull it
if serverResp.statusCode == 404 && strings.Contains(err.Error(), config.Image) {
fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", ref.ImageName(repo))
fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", ref.String())

// we don't want to write to stdout anything apart from container.ID
if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil {
return nil, err
}
if trustedRef != nil && !ref.HasDigest() {
repoInfo, err := registry.ParseRepositoryInfo(repo)
if err != nil {
return nil, err
}
if err := cli.tagTrusted(repoInfo, trustedRef, ref); err != nil {
if trustedRef != nil && !isDigested {
if err := cli.tagTrusted(trustedRef, ref.(reference.NamedTagged)); err != nil {
return nil, err
}
}
Expand Down
34 changes: 22 additions & 12 deletions api/client/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import (
"encoding/json"
"fmt"
"net/url"
"strings"
"text/tabwriter"
"time"

"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/units"
"github.com/docker/docker/utils"
)

// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
Expand Down Expand Up @@ -78,9 +78,9 @@ func (cli *DockerCli) CmdImages(args ...string) error {
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
if !*quiet {
if *showDigests {
fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tSIZE")
} else {
fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tSIZE")
}
}

Expand All @@ -101,21 +101,31 @@ func (cli *DockerCli) CmdImages(args ...string) error {
// combine the tags and digests lists
tagsAndDigests := append(repoTags, repoDigests...)
for _, repoAndRef := range tagsAndDigests {
repo, ref := parsers.ParseRepositoryTag(repoAndRef)
// default tag and digest to none - if there's a value, it'll be set below
// default repo, tag, and digest to none - if there's a value, it'll be set below
repo := "<none>"
tag := "<none>"
digest := "<none>"
if utils.DigestReference(ref) {
digest = ref
} else {
tag = ref

if !strings.HasPrefix(repoAndRef, "<none>") {
ref, err := reference.ParseNamed(repoAndRef)
if err != nil {
return err
}
repo = ref.Name()

switch x := ref.(type) {
case reference.Digested:
digest = x.Digest().String()
case reference.Tagged:
tag = x.Tag()
}
}

if !*quiet {
if *showDigests {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize)))
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.Size)))
} else {
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize)))
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.Size)))
}
} else {
fmt.Fprintln(w, ID)
Expand Down
9 changes: 6 additions & 3 deletions api/client/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
"net/url"
"os"

"github.com/docker/distribution/reference"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/urlutil"
"github.com/docker/docker/registry"
)
Expand Down Expand Up @@ -47,8 +47,11 @@ func (cli *DockerCli) CmdImport(args ...string) error {

if repository != "" {
//Check if the given image name can be resolved
repo, _ := parsers.ParseRepositoryTag(repository)
if err := registry.ValidateRepositoryName(repo); err != nil {
ref, err := reference.ParseNamed(repository)
if err != nil {
return err
}
if err := registry.ValidateRepositoryName(ref); err != nil {
return err
}
}
Expand Down
Loading

0 comments on commit 4352da7

Please sign in to comment.