Merge pull request #280 from tonistiigi/update-containerd
vendor: update containerd to v1.0.2docker-18.09
commit
794d61c1e6
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/moby/buildkit/snapshot"
|
||||
)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/opencontainers/runc/libcontainer/user"
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)))
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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 = ""
|
|
@ -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")
|
||||
})
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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"`
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)");
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue