From 2ddbb2db058b2576e5be3ee83ee2111b73661204 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM)" Date: Fri, 28 Sep 2018 15:02:10 -0700 Subject: [PATCH] Handle shim delete workdir on Windows Signed-off-by: Justin Terry (VM) --- runtime/v2/binary.go | 19 ++++++++++++++++++- runtime/v2/runhcs/service.go | 19 ++++++++++++++----- runtime/v2/shim/shim.go | 7 +++++-- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/runtime/v2/binary.go b/runtime/v2/binary.go index a27289369..034c266a3 100644 --- a/runtime/v2/binary.go +++ b/runtime/v2/binary.go @@ -21,6 +21,7 @@ import ( "context" "io" "os" + gruntime "runtime" "strings" eventstypes "github.com/containerd/containerd/api/events" @@ -109,7 +110,23 @@ func (b *binary) Start(ctx context.Context) (_ *shim, err error) { func (b *binary) Delete(ctx context.Context) (*runtime.Exit, error) { log.G(ctx).Info("cleaning up dead shim") - cmd, err := client.Command(ctx, b.runtime, b.containerdAddress, b.bundle.Path, "-id", b.bundle.ID, "delete") + var bundlePath string + if gruntime.GOOS == "windows" { + // Windows cannot delete the current working directory while an + // executable is in use with it. For the cleanup case we invoke with the + // deafult work dir and forward the bundle path on the cmdline. + bundlePath = "" + } else { + bundlePath = b.bundle.Path + } + + cmd, err := client.Command(ctx, + b.runtime, + b.containerdAddress, + bundlePath, + "-id", b.bundle.ID, + "-bundle", b.bundle.Path, + "delete") if err != nil { return nil, err } diff --git a/runtime/v2/runhcs/service.go b/runtime/v2/runhcs/service.go index c5d92edaf..192687ef8 100644 --- a/runtime/v2/runhcs/service.go +++ b/runtime/v2/runhcs/service.go @@ -195,13 +195,22 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) if err != nil { return nil, err } - path, err := os.Getwd() - if err != nil { - return nil, err + // Forcibly shut down any container in this bundle + rhcs := newRunhcs("") + dopts := &runhcs.DeleteOpts{ + Force: true, } - if err := os.RemoveAll(path); err != nil { - return nil, err + if err := rhcs.Delete(ctx, s.id, dopts); err != nil { + log.G(ctx).WithError(err).Debugf("failed to delete container") } + + opts, ok := ctx.Value(shim.OptsKey{}).(shim.Opts) + if ok && opts.BundlePath != "" { + if err := os.RemoveAll(opts.BundlePath); err != nil { + return nil, err + } + } + return &taskAPI.DeleteResponse{ ExitedAt: time.Now(), ExitStatus: 255, diff --git a/runtime/v2/shim/shim.go b/runtime/v2/shim/shim.go index f2ebf7e1e..39484c191 100644 --- a/runtime/v2/shim/shim.go +++ b/runtime/v2/shim/shim.go @@ -58,7 +58,8 @@ type OptsKey struct{} // Opts are context options associated with the shim invocation. type Opts struct { - Debug bool + BundlePath string + Debug bool } var ( @@ -66,6 +67,7 @@ var ( idFlag string namespaceFlag string socketFlag string + bundlePath string addressFlag string containerdBinaryFlag string action string @@ -76,6 +78,7 @@ func parseFlags() { flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") flag.StringVar(&idFlag, "id", "", "id of the task") flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve") + flag.StringVar(&bundlePath, "bundle", "", "path to the bundle if not workdir") flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd") flag.StringVar(&containerdBinaryFlag, "publish-binary", "containerd", "path to publish binary (used for publishing events)") @@ -141,7 +144,7 @@ func run(id string, initFunc Init) error { return fmt.Errorf("shim namespace cannot be empty") } ctx := namespaces.WithNamespace(context.Background(), namespaceFlag) - ctx = context.WithValue(ctx, OptsKey{}, Opts{Debug: debugFlag}) + ctx = context.WithValue(ctx, OptsKey{}, Opts{BundlePath: bundlePath, Debug: debugFlag}) ctx = log.WithLogger(ctx, log.G(ctx).WithField("runtime", id)) service, err := initFunc(ctx, idFlag, publisher)