diff --git a/cmd/ctr/commands/run/run_windows.go b/cmd/ctr/commands/run/run_windows.go index c33f2302b..82fca433a 100644 --- a/cmd/ctr/commands/run/run_windows.go +++ b/cmd/ctr/commands/run/run_windows.go @@ -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() - id = context.Args().Get(1) - args = context.Args()[2:] - tty = context.Bool("tty") - labelStrings = context.StringSlice("label") + ref = context.Args().First() + id = context.Args().Get(1) + args = context.Args()[2:] ) - 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 { diff --git a/diff/windows/windows.go b/diff/windows/windows.go index 16bffca1e..b288027c9 100644 --- a/diff/windows/windows.go +++ b/diff/windows/windows.go @@ -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 { diff --git a/mount/mount_windows.go b/mount/mount_windows.go index df25ea2a8..6d37fda2a 100644 --- a/mount/mount_windows.go +++ b/mount/mount_windows.go @@ -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{ - HomeDir: home, - } + 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) diff --git a/snapshots/windows/utilities.go b/snapshots/windows/utilities.go deleted file mode 100644 index 1854df66c..000000000 --- a/snapshots/windows/utilities.go +++ /dev/null @@ -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") - } -} diff --git a/snapshots/windows/windows.go b/snapshots/windows/windows.go index be859baa2..3d0951300 100644 --- a/snapshots/windows/windows.go +++ b/snapshots/windows/windows.go @@ -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 { diff --git a/windows/hcsshim.go b/windows/hcsshim.go index 7801da749..8d9501361 100644 --- a/windows/hcsshim.go +++ b/windows/hcsshim.go @@ -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, diff --git a/windows/meta.go b/windows/meta.go deleted file mode 100644 index 81ab9245e..000000000 --- a/windows/meta.go +++ /dev/null @@ -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 -} diff --git a/windows/runtime.go b/windows/runtime.go index fd26b270c..11423b31b 100644 --- a/windows/runtime.go +++ b/windows/runtime.go @@ -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{ @@ -330,8 +311,8 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, spec Stderr: io.Stderr, Terminal: io.Terminal, }, - Pid: t.pid, - Rootfs: rootfs, + Pid: t.pid, + //???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") diff --git a/windows/task.go b/windows/task.go index 89bce1694..950f2e966 100644 --- a/windows/task.go +++ b/windows/task.go @@ -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() }