From f1a469a03578b061af0991228fdd3171a75fc2c8 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Wed, 17 Jun 2020 19:02:56 +0900 Subject: [PATCH] shim v2 runc: propagate options.Root to Cleanup Previously shim v2 (`io.containerd.runc.{v1,v2}`) always used `/run/containerd/runc` as the runc root. Fix #4326 Signed-off-by: Akihiro Suda --- runtime/v2/runc/container.go | 38 +++++++++++++++++++++++++++++++++++ runtime/v2/runc/v1/service.go | 11 +++++++++- runtime/v2/runc/v2/service.go | 11 +++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/runtime/v2/runc/container.go b/runtime/v2/runc/container.go index dd6bb4374..27d434a29 100644 --- a/runtime/v2/runc/container.go +++ b/runtime/v2/runc/container.go @@ -20,6 +20,7 @@ package runc import ( "context" + "encoding/json" "io/ioutil" "os" "path/filepath" @@ -88,6 +89,10 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa Options: r.Options, } + if err := WriteOptions(r.Bundle, opts); err != nil { + return nil, err + } + // For historical reason, we write opts.BinaryName as well as the entire opts if err := WriteRuntime(r.Bundle, opts.BinaryName); err != nil { return nil, err } @@ -156,6 +161,39 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa return container, nil } +const optionsFilename = "options.json" + +// ReadOptions reads the option information from the path. +// When the file does not exist, ReadOptions returns nil without an error. +func ReadOptions(path string) (*options.Options, error) { + filePath := filepath.Join(path, optionsFilename) + if _, err := os.Stat(filePath); err != nil { + if os.IsNotExist(err) { + return nil, nil + } + return nil, err + } + + data, err := ioutil.ReadFile(filePath) + if err != nil { + return nil, err + } + var opts options.Options + if err := json.Unmarshal(data, &opts); err != nil { + return nil, err + } + return &opts, nil +} + +// WriteOptions writes the options information into the path +func WriteOptions(path string, opts options.Options) error { + data, err := json.Marshal(opts) + if err != nil { + return err + } + return ioutil.WriteFile(filepath.Join(path, optionsFilename), data, 0600) +} + // ReadRuntime reads the runtime information from the path func ReadRuntime(path string) (string, error) { data, err := ioutil.ReadFile(filepath.Join(path, "runtime")) diff --git a/runtime/v2/runc/v1/service.go b/runtime/v2/runc/v1/service.go index 151bdaba0..e8ef09c8e 100644 --- a/runtime/v2/runc/v1/service.go +++ b/runtime/v2/runc/v1/service.go @@ -208,7 +208,16 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) if err != nil { return nil, err } - r := process.NewRunc(process.RuncRoot, path, ns, runtime, "", false) + opts, err := runc.ReadOptions(path) + if err != nil { + return nil, err + } + root := process.RuncRoot + if opts != nil && opts.Root != "" { + root = opts.Root + } + + r := process.NewRunc(root, path, ns, runtime, "", false) if err := r.Delete(ctx, s.id, &runcC.DeleteOpts{ Force: true, }); err != nil { diff --git a/runtime/v2/runc/v2/service.go b/runtime/v2/runc/v2/service.go index 7b4e89b86..52b178a20 100644 --- a/runtime/v2/runc/v2/service.go +++ b/runtime/v2/runc/v2/service.go @@ -277,7 +277,16 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) if err != nil { return nil, err } - r := process.NewRunc(process.RuncRoot, path, ns, runtime, "", false) + opts, err := runc.ReadOptions(path) + if err != nil { + return nil, err + } + root := process.RuncRoot + if opts != nil && opts.Root != "" { + root = opts.Root + } + + r := process.NewRunc(root, path, ns, runtime, "", false) if err := r.Delete(ctx, s.id, &runcC.DeleteOpts{ Force: true, }); err != nil {