Merge pull request #280 from tonistiigi/update-containerd

vendor: update containerd to v1.0.2
docker-18.09
Akihiro Suda 2018-02-14 11:34:55 +09:00 committed by GitHub
commit 794d61c1e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 781 additions and 643 deletions

View File

@ -211,7 +211,7 @@ export JAEGER_TRACE=0.0.0.0:6831
### Supported runc version
During development, BuildKit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/v1.0.2-rc.0/RUNC.md) for more information.
During development, BuildKit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/v1.0.2/RUNC.md) for more information.
### Contributing

View File

@ -25,7 +25,7 @@ type DiffPair struct {
Blobsum digest.Digest
}
func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter snapshot.Snapshotter, differ diff.Differ, ref cache.ImmutableRef) ([]DiffPair, error) {
func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter snapshot.Snapshotter, differ diff.Comparer, ref cache.ImmutableRef) ([]DiffPair, error) {
if ref == nil {
return nil, nil
}
@ -68,7 +68,7 @@ func GetDiffPairs(ctx context.Context, contentStore content.Store, snapshotter s
if err != nil {
return nil, err
}
descr, err := differ.DiffMounts(ctx, lower, upper,
descr, err := differ.Compare(ctx, lower, upper,
diff.WithMediaType(ocispec.MediaTypeImageLayerGzip),
diff.WithReference(ref.ID()),
diff.WithLabels(map[string]string{

View File

@ -33,7 +33,7 @@ type CacheRecord struct {
type ExporterOpt struct {
Snapshotter snapshot.Snapshotter
ContentStore content.Store
Differ diff.Differ
Differ diff.Comparer
SessionManager *session.Manager
}

View File

@ -33,7 +33,7 @@ type ImportOpt struct {
SessionManager *session.Manager
ContentStore content.Store
Snapshotter snapshot.Snapshotter
Applier diff.Differ
Applier diff.Applier
CacheAccessor cache.Accessor
}

View File

@ -11,7 +11,7 @@ import (
"sync"
"github.com/BurntSushi/locker"
"github.com/containerd/containerd/fs"
"github.com/containerd/continuity/fs"
iradix "github.com/hashicorp/go-immutable-radix"
"github.com/hashicorp/golang-lru/simplelru"
"github.com/moby/buildkit/cache"

2
cache/fsutil.go vendored
View File

@ -4,7 +4,7 @@ import (
"context"
"io/ioutil"
"github.com/containerd/containerd/fs"
"github.com/containerd/continuity/fs"
"github.com/moby/buildkit/snapshot"
)

View File

@ -40,6 +40,8 @@ func TestClientIntegration(t *testing.T) {
testResolveAndHosts,
testUser,
testOCIExporter,
testWhiteoutParentDir,
testDuplicateWhiteouts,
})
}
@ -552,6 +554,138 @@ func testBuildPushAndValidate(t *testing.T, sb integration.Sandbox) {
require.False(t, ok)
}
// containerd/containerd#2119
func testDuplicateWhiteouts(t *testing.T, sb integration.Sandbox) {
requiresLinux(t)
t.Parallel()
c, err := New(sb.Address())
require.NoError(t, err)
defer c.Close()
busybox := llb.Image("busybox:latest")
st := llb.Scratch()
run := func(cmd string) {
st = busybox.Run(llb.Shlex(cmd), llb.Dir("/wd")).AddMount("/wd", st)
}
run(`sh -c "mkdir -p d0 d1; echo -n first > d1/bar;"`)
run(`sh -c "rm -rf d0 d1"`)
def, err := st.Marshal()
require.NoError(t, err)
destDir, err := ioutil.TempDir("", "buildkit")
require.NoError(t, err)
defer os.RemoveAll(destDir)
out := filepath.Join(destDir, "out.tar")
err = c.Solve(context.TODO(), def, SolveOpt{
Exporter: ExporterOCI,
ExporterAttrs: map[string]string{
"output": out,
},
}, nil)
require.NoError(t, err)
dt, err := ioutil.ReadFile(out)
require.NoError(t, err)
m, err := readTarToMap(dt, false)
require.NoError(t, err)
var index ocispec.Index
err = json.Unmarshal(m["index.json"].data, &index)
require.NoError(t, err)
var mfst ocispec.Manifest
err = json.Unmarshal(m["blobs/sha256/"+index.Manifests[0].Digest.Hex()].data, &mfst)
require.NoError(t, err)
lastLayer := mfst.Layers[len(mfst.Layers)-1]
layer, ok := m["blobs/sha256/"+lastLayer.Digest.Hex()]
require.True(t, ok)
m, err = readTarToMap(layer.data, true)
require.NoError(t, err)
_, ok = m[".wh.d0"]
require.True(t, ok)
_, ok = m[".wh.d1"]
require.True(t, ok)
// check for a bug that added whiteout for subfile
_, ok = m["d1/.wh.bar"]
require.True(t, !ok)
}
// #276
func testWhiteoutParentDir(t *testing.T, sb integration.Sandbox) {
requiresLinux(t)
t.Parallel()
c, err := New(sb.Address())
require.NoError(t, err)
defer c.Close()
busybox := llb.Image("busybox:latest")
st := llb.Scratch()
run := func(cmd string) {
st = busybox.Run(llb.Shlex(cmd), llb.Dir("/wd")).AddMount("/wd", st)
}
run(`sh -c "mkdir -p foo; echo -n first > foo/bar;"`)
run(`rm foo/bar`)
def, err := st.Marshal()
require.NoError(t, err)
destDir, err := ioutil.TempDir("", "buildkit")
require.NoError(t, err)
defer os.RemoveAll(destDir)
out := filepath.Join(destDir, "out.tar")
err = c.Solve(context.TODO(), def, SolveOpt{
Exporter: ExporterOCI,
ExporterAttrs: map[string]string{
"output": out,
},
}, nil)
require.NoError(t, err)
dt, err := ioutil.ReadFile(out)
require.NoError(t, err)
m, err := readTarToMap(dt, false)
require.NoError(t, err)
var index ocispec.Index
err = json.Unmarshal(m["index.json"].data, &index)
require.NoError(t, err)
var mfst ocispec.Manifest
err = json.Unmarshal(m["blobs/sha256/"+index.Manifests[0].Digest.Hex()].data, &mfst)
require.NoError(t, err)
lastLayer := mfst.Layers[len(mfst.Layers)-1]
layer, ok := m["blobs/sha256/"+lastLayer.Digest.Hex()]
require.True(t, ok)
m, err = readTarToMap(layer.data, true)
require.NoError(t, err)
_, ok = m["foo/.wh.bar"]
require.True(t, ok)
_, ok = m["foo/"]
require.True(t, ok)
}
func requiresLinux(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skipf("unsupported GOOS: %s", runtime.GOOS)

View File

@ -11,8 +11,8 @@ import (
"testing"
"github.com/containerd/containerd"
"github.com/containerd/containerd/fs/fstest"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/continuity/fs/fstest"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/stretchr/testify/require"

View File

@ -17,7 +17,7 @@ type buildOpt struct {
func main() {
var opt buildOpt
flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2-rc.0", "containerd version")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2", "containerd version")
flag.StringVar(&opt.runc, "runc", "9f9c96235cc97674e935002fc3d78361b696a69e", "runc version")
flag.Parse()

View File

@ -17,7 +17,7 @@ type buildOpt struct {
func main() {
var opt buildOpt
flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2-rc.0", "containerd version")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2", "containerd version")
flag.StringVar(&opt.runc, "runc", "9f9c96235cc97674e935002fc3d78361b696a69e", "runc version")
flag.Parse()

View File

@ -17,7 +17,7 @@ type buildOpt struct {
func main() {
var opt buildOpt
flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2-rc.0", "containerd version")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2", "containerd version")
flag.StringVar(&opt.runc, "runc", "9f9c96235cc97674e935002fc3d78361b696a69e", "runc version")
flag.Parse()

View File

@ -18,7 +18,7 @@ type buildOpt struct {
func main() {
var opt buildOpt
flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2-rc.0", "containerd version")
flag.StringVar(&opt.containerd, "containerd", "v1.0.2", "containerd version")
flag.StringVar(&opt.runc, "runc", "9f9c96235cc97674e935002fc3d78361b696a69e", "runc version")
flag.StringVar(&opt.buildkit, "buildkit", "master", "buildkit version")
flag.Parse()

View File

@ -6,7 +6,7 @@ import (
"strconv"
"strings"
"github.com/containerd/containerd/fs"
"github.com/containerd/continuity/fs"
"github.com/opencontainers/runc/libcontainer/user"
)

View File

@ -9,9 +9,9 @@ import (
"path/filepath"
"syscall"
"github.com/containerd/containerd/fs"
"github.com/containerd/containerd/mount"
containerdoci "github.com/containerd/containerd/oci"
"github.com/containerd/continuity/fs"
runc "github.com/containerd/go-runc"
"github.com/moby/buildkit/cache"
"github.com/moby/buildkit/executor"

View File

@ -31,7 +31,7 @@ const (
type WriterOpt struct {
Snapshotter snapshot.Snapshotter
ContentStore content.Store
Differ diff.Differ
Differ diff.Comparer
}
func NewImageWriter(opt WriterOpt) (*ImageWriter, error) {

View File

@ -25,7 +25,7 @@ type DockerExporter struct {
}
// Export exports tarball into writer.
func (de *DockerExporter) Export(ctx context.Context, store content.Store, desc ocispec.Descriptor, writer io.Writer) error {
func (de *DockerExporter) Export(ctx context.Context, store content.Provider, desc ocispec.Descriptor, writer io.Writer) error {
tw := tar.NewWriter(writer)
defer tw.Close()
@ -47,8 +47,13 @@ func (de *DockerExporter) Export(ctx context.Context, store content.Store, desc
return nil, nil
}
// Get all the children for a descriptor
childrenHandler := images.ChildrenHandler(store)
// Filter the childen by the platform
childrenHandler = images.FilterPlatform(platforms.Default(), childrenHandler)
handlers := images.Handlers(
images.ChildrenHandler(store, platforms.Default()),
childrenHandler,
images.HandlerFunc(exportHandler),
)
@ -124,7 +129,7 @@ func dockerManifestRecord(ctx context.Context, provider content.Provider, desc o
}
func blobRecord(cs content.Store, desc ocispec.Descriptor) tarRecord {
func blobRecord(cs content.Provider, desc ocispec.Descriptor) tarRecord {
path := "blobs/" + desc.Digest.Algorithm().String() + "/" + desc.Digest.Hex()
return tarRecord{
Header: &tar.Header{

View File

@ -20,9 +20,9 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/fs/fstest"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/platforms"
"github.com/containerd/continuity/fs/fstest"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/frontend/dockerfile/builder"
"github.com/moby/buildkit/identity"

View File

@ -1,5 +1,5 @@
ARG RUNC_VERSION=9f9c96235cc97674e935002fc3d78361b696a69e
ARG CONTAINERD_VERSION=v1.0.2-rc.0
ARG CONTAINERD_VERSION=v1.0.2
# available targets: buildkitd, buildkitd.oci_only, buildkitd.containerd_only
ARG BUILDKIT_TARGET=buildkitd
ARG REGISTRY_VERSION=2.6

View File

@ -5,7 +5,7 @@ import (
"encoding/json"
"os"
"github.com/containerd/containerd/fs"
"github.com/containerd/continuity/fs"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/solver"

View File

@ -38,7 +38,7 @@ type SourceOpt struct {
SessionManager *session.Manager
Snapshotter snapshot.Snapshotter
ContentStore content.Store
Applier diff.Differ
Applier diff.Applier
CacheAccessor cache.Accessor
}
@ -203,9 +203,16 @@ func (p *puller) Snapshot(ctx context.Context) (cache.ImmutableRef, error) {
schema1Converter = schema1.NewConverter(p.is.ContentStore, fetcher)
handlers = append(handlers, schema1Converter)
} else {
// Get all the children for a descriptor
childrenHandler := images.ChildrenHandler(p.is.ContentStore)
// Set any children labels for that content
childrenHandler = images.SetChildrenLabels(p.is.ContentStore, childrenHandler)
// Filter the childen by the platform
childrenHandler = images.FilterPlatform(platforms.Default(), childrenHandler)
handlers = append(handlers,
remotes.FetchHandler(p.is.ContentStore, fetcher),
images.ChildrenHandler(p.is.ContentStore, platforms.Default()),
childrenHandler,
)
}

View File

@ -6,7 +6,7 @@ github.com/davecgh/go-spew v1.1.0
github.com/pmezard/go-difflib v1.0.0
golang.org/x/sys 9aade4d3a3b7e6d876cd3823ad20ec45fc035402 # update to 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce wiht pkg/signal change
github.com/containerd/containerd 34e24997b24c4677469b617b6cb1861e80f2e4d3
github.com/containerd/containerd af593cf5ab1d8089a42ee7f0b6ed541899378bf7
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
github.com/sirupsen/logrus v1.0.0
@ -15,13 +15,13 @@ github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
github.com/gogo/protobuf v0.5
github.com/golang/protobuf 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e
github.com/containerd/continuity 992a5f112bd2211d0983a1cc8562d2882848f3a3
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc 9f9c96235cc97674e935002fc3d78361b696a69e
github.com/opencontainers/runc a618ab5a0186905949ee463dbb762c3d23e12a80
github.com/Microsoft/go-winio v0.4.5
github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
github.com/opencontainers/runtime-spec v1.0.1
github.com/containerd/go-runc ed1cbe1fc31f5fb2359d3a54b6330d1a097858b7
github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f
github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4

View File

@ -13,8 +13,8 @@ import (
"syscall"
"time"
"github.com/containerd/containerd/fs"
"github.com/containerd/containerd/log"
"github.com/containerd/continuity/fs"
"github.com/dmcgowan/go-tar"
"github.com/pkg/errors"
)
@ -436,6 +436,9 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e
AccessTime: cw.whiteoutT,
ChangeTime: cw.whiteoutT,
}
if err := cw.includeParents(hdr); err != nil {
return err
}
if err := cw.tw.WriteHeader(hdr); err != nil {
return errors.Wrap(err, "failed to write whiteout header")
}

View File

@ -22,7 +22,6 @@ import (
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/dialer"
"github.com/containerd/containerd/diff"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/namespaces"
@ -235,10 +234,17 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image
schema1Converter = schema1.NewConverter(store, fetcher)
handler = images.Handlers(append(pullCtx.BaseHandlers, schema1Converter)...)
} else {
// Get all the children for a descriptor
childrenHandler := images.ChildrenHandler(store)
// Set any children labels for that content
childrenHandler = images.SetChildrenLabels(store, childrenHandler)
// Filter the childen by the platform
childrenHandler = images.FilterPlatform(platforms.Default(), childrenHandler)
handler = images.Handlers(append(pullCtx.BaseHandlers,
remotes.FetchHandler(store, fetcher),
images.ChildrenHandler(store, platforms.Default()))...,
)
childrenHandler,
)...)
}
if err := images.Dispatch(ctx, handler, desc); err != nil {
@ -412,7 +418,7 @@ func (c *Client) ImageService() images.Store {
}
// DiffService returns the underlying Differ
func (c *Client) DiffService() diff.Differ {
func (c *Client) DiffService() DiffService {
return NewDiffServiceFromClient(diffapi.NewDiffClient(c.conn))
}

View File

@ -115,7 +115,7 @@ func WithTaskCheckpoint(im Image) NewTaskOpts {
}
}
func decodeIndex(ctx context.Context, store content.Store, id digest.Digest) (*v1.Index, error) {
func decodeIndex(ctx context.Context, store content.Provider, id digest.Digest) (*v1.Index, error) {
var index v1.Index
p, err := content.ReadBlob(ctx, store, id)
if err != nil {

View File

@ -1,17 +1,24 @@
package containerd
import (
"context"
diffapi "github.com/containerd/containerd/api/services/diff/v1"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/diff"
"github.com/containerd/containerd/mount"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/net/context"
)
// DiffService handles the computation and application of diffs
type DiffService interface {
diff.Comparer
diff.Applier
}
// NewDiffServiceFromClient returns a new diff service which communicates
// over a GRPC connection.
func NewDiffServiceFromClient(client diffapi.DiffClient) diff.Differ {
func NewDiffServiceFromClient(client diffapi.DiffClient) DiffService {
return &diffRemote{
client: client,
}
@ -33,7 +40,7 @@ func (r *diffRemote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts
return toDescriptor(resp.Applied), nil
}
func (r *diffRemote) DiffMounts(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) {
func (r *diffRemote) Compare(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) {
var config diff.Config
for _, opt := range opts {
if err := opt(&config); err != nil {

View File

@ -0,0 +1,112 @@
package apply
import (
"context"
"io"
"io/ioutil"
"time"
"github.com/containerd/containerd/archive"
"github.com/containerd/containerd/archive/compression"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/diff"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// NewFileSystemApplier returns an applier which simply mounts
// and applies diff onto the mounted filesystem.
func NewFileSystemApplier(cs content.Provider) diff.Applier {
return &fsApplier{
store: cs,
}
}
type fsApplier struct {
store content.Provider
}
var emptyDesc = ocispec.Descriptor{}
// Apply applies the content associated with the provided digests onto the
// provided mounts. Archive content will be extracted and decompressed if
// necessary.
func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (d ocispec.Descriptor, err error) {
t1 := time.Now()
defer func() {
if err == nil {
log.G(ctx).WithFields(logrus.Fields{
"d": time.Now().Sub(t1),
"dgst": desc.Digest,
"size": desc.Size,
"media": desc.MediaType,
}).Debugf("diff applied")
}
}()
isCompressed, err := images.IsCompressedDiff(ctx, desc.MediaType)
if err != nil {
return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType)
}
var ocidesc ocispec.Descriptor
if err := mount.WithTempMount(ctx, mounts, func(root string) error {
ra, err := s.store.ReaderAt(ctx, desc.Digest)
if err != nil {
return errors.Wrap(err, "failed to get reader from content store")
}
defer ra.Close()
r := content.NewReader(ra)
if isCompressed {
ds, err := compression.DecompressStream(r)
if err != nil {
return err
}
defer ds.Close()
r = ds
}
digester := digest.Canonical.Digester()
rc := &readCounter{
r: io.TeeReader(r, digester.Hash()),
}
if _, err := archive.Apply(ctx, root, rc); err != nil {
return err
}
// Read any trailing data
if _, err := io.Copy(ioutil.Discard, rc); err != nil {
return err
}
ocidesc = ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageLayer,
Size: rc.c,
Digest: digester.Digest(),
}
return nil
}); err != nil {
return emptyDesc, err
}
return ocidesc, nil
}
type readCounter struct {
r io.Reader
c int64
}
func (rc *readCounter) Read(p []byte) (n int, err error) {
n, err = rc.r.Read(p)
rc.c += int64(n)
return
}

View File

@ -1,9 +1,10 @@
package diff
import (
"context"
"github.com/containerd/containerd/mount"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/net/context"
)
// Config is used to hold parameters needed for a diff operation
@ -24,21 +25,24 @@ type Config struct {
// Opt is used to configure a diff operation
type Opt func(*Config) error
// Differ allows the apply and creation of filesystem diffs between mounts
type Differ interface {
// Comparer allows creation of filesystem diffs between mounts
type Comparer interface {
// Compare computes the difference between two mounts and returns a
// descriptor for the computed diff. The options can provide
// a ref which can be used to track the content creation of the diff.
// The media type which is used to determine the format of the created
// content can also be provided as an option.
Compare(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error)
}
// Applier allows applying diffs between mounts
type Applier interface {
// Apply applies the content referred to by the given descriptor to
// the provided mount. The method of applying is based on the
// implementation and content descriptor. For example, in the common
// case the descriptor is a file system difference in tar format,
// that tar would be applied on top of the mounts.
Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount) (ocispec.Descriptor, error)
// DiffMounts computes the difference between two mounts and returns a
// descriptor for the computed diff. The options can provide
// a ref which can be used to track the content creation of the diff.
// The media type which is used to determine the format of the created
// content can also be provided as an option.
DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error)
}
// WithMediaType sets the media type to use for creating the diff, without

View File

@ -1,11 +1,11 @@
package walking
import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"time"
"github.com/containerd/containerd/archive"
@ -13,121 +13,34 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/diff"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
func init() {
plugin.Register(&plugin.Registration{
Type: plugin.DiffPlugin,
ID: "walking",
Requires: []plugin.Type{
plugin.MetadataPlugin,
},
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
md, err := ic.Get(plugin.MetadataPlugin)
if err != nil {
return nil, err
}
ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec())
return NewWalkingDiff(md.(*metadata.DB).ContentStore())
},
})
}
type walkingDiff struct {
store content.Store
}
var emptyDesc = ocispec.Descriptor{}
// NewWalkingDiff is a generic implementation of diff.Differ.
// NewWalkingDiff is expected to work with any filesystem.
func NewWalkingDiff(store content.Store) (diff.Differ, error) {
// NewWalkingDiff is a generic implementation of diff.Comparer. The diff is
// calculated by mounting both the upper and lower mount sets and walking the
// mounted directories concurrently. Changes are calculated by comparing files
// against each other or by comparing file existence between directories.
// NewWalkingDiff uses no special characteristics of the mount sets and is
// expected to work with any filesystem.
func NewWalkingDiff(store content.Store) diff.Comparer {
return &walkingDiff{
store: store,
}, nil
}
}
// Apply applies the content associated with the provided digests onto the
// provided mounts. Archive content will be extracted and decompressed if
// necessary.
func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (d ocispec.Descriptor, err error) {
t1 := time.Now()
defer func() {
if err == nil {
log.G(ctx).WithFields(logrus.Fields{
"d": time.Now().Sub(t1),
"dgst": desc.Digest,
"size": desc.Size,
"media": desc.MediaType,
}).Debugf("diff applied")
}
}()
isCompressed, err := images.IsCompressedDiff(ctx, desc.MediaType)
if err != nil {
return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType)
}
var ocidesc ocispec.Descriptor
if err := mount.WithTempMount(ctx, mounts, func(root string) error {
ra, err := s.store.ReaderAt(ctx, desc.Digest)
if err != nil {
return errors.Wrap(err, "failed to get reader from content store")
}
defer ra.Close()
r := content.NewReader(ra)
if isCompressed {
ds, err := compression.DecompressStream(r)
if err != nil {
return err
}
defer ds.Close()
r = ds
}
digester := digest.Canonical.Digester()
rc := &readCounter{
r: io.TeeReader(r, digester.Hash()),
}
if _, err := archive.Apply(ctx, root, rc); err != nil {
return err
}
// Read any trailing data
if _, err := io.Copy(ioutil.Discard, rc); err != nil {
return err
}
ocidesc = ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageLayer,
Size: rc.c,
Digest: digester.Digest(),
}
return nil
}); err != nil {
return emptyDesc, err
}
return ocidesc, nil
}
// DiffMounts creates a diff between the given mounts and uploads the result
// Compare creates a diff between the given mounts and uploads the result
// to the content store.
func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) {
func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) {
var config diff.Config
for _, opt := range opts {
if err := opt(&config); err != nil {
@ -228,17 +141,6 @@ func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount
return ocidesc, nil
}
type readCounter struct {
r io.Reader
c int64
}
func (rc *readCounter) Read(p []byte) (n int, err error) {
n, err = rc.r.Read(p)
rc.c += int64(n)
return
}
func uniqueRef() string {
t := time.Now()
var b [3]byte

View File

@ -5,6 +5,7 @@ import (
"fmt"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/platforms"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
@ -128,8 +129,78 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor)
//
// One can also replace this with another implementation to allow descending of
// arbitrary types.
func ChildrenHandler(provider content.Provider, platform string) HandlerFunc {
func ChildrenHandler(provider content.Provider) HandlerFunc {
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
return Children(ctx, provider, desc, platform)
return Children(ctx, provider, desc)
}
}
// SetChildrenLabels is a handler wrapper which sets labels for the content on
// the children returned by the handler and passes through the children.
// Must follow a handler that returns the children to be labeled.
func SetChildrenLabels(manager content.Manager, f HandlerFunc) HandlerFunc {
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
children, err := f(ctx, desc)
if err != nil {
return children, err
}
if len(children) > 0 {
info := content.Info{
Digest: desc.Digest,
Labels: map[string]string{},
}
fields := []string{}
for i, ch := range children {
info.Labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = ch.Digest.String()
fields = append(fields, fmt.Sprintf("labels.containerd.io/gc.ref.content.%d", i))
}
_, err := manager.Update(ctx, info, fields...)
if err != nil {
return nil, err
}
}
return children, err
}
}
// FilterPlatform is a handler wrapper which limits the descriptors returned
// by a handler to a single platform.
func FilterPlatform(platform string, f HandlerFunc) HandlerFunc {
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
children, err := f(ctx, desc)
if err != nil {
return children, err
}
var descs []ocispec.Descriptor
if platform != "" && isMultiPlatform(desc.MediaType) {
matcher, err := platforms.Parse(platform)
if err != nil {
return nil, err
}
for _, d := range children {
if d.Platform == nil || matcher.Match(*d.Platform) {
descs = append(descs, d)
}
}
} else {
descs = children
}
return descs, nil
}
}
func isMultiPlatform(mediaType string) bool {
switch mediaType {
case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
return true
default:
return false
}
}

View File

@ -102,7 +102,7 @@ func (image *Image) Size(ctx context.Context, provider content.Provider, platfor
}
size += desc.Size
return nil, nil
}), ChildrenHandler(provider, platform)), image.Target)
}), FilterPlatform(platform, ChildrenHandler(provider))), image.Target)
}
// Manifest resolves a manifest from the image for the given platform.
@ -238,7 +238,7 @@ func Platforms(ctx context.Context, provider content.Provider, image ocispec.Des
platforms.Normalize(ocispec.Platform{OS: image.OS, Architecture: image.Architecture}))
}
return nil, nil
}), ChildrenHandler(provider, "")), image)
}), ChildrenHandler(provider)), image)
}
// Check returns nil if the all components of an image are available in the
@ -285,7 +285,7 @@ func Check(ctx context.Context, provider content.Provider, image ocispec.Descrip
}
// Children returns the immediate children of content described by the descriptor.
func Children(ctx context.Context, provider content.Provider, desc ocispec.Descriptor, platform string) ([]ocispec.Descriptor, error) {
func Children(ctx context.Context, provider content.Provider, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
var descs []ocispec.Descriptor
switch desc.MediaType {
case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
@ -314,21 +314,7 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return nil, err
}
if platform != "" {
matcher, err := platforms.Parse(platform)
if err != nil {
return nil, err
}
for _, d := range index.Manifests {
if d.Platform == nil || matcher.Match(*d.Platform) {
descs = append(descs, d)
}
}
} else {
descs = append(descs, index.Manifests...)
}
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip,
MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig,

View File

@ -17,5 +17,5 @@ type Importer interface {
// Exporter is the interface for image exporter.
type Exporter interface {
// Export exports an image to a tar stream.
Export(ctx context.Context, store content.Store, desc ocispec.Descriptor, writer io.Writer) error
Export(ctx context.Context, store content.Provider, desc ocispec.Descriptor, writer io.Writer) error
}

View File

@ -25,7 +25,7 @@ type V1Exporter struct {
}
// Export implements Exporter.
func (oe *V1Exporter) Export(ctx context.Context, store content.Store, desc ocispec.Descriptor, writer io.Writer) error {
func (oe *V1Exporter) Export(ctx context.Context, store content.Provider, desc ocispec.Descriptor, writer io.Writer) error {
tw := tar.NewWriter(writer)
defer tw.Close()
@ -42,7 +42,7 @@ func (oe *V1Exporter) Export(ctx context.Context, store content.Store, desc ocis
}
handlers := images.Handlers(
images.ChildrenHandler(store, platforms.Default()),
images.FilterPlatform(platforms.Default(), images.ChildrenHandler(store)),
images.HandlerFunc(exportHandler),
)
@ -67,7 +67,7 @@ type tarRecord struct {
CopyTo func(context.Context, io.Writer) (int64, error)
}
func blobRecord(cs content.Store, desc ocispec.Descriptor) tarRecord {
func blobRecord(cs content.Provider, desc ocispec.Descriptor) tarRecord {
path := "blobs/" + desc.Digest.Algorithm().String() + "/" + desc.Digest.Hex()
return tarRecord{
Header: &tar.Header{

View File

@ -113,7 +113,7 @@ func normalizeImageRef(imageName string, manifest ocispec.Descriptor) (string, e
return imageName + ":" + ociRef, nil
}
func onUntarBlob(ctx context.Context, r io.Reader, store content.Store, name string, size int64) error {
func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, name string, size int64) error {
// name is like "blobs/sha256/deadbeef"
split := strings.Split(name, "/")
if len(split) != 3 {

View File

@ -2,6 +2,7 @@ package log
import (
"context"
"sync/atomic"
"github.com/sirupsen/logrus"
)
@ -21,6 +22,19 @@ type (
loggerKey struct{}
)
// TraceLevel is the log level for tracing. Trace level is lower than debug level,
// and is usually used to trace detailed behavior of the program.
const TraceLevel = logrus.Level(uint32(logrus.DebugLevel + 1))
// ParseLevel takes a string level and returns the Logrus log level constant.
// It supports trace level.
func ParseLevel(lvl string) (logrus.Level, error) {
if lvl == "trace" {
return TraceLevel, nil
}
return logrus.ParseLevel(lvl)
}
// WithLogger returns a new context with the provided logger. Use in
// combination with logger.WithField(s) for great effect.
func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
@ -38,3 +52,19 @@ func GetLogger(ctx context.Context) *logrus.Entry {
return logger.(*logrus.Entry)
}
// Trace logs a message at level Trace with the log entry passed-in.
func Trace(e *logrus.Entry, args ...interface{}) {
level := logrus.Level(atomic.LoadUint32((*uint32)(&e.Logger.Level)))
if level >= TraceLevel {
e.Debug(args...)
}
}
// Tracef logs a message at level Trace with the log entry passed-in.
func Tracef(e *logrus.Entry, format string, args ...interface{}) {
level := logrus.Level(atomic.LoadUint32((*uint32)(&e.Logger.Level)))
if level >= TraceLevel {
e.Debugf(format, args...)
}
}

View File

@ -1,12 +0,0 @@
package log
import (
"io/ioutil"
"log"
"google.golang.org/grpc/grpclog"
)
func init() {
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
}

View File

@ -36,10 +36,10 @@ func WithHostname(name string) SpecOpts {
}
// WithEnv appends environment variables
func WithEnv(environmnetVariables []string) SpecOpts {
func WithEnv(environmentVariables []string) SpecOpts {
return func(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error {
if len(environmnetVariables) > 0 {
s.Process.Env = replaceOrAppendEnvValues(s.Process.Env, environmnetVariables)
if len(environmentVariables) > 0 {
s.Process.Env = replaceOrAppendEnvValues(s.Process.Env, environmentVariables)
}
return nil
}

View File

@ -13,10 +13,10 @@ import (
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/fs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/continuity/fs"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runc/libcontainer/user"
specs "github.com/opencontainers/runtime-spec/specs-go"

View File

@ -140,10 +140,19 @@ func Register(r *Registration) {
register.r = append(register.r, r)
}
// Graph returns an ordered list of registered plugins for initialization
func Graph() (ordered []*Registration) {
// Graph returns an ordered list of registered plugins for initialization.
// Plugins in disableList specified by id will be disabled.
func Graph(disableList []string) (ordered []*Registration) {
register.RLock()
defer register.RUnlock()
for _, d := range disableList {
for i, r := range register.r {
if r.ID == d {
register.r = append(register.r[:i], register.r[i+1:]...)
break
}
}
}
added := map[*Registration]bool{}
for _, r := range register.r {

View File

@ -103,8 +103,41 @@ func (c *Converter) Handle(ctx context.Context, desc ocispec.Descriptor) ([]ocis
}
}
// ConvertOptions provides options on converting a docker schema1 manifest.
type ConvertOptions struct {
// ManifestMediaType specifies the media type of the manifest OCI descriptor.
ManifestMediaType string
// ConfigMediaType specifies the media type of the manifest config OCI
// descriptor.
ConfigMediaType string
}
// ConvertOpt allows configuring a convert operation.
type ConvertOpt func(context.Context, *ConvertOptions) error
// UseDockerSchema2 is used to indicate that a schema1 manifest should be
// converted into the media types for a docker schema2 manifest.
func UseDockerSchema2() ConvertOpt {
return func(ctx context.Context, o *ConvertOptions) error {
o.ManifestMediaType = images.MediaTypeDockerSchema2Manifest
o.ConfigMediaType = images.MediaTypeDockerSchema2Config
return nil
}
}
// Convert a docker manifest to an OCI descriptor
func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) {
func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.Descriptor, error) {
co := ConvertOptions{
ManifestMediaType: ocispec.MediaTypeImageManifest,
ConfigMediaType: ocispec.MediaTypeImageConfig,
}
for _, opt := range opts {
if err := opt(ctx, &co); err != nil {
return ocispec.Descriptor{}, err
}
}
history, diffIDs, err := c.schema1ManifestHistory()
if err != nil {
return ocispec.Descriptor{}, errors.Wrap(err, "schema 1 conversion failed")
@ -121,13 +154,13 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) {
DiffIDs: diffIDs,
}
b, err := json.Marshal(img)
b, err := json.MarshalIndent(img, "", " ")
if err != nil {
return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image")
}
config := ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageConfig,
MediaType: co.ConfigMediaType,
Digest: digest.Canonical.FromBytes(b),
Size: int64(len(b)),
}
@ -145,13 +178,13 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) {
Layers: layers,
}
mb, err := json.Marshal(manifest)
mb, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image")
}
desc := ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageManifest,
MediaType: co.ManifestMediaType,
Digest: digest.Canonical.FromBytes(mb),
Size: int64(len(mb)),
}

View File

@ -2,7 +2,6 @@ package remotes
import (
"context"
"encoding/json"
"fmt"
"io"
"math/rand"
@ -102,83 +101,27 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc
break
}
ws, err := cw.Status()
if err != nil {
return err
}
if ws.Offset == desc.Size {
// If writer is already complete, commit and return
err := cw.Commit(ctx, desc.Size, desc.Digest)
if err != nil && !errdefs.IsAlreadyExists(err) {
return errors.Wrapf(err, "failed commit on ref %q", ws.Ref)
}
return nil
}
rc, err := fetcher.Fetch(ctx, desc)
if err != nil {
return err
}
defer rc.Close()
r, opts := commitOpts(desc, rc)
return content.Copy(ctx, cw, r, desc.Size, desc.Digest, opts...)
}
// commitOpts gets the appropriate content options to alter
// the content info on commit based on media type.
func commitOpts(desc ocispec.Descriptor, r io.Reader) (io.Reader, []content.Opt) {
var childrenF func(r io.Reader) ([]ocispec.Descriptor, error)
// TODO(AkihiroSuda): use images/oci.GetChildrenDescriptors?
switch desc.MediaType {
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
childrenF = func(r io.Reader) ([]ocispec.Descriptor, error) {
var (
manifest ocispec.Manifest
decoder = json.NewDecoder(r)
)
if err := decoder.Decode(&manifest); err != nil {
return nil, err
}
return append([]ocispec.Descriptor{manifest.Config}, manifest.Layers...), nil
}
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
childrenF = func(r io.Reader) ([]ocispec.Descriptor, error) {
var (
index ocispec.Index
decoder = json.NewDecoder(r)
)
if err := decoder.Decode(&index); err != nil {
return nil, err
}
return index.Manifests, nil
}
default:
return r, nil
}
pr, pw := io.Pipe()
var children []ocispec.Descriptor
errC := make(chan error)
go func() {
defer close(errC)
ch, err := childrenF(pr)
if err != nil {
errC <- err
}
children = ch
}()
opt := func(info *content.Info) error {
err := <-errC
if err != nil {
return errors.Wrap(err, "unable to get commit labels")
}
if len(children) > 0 {
if info.Labels == nil {
info.Labels = map[string]string{}
}
for i, ch := range children {
info.Labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = ch.Digest.String()
}
}
return nil
}
return io.TeeReader(r, pw), []content.Opt{opt}
return content.Copy(ctx, cw, rc, desc.Size, desc.Digest)
}
// PushHandler returns a handler that will push all content from the provider
@ -243,7 +186,7 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, pr
pushHandler := PushHandler(pusher, provider)
handlers := append(baseHandlers,
images.ChildrenHandler(provider, platforms.Default()),
images.FilterPlatform(platforms.Default(), images.ChildrenHandler(provider)),
filterHandler,
pushHandler,
)

View File

@ -30,7 +30,7 @@ type Layer struct {
// The returned result is a chain id digest representing all the applied layers.
// Layers are applied in order they are given, making the first layer the
// bottom-most layer in the layer chain.
func ApplyLayers(ctx context.Context, layers []Layer, sn snapshots.Snapshotter, a diff.Differ) (digest.Digest, error) {
func ApplyLayers(ctx context.Context, layers []Layer, sn snapshots.Snapshotter, a diff.Applier) (digest.Digest, error) {
var chain []digest.Digest
for _, layer := range layers {
if _, err := ApplyLayer(ctx, layer, chain, sn, a); err != nil {
@ -46,7 +46,7 @@ func ApplyLayers(ctx context.Context, layers []Layer, sn snapshots.Snapshotter,
// ApplyLayer applies a single layer on top of the given provided layer chain,
// using the provided snapshotter and applier. If the layer was unpacked true
// is returned, if the layer already exists false is returned.
func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snapshots.Snapshotter, a diff.Differ, opts ...snapshots.Opt) (bool, error) {
func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snapshots.Snapshotter, a diff.Applier, opts ...snapshots.Opt) (bool, error) {
var (
parent = identity.ChainID(chain)
chainID = identity.ChainID(append(chain, layer.Diff.Digest))

View File

@ -10,11 +10,11 @@ import (
"golang.org/x/net/context"
)
// Diff creates a layer diff for the given snapshot identifier from the parent
// of the snapshot. A content ref is provided to track the progress of the
// content creation and the provided snapshotter and mount differ are used
// CreateDiff creates a layer diff for the given snapshot identifier from the
// parent of the snapshot. A content ref is provided to track the progress of
// the content creation and the provided snapshotter and mount differ are used
// for calculating the diff. The descriptor for the layer diff is returned.
func Diff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d diff.Differ, opts ...diff.Opt) (ocispec.Descriptor, error) {
func CreateDiff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d diff.Comparer, opts ...diff.Opt) (ocispec.Descriptor, error) {
info, err := sn.Stat(ctx, snapshotID)
if err != nil {
return ocispec.Descriptor{}, err
@ -42,5 +42,5 @@ func Diff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d di
defer sn.Remove(ctx, upperKey)
}
return d.DiffMounts(ctx, lower, upper, opts...)
return d.Compare(ctx, lower, upper, opts...)
}

View File

@ -6,13 +6,13 @@ import (
"os"
"path/filepath"
"github.com/containerd/containerd/fs"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/storage"
"github.com/containerd/continuity/fs"
"github.com/pkg/errors"
)

View File

@ -11,13 +11,13 @@ import (
"strings"
"syscall"
"github.com/containerd/containerd/fs"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/storage"
"github.com/containerd/continuity/fs"
"github.com/pkg/errors"
)

View File

@ -24,5 +24,5 @@ func StatMtime(st *syscall.Stat_t) syscall.Timespec {
// StatATimeAsTime returns st.Atim as a time.Time
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
return time.Unix(st.Atim.Sec, st.Atim.Nsec)
return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert
}

View File

@ -536,7 +536,7 @@ func (t *task) checkpointRWSnapshot(ctx context.Context, index *v1.Index, snapsh
opts := []diff.Opt{
diff.WithReference(fmt.Sprintf("checkpoint-rw-%s", id)),
}
rw, err := rootfs.Diff(ctx, id, t.client.SnapshotService(snapshotterName), t.client.DiffService(), opts...)
rw, err := rootfs.CreateDiff(ctx, id, t.client.SnapshotService(snapshotterName), t.client.DiffService(), opts...)
if err != nil {
return err
}
@ -572,7 +572,7 @@ func (t *task) writeIndex(ctx context.Context, index *v1.Index) (d v1.Descriptor
return writeContent(ctx, t.client.ContentStore(), v1.MediaTypeImageIndex, t.id, buf, content.WithLabels(labels))
}
func writeContent(ctx context.Context, store content.Store, mediaType, ref string, r io.Reader, opts ...content.Opt) (d v1.Descriptor, err error) {
func writeContent(ctx context.Context, store content.Ingester, mediaType, ref string, r io.Reader, opts ...content.Opt) (d v1.Descriptor, err error) {
writer, err := store.Writer(ctx, ref, 0, "")
if err != nil {
return d, err

View File

@ -1,7 +1,7 @@
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f
github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
github.com/containerd/cgroups 29da22c6171a4316169f9205ab6c49f59b5b852f
github.com/containerd/cgroups c0710c92e8b3a44681d1321dcfd1360fc5c6c089
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
@ -16,11 +16,9 @@ github.com/docker/go-units v0.3.1
github.com/gogo/protobuf v0.5
github.com/golang/protobuf 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
github.com/opencontainers/runtime-spec v1.0.1
github.com/opencontainers/runc 9f9c96235cc97674e935002fc3d78361b696a69e
github.com/opencontainers/runc a618ab5a0186905949ee463dbb762c3d23e12a80
github.com/sirupsen/logrus v1.0.0
github.com/containerd/btrfs cc52c4dea2ce11a44e6639e561bb5c2af9ada9e3
github.com/stretchr/testify v1.1.4
github.com/davecgh/go-spew v1.1.0
github.com/pmezard/go-difflib v1.0.0
github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
@ -30,9 +28,9 @@ github.com/pkg/errors v0.8.0
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 https://github.com/golang/sys
github.com/opencontainers/image-spec v1.0.1
github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e
github.com/containerd/continuity 992a5f112bd2211d0983a1cc8562d2882848f3a3
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
github.com/BurntSushi/toml v0.2.0-21-g9906417
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
github.com/Microsoft/go-winio v0.4.5
github.com/Microsoft/hcsshim v0.6.7
@ -40,5 +38,7 @@ github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
github.com/dmcgowan/go-tar go1.10
github.com/stevvooe/ttrpc d2710463e497617f16f26d1e715a3308609e7982
github.com/stevvooe/ttrpc d4528379866b0ce7e9d71f3eb96f0582fc374577
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010a
github.com/google/go-cmp v0.1.0

View File

@ -1,15 +0,0 @@
package devices
// from /usr/include/sys/types.h
func getmajor(dev int32) uint64 {
return (uint64(dev) >> 24) & 0xff
}
func getminor(dev int32) uint64 {
return uint64(dev) & 0xffffff
}
func makedev(major int, minor int) int {
return ((major << 24) | minor)
}

View File

@ -1,23 +0,0 @@
// +build solaris,!cgo
//
// Implementing the functions below requires cgo support. Non-cgo stubs
// versions are defined below to enable cross-compilation of source code
// that depends on these functions, but the resultant cross-compiled
// binaries cannot actually be used. If the stub function(s) below are
// actually invoked they will cause the calling process to exit.
//
package devices
func getmajor(dev uint64) uint64 {
panic("getmajor() support requires cgo.")
}
func getminor(dev uint64) uint64 {
panic("getminor() support requires cgo.")
}
func makedev(major int, minor int) int {
panic("makedev() support requires cgo.")
}

View File

@ -1,15 +0,0 @@
package devices
// from /usr/include/sys/types.h
func getmajor(dev uint32) uint64 {
return (uint64(dev) >> 24) & 0xff
}
func getminor(dev uint32) uint64 {
return uint64(dev) & 0xffffff
}
func makedev(major int, minor int) int {
return ((major << 24) | minor)
}

View File

@ -1,15 +0,0 @@
package devices
// from /usr/include/linux/kdev_t.h
func getmajor(dev uint64) uint64 {
return dev >> 8
}
func getminor(dev uint64) uint64 {
return dev & 0xff
}
func makedev(major int, minor int) int {
return ((major << 8) | minor)
}

View File

@ -1,18 +0,0 @@
// +build cgo
package devices
//#include <sys/mkdev.h>
import "C"
func getmajor(dev uint64) uint64 {
return uint64(C.major(C.dev_t(dev)))
}
func getminor(dev uint64) uint64 {
return uint64(C.minor(C.dev_t(dev)))
}
func makedev(major int, minor int) int {
return int(C.makedev(C.major_t(major), C.minor_t(minor)))
}

View File

@ -6,6 +6,8 @@ import (
"fmt"
"os"
"syscall"
"golang.org/x/sys/unix"
)
func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
@ -14,42 +16,43 @@ func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
return 0, 0, fmt.Errorf("cannot extract device from os.FileInfo")
}
return getmajor(sys.Rdev), getminor(sys.Rdev), nil
dev := uint64(sys.Rdev)
return uint64(unix.Major(dev)), uint64(unix.Minor(dev)), nil
}
// mknod provides a shortcut for syscall.Mknod
func Mknod(p string, mode os.FileMode, maj, min int) error {
var (
m = syscallMode(mode.Perm())
dev int
dev uint64
)
if mode&os.ModeDevice != 0 {
dev = makedev(maj, min)
dev = unix.Mkdev(uint32(maj), uint32(min))
if mode&os.ModeCharDevice != 0 {
m |= syscall.S_IFCHR
m |= unix.S_IFCHR
} else {
m |= syscall.S_IFBLK
m |= unix.S_IFBLK
}
} else if mode&os.ModeNamedPipe != 0 {
m |= syscall.S_IFIFO
m |= unix.S_IFIFO
}
return syscall.Mknod(p, m, dev)
return unix.Mknod(p, m, int(dev))
}
// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
func syscallMode(i os.FileMode) (o uint32) {
o |= uint32(i.Perm())
if i&os.ModeSetuid != 0 {
o |= syscall.S_ISUID
o |= unix.S_ISUID
}
if i&os.ModeSetgid != 0 {
o |= syscall.S_ISGID
o |= unix.S_ISGID
}
if i&os.ModeSticky != 0 {
o |= syscall.S_ISVTX
o |= unix.S_ISVTX
}
return
}

View File

@ -0,0 +1,74 @@
package driver
import (
"io"
"io/ioutil"
"os"
"sort"
)
// ReadFile works the same as ioutil.ReadFile with the Driver abstraction
func ReadFile(r Driver, filename string) ([]byte, error) {
f, err := r.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
data, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
return data, nil
}
// WriteFile works the same as ioutil.WriteFile with the Driver abstraction
func WriteFile(r Driver, filename string, data []byte, perm os.FileMode) error {
f, err := r.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
defer f.Close()
n, err := f.Write(data)
if err != nil {
return err
} else if n != len(data) {
return io.ErrShortWrite
}
return nil
}
// ReadDir works the same as ioutil.ReadDir with the Driver abstraction
func ReadDir(r Driver, dirname string) ([]os.FileInfo, error) {
f, err := r.Open(dirname)
if err != nil {
return nil, err
}
defer f.Close()
dirs, err := f.Readdir(-1)
if err != nil {
return nil, err
}
sort.Sort(fileInfos(dirs))
return dirs, nil
}
// Simple implementation of the sort.Interface for os.FileInfo
type fileInfos []os.FileInfo
func (fis fileInfos) Len() int {
return len(fis)
}
func (fis fileInfos) Less(i, j int) bool {
return fis[i].Name() < fis[j].Name()
}
func (fis fileInfos) Swap(i, j int) {
fis[i], fis[j] = fis[j], fis[i]
}

View File

@ -5,7 +5,6 @@ import (
"os"
"syscall"
"github.com/containerd/containerd/sys"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
@ -36,7 +35,7 @@ func copyFileInfo(fi os.FileInfo, name string) error {
}
}
timespec := []unix.Timespec{unix.Timespec(sys.StatAtime(st)), unix.Timespec(sys.StatMtime(st))}
timespec := []unix.Timespec{unix.Timespec(StatAtime(st)), unix.Timespec(StatMtime(st))}
if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
return errors.Wrapf(err, "failed to utime %s", name)
}

View File

@ -7,7 +7,6 @@ import (
"os"
"syscall"
"github.com/containerd/containerd/sys"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
@ -38,7 +37,7 @@ func copyFileInfo(fi os.FileInfo, name string) error {
}
}
timespec := []syscall.Timespec{sys.StatAtime(st), sys.StatMtime(st)}
timespec := []syscall.Timespec{StatAtime(st), StatMtime(st)}
if err := syscall.UtimesNano(name, timespec); err != nil {
return errors.Wrapf(err, "failed to utime %s", name)
}

View File

@ -273,7 +273,7 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b string) (err
if rmdir != "" && strings.HasPrefix(f1.path, rmdir) {
f1 = nil
continue
} else if rmdir == "" && f1.f.IsDir() {
} else if f1.f.IsDir() {
rmdir = f1.path + string(os.PathSeparator)
} else if rmdir != "" {
rmdir = ""

View File

@ -3,12 +3,12 @@ package fstest
import (
"time"
"github.com/containerd/containerd/errdefs"
"github.com/pkg/errors"
)
// Lchtimes changes access and mod time of file without following symlink
func Lchtimes(name string, atime, mtime time.Time) Applier {
return applyFn(func(root string) error {
return errdefs.ErrNotImplemented
return errors.New("Not implemented")
})
}

28
vendor/github.com/containerd/continuity/fs/stat_bsd.go generated vendored Normal file
View File

@ -0,0 +1,28 @@
// +build darwin freebsd
package fs
import (
"syscall"
"time"
)
// StatAtime returns the access time from a stat struct
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
return st.Atimespec
}
// StatCtime returns the created time from a stat struct
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
return st.Ctimespec
}
// StatMtime returns the modified time from a stat struct
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
return st.Mtimespec
}
// StatATimeAsTime returns the access time as a time.Time
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert
}

View File

@ -0,0 +1,26 @@
package fs
import (
"syscall"
"time"
)
// StatAtime returns the Atim
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
return st.Atim
}
// StatCtime returns the Ctim
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
return st.Ctim
}
// StatMtime returns the Mtim
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
return st.Mtim
}
// StatATimeAsTime returns st.Atim as a time.Time
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
return time.Unix(st.Atim.Sec, st.Atim.Nsec)
}

View File

@ -82,9 +82,9 @@ type Resource struct {
// Relative links do not start with a slash and are relative to the
// resource path.
Target string `protobuf:"bytes,9,opt,name=target" json:"target,omitempty"`
// Major specifies the major device number for charactor and block devices.
// Major specifies the major device number for character and block devices.
Major uint64 `protobuf:"varint,10,opt,name=major" json:"major,omitempty"`
// Minor specifies the minor device number for charactor and block devices.
// Minor specifies the minor device number for character and block devices.
Minor uint64 `protobuf:"varint,11,opt,name=minor" json:"minor,omitempty"`
// Xattr provides storage for extended attributes for the target resource.
Xattr []*XAttr `protobuf:"bytes,12,rep,name=xattr" json:"xattr,omitempty"`

View File

@ -53,10 +53,10 @@ message Resource {
// resource path.
string target = 9;
// Major specifies the major device number for charactor and block devices.
// Major specifies the major device number for character and block devices.
uint64 major = 10;
// Minor specifies the minor device number for charactor and block devices.
// Minor specifies the minor device number for character and block devices.
uint64 minor = 11;
// Xattr provides storage for extended attributes for the target resource.

View File

@ -1,11 +0,0 @@
package sysx
// These functions will be generated by generate.sh
// $ GOOS=linux GOARCH=386 ./generate.sh copy
// $ GOOS=linux GOARCH=amd64 ./generate.sh copy
// $ GOOS=linux GOARCH=arm ./generate.sh copy
// $ GOOS=linux GOARCH=arm64 ./generate.sh copy
// $ GOOS=linux GOARCH=ppc64le ./generate.sh copy
// $ GOOS=linux GOARCH=s390x ./generate.sh copy
//sys CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error)

View File

@ -1,20 +0,0 @@
// mksyscall.pl -l32 copy_linux.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package sysx
import (
"syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View File

@ -1,20 +0,0 @@
// mksyscall.pl copy_linux.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package sysx
import (
"syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View File

@ -1,20 +0,0 @@
// mksyscall.pl -l32 copy_linux.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package sysx
import (
"syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View File

@ -1,20 +0,0 @@
// mksyscall.pl copy_linux.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package sysx
import (
"syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View File

@ -1,20 +0,0 @@
// mksyscall.pl copy_linux.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package sysx
import (
"syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View File

@ -1,20 +0,0 @@
// mksyscall.pl copy_linux.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package sysx
import (
"syscall"
"unsafe"
)
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View File

@ -1,7 +0,0 @@
package sysx
const (
// SYS_COPYFILERANGE defined in Kernel 4.5+
// Number defined in /usr/include/asm/unistd_32.h
SYS_COPY_FILE_RANGE = 377
)

View File

@ -1,7 +0,0 @@
package sysx
const (
// SYS_COPYFILERANGE defined in Kernel 4.5+
// Number defined in /usr/include/asm/unistd_64.h
SYS_COPY_FILE_RANGE = 326
)

View File

@ -1,7 +0,0 @@
package sysx
const (
// SYS_COPY_FILE_RANGE defined in Kernel 4.5+
// Number defined in /usr/include/arm-linux-gnueabihf/asm/unistd.h
SYS_COPY_FILE_RANGE = 391
)

View File

@ -1,7 +0,0 @@
package sysx
const (
// SYS_COPY_FILE_RANGE defined in Kernel 4.5+
// Number defined in /usr/include/asm-generic/unistd.h
SYS_COPY_FILE_RANGE = 285
)

View File

@ -1,7 +0,0 @@
package sysx
const (
// SYS_COPYFILERANGE defined in Kernel 4.5+
// Number defined in /usr/include/asm/unistd_64.h
SYS_COPY_FILE_RANGE = 379
)

View File

@ -1,7 +0,0 @@
package sysx
const (
// SYS_COPYFILERANGE defined in Kernel 4.5+
// Number defined in /usr/include/asm/unistd_64.h
SYS_COPY_FILE_RANGE = 375
)

13
vendor/github.com/containerd/continuity/vendor.conf generated vendored Normal file
View File

@ -0,0 +1,13 @@
bazil.org/fuse 371fbbdaa8987b715bdd21d6adc4c9b20155f748
github.com/dustin/go-humanize bb3d318650d48840a39aa21a027c6630e198e626
github.com/golang/protobuf 1e59b77b52bf8e4b449a57e6f79f21226d571845
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b09e2af76183bf
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
github.com/sirupsen/logrus 89742aefa4b206dcf400792f3bd35b542998eb3b
github.com/spf13/cobra 2da4a54c5ceefcee7ca5dd0eea1e18a3b6366489
github.com/spf13/pflag 4c012f6dcd9546820e378d0bdda4d8fc772cdfea
golang.org/x/crypto 9f005a07e0d31d45e6656d241bb5c0f2efd4bc94
golang.org/x/net a337091b0525af65de94df2eb7e98bd9962dcbe2
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
golang.org/x/sys 665f6529cca930e27b831a0d1dafffbe1c172924

View File

@ -1,7 +1,6 @@
package runc
import (
"bytes"
"context"
"encoding/json"
"errors"
@ -532,7 +531,9 @@ func (r *Runc) Restore(context context.Context, id, bundle string, opts *Restore
// Update updates the current container with the provided resource spec
func (r *Runc) Update(context context.Context, id string, resources *specs.LinuxResources) error {
buf := bytes.NewBuffer(nil)
buf := getBuf()
defer putBuf(buf)
if err := json.NewEncoder(buf).Encode(resources); err != nil {
return err
}
@ -638,11 +639,12 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
}
func cmdOutput(cmd *exec.Cmd, combined bool) ([]byte, error) {
var b bytes.Buffer
b := getBuf()
defer putBuf(b)
cmd.Stdout = &b
cmd.Stdout = b
if combined {
cmd.Stderr = &b
cmd.Stderr = b
}
ec, err := Monitor.Start(cmd)
if err != nil {

View File

@ -1,8 +1,10 @@
package runc
import (
"bytes"
"io/ioutil"
"strconv"
"sync"
"syscall"
)
@ -26,3 +28,18 @@ func exitStatus(status syscall.WaitStatus) int {
}
return status.ExitStatus()
}
var bytesBufferPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(nil)
},
}
func getBuf() *bytes.Buffer {
return bytesBufferPool.Get().(*bytes.Buffer)
}
func putBuf(b *bytes.Buffer) {
b.Reset()
bytesBufferPool.Put(b)
}

View File

@ -22,7 +22,6 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/limits.h>
#include <linux/netlink.h>
#include <linux/types.h>
@ -73,7 +72,7 @@ struct nlconfig_t {
char *oom_score_adj;
size_t oom_score_adj_len;
/* User namespace settings.*/
/* User namespace settings. */
char *uidmap;
size_t uidmap_len;
char *gidmap;
@ -82,7 +81,7 @@ struct nlconfig_t {
size_t namespaces_len;
uint8_t is_setgroup;
/* Rootless container settings.*/
/* Rootless container settings. */
uint8_t is_rootless;
char *uidmappath;
size_t uidmappath_len;
@ -167,7 +166,7 @@ static int write_file(char *data, size_t data_len, char *pathfmt, ...)
goto out;
}
out:
out:
close(fd);
return ret;
}
@ -226,14 +225,14 @@ static int try_mapping_tool(const char *app, int pid, char *map, size_t map_len)
if (!child) {
#define MAX_ARGV 20
char *argv[MAX_ARGV];
char *envp[] = {NULL};
char *envp[] = { NULL };
char pid_fmt[16];
int argc = 0;
char *next;
snprintf(pid_fmt, 16, "%d", pid);
argv[argc++] = (char *) app;
argv[argc++] = (char *)app;
argv[argc++] = pid_fmt;
/*
* Convert the map string into a list of argument that
@ -533,7 +532,7 @@ void nsexec(void)
int pipenum;
jmp_buf env;
int sync_child_pipe[2], sync_grandchild_pipe[2];
struct nlconfig_t config = {0};
struct nlconfig_t config = { 0 };
/*
* If we don't have an init pipe, just return to the go routine.
@ -637,14 +636,14 @@ void nsexec(void)
* it will send us its PID which we will send to the bootstrap
* process.
*/
case JUMP_PARENT: {
case JUMP_PARENT:{
int len;
pid_t child, first_child = -1;
char buf[JSON_MAX];
bool ready = false;
/* For debugging. */
prctl(PR_SET_NAME, (unsigned long) "runc:[0:PARENT]", 0, 0, 0);
prctl(PR_SET_NAME, (unsigned long)"runc:[0:PARENT]", 0, 0, 0);
/* Start the process of getting a container. */
child = clone_parent(&env, JUMP_CHILD);
@ -702,7 +701,7 @@ void nsexec(void)
bail("failed to sync with child: write(SYNC_USERMAP_ACK)");
}
break;
case SYNC_RECVPID_PLS: {
case SYNC_RECVPID_PLS:{
first_child = child;
/* Get the init_func pid. */
@ -790,7 +789,7 @@ void nsexec(void)
* (stage 2: JUMP_INIT) for PID namespace. We then send the
* child's PID to our parent (stage 0).
*/
case JUMP_CHILD: {
case JUMP_CHILD:{
pid_t child;
enum sync_t s;
@ -799,7 +798,7 @@ void nsexec(void)
close(sync_child_pipe[1]);
/* For debugging. */
prctl(PR_SET_NAME, (unsigned long) "runc:[1:CHILD]", 0, 0, 0);
prctl(PR_SET_NAME, (unsigned long)"runc:[1:CHILD]", 0, 0, 0);
/*
* We need to setns first. We cannot do this earlier (in stage 0)
@ -907,7 +906,7 @@ void nsexec(void)
* final cleanup steps and then return to the Go runtime to allow
* init_linux.go to run.
*/
case JUMP_INIT: {
case JUMP_INIT:{
/*
* We're inside the child now, having jumped from the
* start_child() code after forking in the parent.
@ -921,7 +920,7 @@ void nsexec(void)
close(sync_child_pipe[1]);
/* For debugging. */
prctl(PR_SET_NAME, (unsigned long) "runc:[2:INIT]", 0, 0, 0);
prctl(PR_SET_NAME, (unsigned long)"runc:[2:INIT]", 0, 0, 0);
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with parent: read(SYNC_GRANDCHILD)");

View File

@ -50,8 +50,8 @@ type WorkerOpt struct {
Executor executor.Executor
Snapshotter snapshot.Snapshotter
ContentStore content.Store
Applier diff.Differ
Differ diff.Differ
Applier diff.Applier
Differ diff.Comparer
ImageStore images.Store // optional
}

View File

@ -7,6 +7,7 @@ import (
"github.com/boltdb/bolt"
"github.com/containerd/containerd/content/local"
"github.com/containerd/containerd/diff/apply"
"github.com/containerd/containerd/diff/walking"
ctdmetadata "github.com/containerd/containerd/metadata"
ctdsnapshot "github.com/containerd/containerd/snapshots"
@ -63,10 +64,6 @@ func NewWorkerOpt(root string, labels map[string]string) (base.WorkerOpt, error)
}
c = containerdsnapshot.NewContentStore(mdb.ContentStore(), "buildkit", gc)
df, err := walking.NewWalkingDiff(c)
if err != nil {
return opt, err
}
id, err := base.ID(root)
if err != nil {
@ -83,8 +80,8 @@ func NewWorkerOpt(root string, labels map[string]string) (base.WorkerOpt, error)
Executor: exe,
Snapshotter: containerdsnapshot.NewSnapshotter(mdb.Snapshotter("overlayfs"), c, md, "buildkit", gc),
ContentStore: c,
Applier: df,
Differ: df,
Applier: apply.NewFileSystemApplier(c),
Differ: walking.NewWalkingDiff(c),
ImageStore: nil, // explicitly
}
return opt, nil