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 {