oci: introduce WithSpecFromFile combinator

We introduce a WithSpecFromFile option combinator to allow creation
simpler creation of OCI specs from a file name. Often used as the first
option in a `SpecOpts` slice, it simplifies choosing between a local
file and the built-in default.

The code in `ctr run` has been updated to use the new option, with out
changing the order of operations or functionality present there.

Signed-off-by: Stephen Day <stephen.day@getcruise.com>
This commit is contained in:
Stephen Day
2018-07-19 12:38:00 -07:00
parent c8017d0275
commit 2a1bd7414b
9 changed files with 162 additions and 44 deletions

View File

@@ -19,9 +19,7 @@ package run
import (
gocontext "context"
"encoding/csv"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/containerd/console"
@@ -37,17 +35,6 @@ import (
"github.com/urfave/cli"
)
func loadSpec(path string, s *specs.Spec) error {
raw, err := ioutil.ReadFile(path)
if err != nil {
return errors.New("cannot load spec config file")
}
if err := json.Unmarshal(raw, s); err != nil {
return errors.Errorf("decoding spec config file failed, current supported OCI runtime-spec : v%s", specs.Version)
}
return nil
}
func withMounts(context *cli.Context) oci.SpecOpts {
return func(ctx gocontext.Context, client oci.Client, container *containers.Container, s *specs.Spec) error {
mounts := make([]specs.Mount, 0)

View File

@@ -52,6 +52,13 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
cOpts []containerd.NewContainerOpts
spec containerd.NewContainerOpts
)
if context.IsSet("config") {
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
} else {
opts = append(opts, oci.WithDefaultSpec())
}
opts = append(opts, oci.WithEnv(context.StringSlice("env")))
opts = append(opts, withMounts(context))
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
@@ -117,15 +124,10 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
if context.IsSet("gpus") {
opts = append(opts, nvidia.WithGPUs(nvidia.WithDevices(context.Int("gpus")), nvidia.WithAllCapabilities))
}
if context.IsSet("config") {
var s specs.Spec
if err := loadSpec(context.String("config"), &s); err != nil {
return nil, err
}
spec = containerd.WithSpec(&s, opts...)
} else {
spec = containerd.WithNewSpec(opts...)
}
var s specs.Spec
spec = containerd.WithSpec(&s, opts...)
cOpts = append(cOpts, spec)
// oci.WithImageConfig (WithUsername, WithUserID) depends on rootfs snapshot for resolving /etc/passwd.

View File

@@ -63,6 +63,13 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
cOpts []containerd.NewContainerOpts
spec containerd.NewContainerOpts
)
if context.IsSet("config") {
opts = append(opts, oci.WithSpecFromFile(context.String("config")))
} else {
opts = append(opts, oci.WithDefaultSpec())
}
opts = append(opts, oci.WithImageConfig(image))
opts = append(opts, oci.WithEnv(context.StringSlice("env")))
opts = append(opts, withMounts(context))
@@ -74,15 +81,8 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
opts = append(opts, oci.WithProcessCwd(cwd))
}
if context.IsSet("config") {
var s specs.Spec
if err := loadSpec(context.String("config"), &s); err != nil {
return nil, err
}
spec = containerd.WithSpec(&s, opts...)
} else {
spec = containerd.WithNewSpec(opts...)
}
var s specs.Spec
spec = containerd.WithSpec(&s, opts...)
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
cOpts = append(cOpts, containerd.WithImage(image))