diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index a7a08dc..f6a5ee8 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -16,6 +16,7 @@ import ( gocontext "golang.org/x/net/context" "google.golang.org/grpc" + "github.com/Sirupsen/logrus" "github.com/docker/containerd" api "github.com/docker/containerd/api/execution" "github.com/docker/containerd/events" @@ -23,7 +24,6 @@ import ( "github.com/docker/containerd/execution/executors/shim" "github.com/docker/containerd/log" metrics "github.com/docker/go-metrics" - "github.com/Sirupsen/logrus" "github.com/urfave/cli" "github.com/nats-io/go-nats" diff --git a/cmd/ctr/main.go b/cmd/ctr/main.go index 7664ab9..04004bc 100644 --- a/cmd/ctr/main.go +++ b/cmd/ctr/main.go @@ -4,8 +4,8 @@ import ( "fmt" "os" - "github.com/docker/containerd" "github.com/Sirupsen/logrus" + "github.com/docker/containerd" "github.com/urfave/cli" ) diff --git a/events/poster.go b/events/poster.go index 1ff5e55..2628012 100644 --- a/events/poster.go +++ b/events/poster.go @@ -3,8 +3,8 @@ package events import ( "context" - "github.com/docker/containerd/log" "github.com/Sirupsen/logrus" + "github.com/docker/containerd/log" ) var ( diff --git a/execution/executors/shim/process.go b/execution/executors/shim/process.go index c3c82c3..33f40d7 100644 --- a/execution/executors/shim/process.go +++ b/execution/executors/shim/process.go @@ -11,10 +11,10 @@ import ( "sync" "syscall" + "github.com/Sirupsen/logrus" "github.com/docker/containerd/execution" "github.com/docker/containerd/log" "github.com/pkg/errors" - "github.com/Sirupsen/logrus" "golang.org/x/sys/unix" runc "github.com/crosbymichael/go-runc" diff --git a/execution/executors/shim/shim.go b/execution/executors/shim/shim.go index c33376a..e610ebb 100644 --- a/execution/executors/shim/shim.go +++ b/execution/executors/shim/shim.go @@ -11,11 +11,11 @@ import ( "sync" "syscall" + "github.com/Sirupsen/logrus" "github.com/docker/containerd/execution" "github.com/docker/containerd/log" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/Sirupsen/logrus" ) const ( diff --git a/rootfs/apply.go b/rootfs/apply.go index 2ea427b..8d08a2e 100644 --- a/rootfs/apply.go +++ b/rootfs/apply.go @@ -8,6 +8,7 @@ import ( "github.com/docker/containerd/log" "github.com/docker/docker/pkg/archive" "github.com/opencontainers/go-digest" + "github.com/opencontainers/image-spec/identity" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -32,14 +33,14 @@ type Mounter interface { // The returned digest is the diffID for the applied layer. func ApplyLayer(snapshots Snapshotter, mounter Mounter, rd io.Reader, parent digest.Digest) (digest.Digest, error) { digester := digest.Canonical.Digester() // used to calculate diffID. - rd = io.TeeReader(rd, digester) + rd = io.TeeReader(rd, digester.Hash()) // create a temporary directory to work from, needs to be on same // filesystem. Probably better if this shared but we'll use a tempdir, for // now. dir, err := ioutil.TempDir("", "unpack-") if err != nil { - return errors.Wrapf(err, "creating temporary directory failed") + return "", errors.Wrapf(err, "creating temporary directory failed") } // TODO(stevvooe): Choose this key WAY more carefully. We should be able to @@ -61,11 +62,11 @@ func ApplyLayer(snapshots Snapshotter, mounter Mounter, rd io.Reader, parent dig } defer mounter.Unmount(mounts...) - if err := archive.ApplyLayer(key, rd); err != nil { + if _, err := archive.ApplyLayer(key, rd); err != nil { return "", err } - diffID := digest.Digest() + diffID := digester.Digest() chainID := diffID if parent != "" { @@ -81,13 +82,13 @@ func ApplyLayer(snapshots Snapshotter, mounter Mounter, rd io.Reader, parent dig // // If successful, the chainID for the top-level layer is returned. That // identifier can be used to check out a snapshot. -func Prepare(snapshots Snaphotter, mounter Mounter, layers []ocispec.Descriptor, +func Prepare(snapshots Snapshotter, mounter Mounter, layers []ocispec.Descriptor, // TODO(stevvooe): The following functions are candidate for internal // object functions. We can use these to formulate the beginnings of a // rootfs Controller. // // Just pass them in for now. - openBlob func(digest.Digest) (digest.Digest, error), + openBlob func(digest.Digest) (io.ReadCloser, error), resolveDiffID func(digest.Digest) digest.Digest, registerDiffID func(diffID, dgst digest.Digest) error) (digest.Digest, error) { var ( @@ -96,11 +97,14 @@ func Prepare(snapshots Snaphotter, mounter Mounter, layers []ocispec.Descriptor, ) for _, layer := range layers { + // TODO: layer.Digest should not be string + // (https://github.com/opencontainers/image-spec/pull/514) + layerDigest := digest.Digest(layer.Digest) // This will convert a possibly compressed layer hash to the // uncompressed hash, if we know about it. If we don't, we unpack and // calculate it. If we do have it, we then calculate the chain id for // the application and see if the snapshot is there. - diffID := resolveDiffID(layer.Digest) + diffID := resolveDiffID(layerDigest) if diffID != "" { chainLocal := append(chain, diffID) chainID := identity.ChainID(chainLocal) @@ -110,7 +114,7 @@ func Prepare(snapshots Snaphotter, mounter Mounter, layers []ocispec.Descriptor, } } - rc, err := openBlob(layer.Digest) + rc, err := openBlob(layerDigest) if err != nil { return "", err } @@ -125,8 +129,8 @@ func Prepare(snapshots Snaphotter, mounter Mounter, layers []ocispec.Descriptor, // For uncompressed layers, this will be the same. For compressed // layers, we can look up the diffID from the digest if we've already // unpacked it. - if err := registerDiffID(diffID, layer.Digest); err != nil { - return nil, err + if err := registerDiffID(diffID, layerDigest); err != nil { + return "", err } chain = append(chain, diffID) diff --git a/vendor/github.com/opencontainers/image-spec/identity/chainid.go b/vendor/github.com/opencontainers/image-spec/identity/chainid.go new file mode 100644 index 0000000..0bb2853 --- /dev/null +++ b/vendor/github.com/opencontainers/image-spec/identity/chainid.go @@ -0,0 +1,67 @@ +// Copyright 2016 The Linux Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package identity provides implementations of subtle calculations pertaining +// to image and layer identity. The primary item present here is the ChainID +// calculation used in identifying the result of subsequent layer applications. +// +// Helpers are also provided here to ease transition to the +// github.com/opencontainers/go-digest package, but that package may be used +// directly. +package identity + +import "github.com/opencontainers/go-digest" + +// ChainID takes a slice of digests and returns the ChainID corresponding to +// the last entry. Typically, these are a list of layer DiffIDs, with the +// result providing the ChainID identifying the result of sequential +// application of the preceding layers. +func ChainID(dgsts []digest.Digest) digest.Digest { + chainIDs := make([]digest.Digest, len(dgsts)) + copy(chainIDs, dgsts) + ChainIDs(chainIDs) + + if len(chainIDs) == 0 { + return "" + } + return chainIDs[len(chainIDs)-1] +} + +// ChainIDs calculates the recursively applied chain id for each identifier in +// the slice. The result is written direcly back into the slice such that the +// ChainID for each item will be in the respective position. +// +// By definition of ChainID, the zeroth element will always be the same before +// and after the call. +// +// As an example, given the chain of ids `[A, B, C]`, the result `[A, +// ChainID(A|B), ChainID(A|B|C)]` will be written back to the slice. +// +// The input is provided as a return value for convenience. +// +// Typically, these are a list of layer DiffIDs, with the +// result providing the ChainID for each the result of each layer application +// sequentially. +func ChainIDs(dgsts []digest.Digest) []digest.Digest { + if len(dgsts) < 2 { + return dgsts + } + + parent := digest.FromBytes([]byte(dgsts[0] + " " + dgsts[1])) + next := dgsts[1:] + next[0] = parent + ChainIDs(next) + + return dgsts +} diff --git a/vendor/github.com/opencontainers/image-spec/identity/helpers.go b/vendor/github.com/opencontainers/image-spec/identity/helpers.go new file mode 100644 index 0000000..9d96eaa --- /dev/null +++ b/vendor/github.com/opencontainers/image-spec/identity/helpers.go @@ -0,0 +1,40 @@ +// Copyright 2016 The Linux Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package identity + +import ( + _ "crypto/sha256" // side-effect to install impls, sha256 + _ "crypto/sha512" // side-effect to install impls, sha384/sh512 + + "io" + + digest "github.com/opencontainers/go-digest" +) + +// FromReader consumes the content of rd until io.EOF, returning canonical +// digest. +func FromReader(rd io.Reader) (digest.Digest, error) { + return digest.Canonical.FromReader(rd) +} + +// FromBytes digests the input and returns a Digest. +func FromBytes(p []byte) digest.Digest { + return digest.Canonical.FromBytes(p) +} + +// FromString digests the input and returns a Digest. +func FromString(s string) digest.Digest { + return digest.Canonical.FromString(s) +}