Update Windows runtime to use snapshotter and differ layers

This changes the Windows runtime to use the snapshotter and differ
created layers, and updates the ctr commands to use the snapshotter and differ.

Signed-off-by: Darren Stahl <darst@microsoft.com>
This commit is contained in:
Darren Stahl 2018-01-05 13:30:26 -08:00
parent a5a9f91832
commit dcff993653
9 changed files with 92 additions and 318 deletions

View File

@ -7,32 +7,12 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/oci"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
func init() {
Command.Flags = append(Command.Flags, cli.StringSliceFlag{
Name: "layer",
Usage: "HCSSHIM Layers to be used",
})
}
func withLayers(context *cli.Context) oci.SpecOpts {
return func(ctx gocontext.Context, client oci.Client, c *containers.Container, s *specs.Spec) error {
l := context.StringSlice("layer")
if l == nil {
return errors.Wrap(errdefs.ErrInvalidArgument, "base layers must be specified with `--layer`")
}
s.Windows.LayerFolders = l
return nil
}
}
func withTTY(terminal bool) oci.SpecOpts {
if !terminal {
return func(ctx gocontext.Context, client oci.Client, c *containers.Container, s *specs.Spec) error {
@ -51,36 +31,39 @@ func withTTY(terminal bool) oci.SpecOpts {
func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
var (
// ref = context.Args().First()
ref = context.Args().First()
id = context.Args().Get(1)
args = context.Args()[2:]
tty = context.Bool("tty")
labelStrings = context.StringSlice("label")
)
labels := commands.LabelArgs(labelStrings)
// TODO(mlaventure): get base image once we have a snapshotter
opts := []oci.SpecOpts{
// TODO(mlaventure): use oci.WithImageConfig once we have a snapshotter
withLayers(context),
oci.WithEnv(context.StringSlice("env")),
withMounts(context),
withTTY(tty),
image, err := client.GetImage(ctx, ref)
if err != nil {
return nil, err
}
var (
opts []oci.SpecOpts
cOpts []containerd.NewContainerOpts
)
opts = append(opts, oci.WithImageConfig(image))
opts = append(opts, oci.WithEnv(context.StringSlice("env")))
opts = append(opts, withMounts(context))
if len(args) > 0 {
opts = append(opts, oci.WithProcessArgs(args...))
}
if cwd := context.String("cwd"); cwd != "" {
opts = append(opts, oci.WithProcessCwd(cwd))
}
return client.NewContainer(ctx, id,
containerd.WithNewSpec(opts...),
containerd.WithContainerLabels(labels),
containerd.WithRuntime(context.String("runtime"), nil),
// TODO(mlaventure): containerd.WithImage(image),
)
opts = append(opts, withTTY(context.Bool("tty")))
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
cOpts = append(cOpts, containerd.WithImage(image))
cOpts = append(cOpts, containerd.WithSnapshotter(context.String("snapshotter")))
cOpts = append(cOpts, containerd.WithNewSnapshot(id, image))
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
cOpts = append([]containerd.NewContainerOpts{containerd.WithNewSpec(opts...)}, cOpts...)
return client.NewContainer(ctx, id, cOpts...)
}
func getNewTaskOpts(_ *cli.Context) []containerd.NewTaskOpts {

View File

@ -140,7 +140,7 @@ func (s *windowsDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts
// DiffMounts creates a diff between the given mounts and uploads the result
// to the content store.
func (s *windowsDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) {
panic("not implemented on Windows")
return emptyDesc, errdefs.ErrNotImplemented
}
type readCounter struct {

View File

@ -39,11 +39,6 @@ func (m *Mount) Mount(target string) error {
if err = hcsshim.PrepareLayer(di, layerID, parentLayerPaths); err != nil {
return errors.Wrapf(err, "failed to prepare layer %s", m.Source)
}
defer func() {
if err != nil {
hcsshim.UnprepareLayer(di, layerID)
}
}()
return nil
}
@ -67,10 +62,12 @@ func (m *Mount) GetParentPaths() ([]string, error) {
// Unmount the mount at the provided path
func Unmount(mount string, flags int) error {
home, layerID := filepath.Split(mount)
var di = hcsshim.DriverInfo{
var (
home, layerID = filepath.Split(mount)
di = hcsshim.DriverInfo{
HomeDir: home,
}
)
if err := hcsshim.UnprepareLayer(di, layerID); err != nil {
return errors.Wrapf(err, "failed to unprepare layer %s", mount)

View File

@ -1,16 +0,0 @@
// +build windows
package windows
import (
"context"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/snapshots/storage"
)
func rollbackWithLogging(ctx context.Context, t storage.Transactor) {
if err := t.Rollback(); err != nil {
log.G(ctx).WithError(err).Warn("failed to rollback transaction")
}
}

View File

@ -41,12 +41,12 @@ type snapshotter struct {
// NewSnapshotter returns a new windows snapshotter
func NewSnapshotter(root string) (snapshots.Snapshotter, error) {
fsType, err := getFileSystemType(string(root[0]))
fsType, err := getFileSystemType(root)
if err != nil {
return nil, err
}
if strings.ToLower(fsType) == "refs" {
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "%s is on an ReFS volume - ReFS volumes are not supported", root)
if strings.ToLower(fsType) != "ntfs" {
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "%s is not on an NTFS volume - only NTFS volumes are supported", root)
}
if err := os.MkdirAll(root, 0700); err != nil {
@ -83,11 +83,7 @@ func (s *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, err
defer t.Rollback()
_, info, _, err := storage.GetInfo(ctx, key)
if err != nil {
return snapshots.Info{}, err
}
return info, nil
return info, err
}
func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) {
@ -95,13 +91,7 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath
if err != nil {
return snapshots.Info{}, err
}
var committed bool
defer func() {
if committed == false {
rollbackWithLogging(ctx, t)
}
}()
defer t.Rollback()
info, err = storage.UpdateInfo(ctx, info, fieldpaths...)
if err != nil {
@ -111,7 +101,6 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath
if err := t.Commit(); err != nil {
return snapshots.Info{}, err
}
committed = true
return info, nil
}
@ -156,6 +145,7 @@ func (s *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, er
return nil, err
}
defer t.Rollback()
snapshot, err := storage.GetSnapshot(ctx, key)
if err != nil {
return nil, errors.Wrap(err, "failed to get snapshot mount")
@ -168,13 +158,8 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
if err != nil {
return err
}
defer t.Rollback()
var committed bool
defer func() {
if committed == false {
rollbackWithLogging(ctx, t)
}
}()
usage := fs.Usage{
Size: 0,
}
@ -186,7 +171,6 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
if err := t.Commit(); err != nil {
return err
}
committed = true
return nil
}
@ -197,13 +181,7 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
if err != nil {
return err
}
var committed bool
defer func() {
if committed == false {
rollbackWithLogging(ctx, t)
}
}()
defer t.Rollback()
id, _, err := storage.Remove(ctx, key)
if err != nil {
@ -217,15 +195,13 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
return err
}
err = t.Commit()
if err != nil {
if err := t.Commit(); err != nil {
if err1 := os.Rename(renamed, path); err1 != nil {
// May cause inconsistent data on disk
log.G(ctx).WithError(err1).WithField("path", renamed).Errorf("Failed to rename after failed commit")
}
return errors.Wrap(err, "failed to commit")
}
committed = true
if err := hcsshim.DestroyLayer(s.info, renamedID); err != nil {
// Must be cleaned up, any "rm-*" could be removed if no active transactions
@ -242,6 +218,7 @@ func (s *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho
return err
}
defer t.Rollback()
return storage.WalkInfo(ctx, fn)
}
@ -251,9 +228,7 @@ func (s *snapshotter) Close() error {
}
func (s *snapshotter) mounts(sn storage.Snapshot) []mount.Mount {
var (
roFlag string
)
var roFlag string
if sn.Kind == snapshots.KindView {
roFlag = "ro"
@ -288,13 +263,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
if err != nil {
return nil, err
}
var committed bool
defer func() {
if committed == false {
rollbackWithLogging(ctx, t)
}
}()
defer t.Rollback()
newSnapshot, err := storage.CreateSnapshot(ctx, kind, key, parent, opts...)
if err != nil {
@ -328,7 +297,6 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
if err := t.Commit(); err != nil {
return nil, errors.Wrap(err, "commit failed")
}
committed = true
return s.mounts(newSnapshot), nil
}
@ -343,17 +311,19 @@ func (s *snapshotter) parentIDsToParentPaths(parentIDs []string) []string {
// getFileSystemType obtains the type of a file system through GetVolumeInformation
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx
func getFileSystemType(drive string) (fsType string, hr error) {
func getFileSystemType(path string) (fsType string, hr error) {
drive := filepath.VolumeName(path)
if len(drive) != 2 {
return "", errors.New("getFileSystemType path must start with a drive letter")
}
var (
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procGetVolumeInformation = modkernel32.NewProc("GetVolumeInformationW")
buf = make([]uint16, 255)
size = windows.MAX_PATH + 1
)
if len(drive) != 1 {
return "", errors.New("getFileSystemType must be called with a drive letter")
}
drive += `:\`
drive += `\`
n := uintptr(unsafe.Pointer(nil))
r0, _, _ := syscall.Syscall9(procGetVolumeInformation.Addr(), 8, uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(drive))), n, n, n, n, n, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0)
if int32(r0) < 0 {

View File

@ -4,14 +4,12 @@ package windows
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/Microsoft/hcsshim"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@ -49,14 +47,14 @@ func newWindowsContainerConfig(ctx context.Context, owner, id string, spec *spec
}
conf.IgnoreFlushesDuringBoot = spec.Windows.IgnoreFlushesDuringBoot
if len(spec.Windows.LayerFolders) < 1 {
if len(spec.Windows.LayerFolders) < 2 {
return nil, errors.Wrap(errdefs.ErrInvalidArgument,
"spec.Windows.LayerFolders must have at least 1 layers")
"spec.Windows.LayerFolders must have at least 2 layers")
}
var (
layerFolders = spec.Windows.LayerFolders
homeDir = filepath.Dir(layerFolders[0])
layerFolderPath = filepath.Join(homeDir, id)
layerFolderPath = spec.Windows.LayerFolders[0]
layerFolders = spec.Windows.LayerFolders[1:]
layerID = filepath.Base(layerFolderPath)
)
// TODO: use the create request Mount for those
@ -71,39 +69,12 @@ func newWindowsContainerConfig(ctx context.Context, owner, id string, spec *spec
Path: layerPath,
})
}
var (
di = hcsshim.DriverInfo{
Flavour: 1, // filter driver
HomeDir: homeDir,
}
)
conf.LayerFolderPath = layerFolderPath
// TODO: Once there is a snapshotter for windows, this can be deleted.
// The R/W Layer should come from the Rootfs Mounts provided
//
// Windows doesn't support creating a container with a readonly
// filesystem, so always create a RW one
if err = hcsshim.CreateSandboxLayer(di, id, layerFolders[0], layerFolders); err != nil {
return nil, errors.Wrapf(err, "failed to create sandbox layer for %s: layers: %#v, driverInfo: %#v",
id, layerFolders, di)
var di = hcsshim.DriverInfo{
HomeDir: filepath.Dir(layerFolderPath),
}
defer func() {
if err != nil {
removeLayer(ctx, conf.LayerFolderPath)
}
}()
if err = hcsshim.ActivateLayer(di, id); err != nil {
return nil, errors.Wrapf(err, "failed to activate layer %s", conf.LayerFolderPath)
}
if err = hcsshim.PrepareLayer(di, id, layerFolders); err != nil {
return nil, errors.Wrapf(err, "failed to prepare layer %s", conf.LayerFolderPath)
}
conf.VolumePath, err = hcsshim.GetLayerMountPath(di, id)
conf.VolumePath, err = hcsshim.GetLayerMountPath(di, layerID)
if err != nil {
return nil, errors.Wrapf(err, "failed to getmount path for layer %s: driverInfo: %#v", id, di)
}
@ -146,41 +117,6 @@ func newWindowsContainerConfig(ctx context.Context, owner, id string, spec *spec
return conf, nil
}
// removeLayer deletes the given layer, all associated containers must have
// been shutdown for this to succeed.
func removeLayer(ctx context.Context, path string) error {
var (
err error
layerID = filepath.Base(path)
parentPath = filepath.Dir(path)
di = hcsshim.DriverInfo{
Flavour: 1, // filter driver
HomeDir: parentPath,
}
)
if err = hcsshim.UnprepareLayer(di, layerID); err != nil {
log.G(ctx).WithError(err).Warnf("failed to unprepare layer %s for removal", path)
}
if err = hcsshim.DeactivateLayer(di, layerID); err != nil {
log.G(ctx).WithError(err).Warnf("failed to deactivate layer %s for removal", path)
}
removePath := filepath.Join(parentPath, fmt.Sprintf("%s-removing", layerID))
if err = os.Rename(path, removePath); err != nil {
log.G(ctx).WithError(err).Warnf("failed to rename container layer %s for removal", path)
removePath = path
}
if err = hcsshim.DestroyLayer(di, removePath); err != nil {
log.G(ctx).WithError(err).Errorf("failed to remove container layer %s", removePath)
return err
}
return nil
}
func newProcessConfig(processSpec *specs.Process, pset *pipeSet) *hcsshim.ProcessConfig {
conf := &hcsshim.ProcessConfig{
EmulateConsole: pset.src.Terminal,

View File

@ -1,54 +0,0 @@
// +build windows
package windows
// TODO: remove this file (i.e. meta.go) once we have a snapshotter
import (
"github.com/boltdb/bolt"
"github.com/containerd/containerd/errdefs"
"github.com/pkg/errors"
)
func newLayerFolderStore(tx *bolt.Tx) *layerFolderStore {
return &layerFolderStore{tx}
}
type layerFolderStore struct {
tx *bolt.Tx
}
func (s *layerFolderStore) Create(id, layer string) error {
bkt, err := s.tx.CreateBucketIfNotExists([]byte(pluginID))
if err != nil {
return errors.Wrapf(err, "failed to create bucket %s", pluginID)
}
err = bkt.Put([]byte(id), []byte(layer))
if err != nil {
return errors.Wrapf(err, "failed to store entry %s:%s", id, layer)
}
return nil
}
func (s *layerFolderStore) Get(id string) (string, error) {
bkt := s.tx.Bucket([]byte(pluginID))
if bkt == nil {
return "", errors.Wrapf(errdefs.ErrNotFound, "bucket %s", pluginID)
}
return string(bkt.Get([]byte(id))), nil
}
func (s *layerFolderStore) Delete(id string) error {
bkt := s.tx.Bucket([]byte(pluginID))
if bkt == nil {
return errors.Wrapf(errdefs.ErrNotFound, "bucket %s", pluginID)
}
if err := bkt.Delete([]byte(id)); err != nil {
return errors.Wrapf(err, "failed to delete entry %s", id)
}
return nil
}

View File

@ -10,13 +10,11 @@ import (
"time"
"github.com/Microsoft/hcsshim"
"github.com/boltdb/bolt"
eventstypes "github.com/containerd/containerd/api/events"
containerdtypes "github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime"
@ -55,12 +53,6 @@ func New(ic *plugin.InitContext) (interface{}, error) {
if err := os.MkdirAll(ic.Root, 0700); err != nil {
return nil, errors.Wrapf(err, "could not create state directory at %s", ic.Root)
}
m, err := ic.Get(plugin.MetadataPlugin)
if err != nil {
return nil, err
}
r := &windowsRuntime{
root: ic.Root,
pidPool: newPidPool(),
@ -70,7 +62,6 @@ func New(ic *plugin.InitContext) (interface{}, error) {
// TODO(mlaventure): windows needs a stat monitor
monitor: nil,
tasks: runtime.NewTaskList(),
db: m.(*metadata.DB),
}
// Load our existing containers and kill/delete them. We don't support
@ -91,7 +82,6 @@ type windowsRuntime struct {
monitor runtime.TaskMonitor
tasks *runtime.TaskList
db *metadata.DB
}
func (r *windowsRuntime) ID() string {
@ -124,8 +114,14 @@ func (r *windowsRuntime) Create(ctx context.Context, id string, opts runtime.Cre
if createOpts.TerminateDuration == 0 {
createOpts.TerminateDuration = defaultTerminateDuration
}
spec.Windows.LayerFolders = append(spec.Windows.LayerFolders, opts.Rootfs[0].Source)
parentLayerPaths, err := opts.Rootfs[0].GetParentPaths()
if err != nil {
return nil, err
}
spec.Windows.LayerFolders = append(spec.Windows.LayerFolders, parentLayerPaths...)
return r.newTask(ctx, namespace, id, spec, opts.IO, createOpts)
return r.newTask(ctx, namespace, id, opts.Rootfs, spec, opts.IO, createOpts)
}
func (r *windowsRuntime) Get(ctx context.Context, id string) (runtime.Task, error) {
@ -209,14 +205,19 @@ func (r *windowsRuntime) Delete(ctx context.Context, t runtime.Task) (*runtime.E
ns, _ := namespaces.Namespace(ctx)
serviceCtx := log.WithLogger(context.Background(), log.GetLogger(ctx))
serviceCtx = namespaces.WithNamespace(serviceCtx, ns)
r.serviceTask(serviceCtx, ns, wt.id+"_servicing", wt.spec)
r.serviceTask(serviceCtx, ns, wt.id+"_servicing", wt.rootfs, wt.spec)
}
if err := mount.UnmountAll(wt.rootfs[0].Source, 0); err != nil {
log.G(ctx).WithError(err).WithField("path", wt.rootfs[0].Source).
Warn("failed to unmount rootfs on failure")
}
// We were never started, return failure
return rtExit, nil
}
func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec *specs.Spec, io runtime.IO, createOpts *hcsshimtypes.CreateOptions) (*task, error) {
func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, rootfs []mount.Mount, spec *specs.Spec, io runtime.IO, createOpts *hcsshimtypes.CreateOptions) (*task, error) {
var (
err error
pset *pipeSet
@ -241,6 +242,18 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec
}
}()
if err := mount.All(rootfs, ""); err != nil {
return nil, errors.Wrap(err, "failed to mount rootfs")
}
defer func() {
if err != nil {
if err := mount.UnmountAll(rootfs[0].Source, 0); err != nil {
log.G(ctx).WithError(err).WithField("path", rootfs[0].Source).
Warn("failed to unmount rootfs on failure")
}
}
}()
var (
conf *hcsshim.ContainerConfig
nsid = namespace + "-" + id
@ -248,31 +261,6 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec
if conf, err = newWindowsContainerConfig(ctx, hcsshimOwner, nsid, spec); err != nil {
return nil, err
}
defer func() {
if err != nil {
removeLayer(ctx, conf.LayerFolderPath)
}
}()
// TODO: remove this once we have a windows snapshotter
// Store the LayerFolder in the db so we can clean it if we die
if err = r.db.Update(func(tx *bolt.Tx) error {
s := newLayerFolderStore(tx)
return s.Create(nsid, conf.LayerFolderPath)
}); err != nil {
return nil, err
}
defer func() {
if err != nil {
if dbErr := r.db.Update(func(tx *bolt.Tx) error {
s := newLayerFolderStore(tx)
return s.Delete(nsid)
}); dbErr != nil {
log.G(ctx).WithField("id", id).
Error("failed to remove key from metadata")
}
}
}()
ctr, err := hcsshim.CreateContainer(nsid, conf)
if err != nil {
@ -301,6 +289,7 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec
hyperV: spec.Windows.HyperV != nil,
publisher: r.publisher,
rwLayer: conf.LayerFolderPath,
rootfs: rootfs,
pidPool: r.pidPool,
hcsContainer: ctr,
terminateDuration: createOpts.TerminateDuration,
@ -312,14 +301,6 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec
}
r.tasks.Add(ctx, t)
var rootfs []*containerdtypes.Mount
for _, l := range append([]string{t.rwLayer}, spec.Windows.LayerFolders...) {
rootfs = append(rootfs, &containerdtypes.Mount{
Type: "windows-layer",
Source: l,
})
}
r.publisher.Publish(ctx,
runtime.TaskCreateEventTopic,
&eventstypes.TaskCreate{
@ -331,7 +312,7 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec
Terminal: io.Terminal,
},
Pid: t.pid,
Rootfs: rootfs,
//???Rootfs: rootfs,
// TODO: what should be in Bundle for windows?
})
@ -360,34 +341,10 @@ func (r *windowsRuntime) cleanup(ctx context.Context) {
container.Wait()
}
container.Close()
// TODO: remove this once we have a windows snapshotter
var layerFolderPath string
if err := r.db.View(func(tx *bolt.Tx) error {
s := newLayerFolderStore(tx)
l, e := s.Get(p.ID)
if err == nil {
layerFolderPath = l
}
return e
}); err == nil && layerFolderPath != "" {
removeLayer(ctx, layerFolderPath)
if dbErr := r.db.Update(func(tx *bolt.Tx) error {
s := newLayerFolderStore(tx)
return s.Delete(p.ID)
}); dbErr != nil {
log.G(ctx).WithField("id", p.ID).
Error("failed to remove key from metadata")
}
} else {
log.G(ctx).WithField("id", p.ID).
Debug("key not found in metadata, R/W layer may be leaked")
}
}
}
func (r *windowsRuntime) serviceTask(ctx context.Context, namespace, id string, spec *specs.Spec) {
func (r *windowsRuntime) serviceTask(ctx context.Context, namespace, id string, rootfs []mount.Mount, spec *specs.Spec) {
var (
err error
t *task
@ -397,7 +354,7 @@ func (r *windowsRuntime) serviceTask(ctx context.Context, namespace, id string,
}
)
t, err = r.newTask(ctx, namespace, id, spec, io, createOpts)
t, err = r.newTask(ctx, namespace, id, rootfs, spec, io, createOpts)
if err != nil {
log.G(ctx).WithError(err).WithField("id", id).
Warn("failed to created servicing task")

View File

@ -11,6 +11,7 @@ import (
eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/windows/hcsshimtypes"
"github.com/containerd/typeurl"
@ -33,6 +34,7 @@ type task struct {
publisher events.Publisher
rwLayer string
rootfs []mount.Mount
pidPool *pidPool
hcsContainer hcsshim.Container
@ -406,6 +408,5 @@ func (t *task) cleanup() {
for _, p := range t.processes {
t.removeProcessNL(p.id)
}
removeLayer(context.Background(), t.rwLayer)
t.Unlock()
}