From 51b72d856da09457ff9f3f68fd3aa56a1b221999 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 5 Oct 2017 14:52:21 -0400 Subject: [PATCH 1/4] Add kpod create skeleton with flags. Stripped options parsing because it wouldn't compile anymore. Signed-off-by: Matthew Heon --- cmd/kpod/create.go | 192 +++++++++++++++++++++++++++++++++++++++++++++ cmd/kpod/main.go | 1 + 2 files changed, 193 insertions(+) create mode 100644 cmd/kpod/create.go diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go new file mode 100644 index 00000000..2197ec32 --- /dev/null +++ b/cmd/kpod/create.go @@ -0,0 +1,192 @@ +package main + +import ( + "github.com/pkg/errors" + "github.com/urfave/cli" + pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" +) + +// TODO: Missing flags from docker-create - particularly --security-opt or equiv and resource limit flags +// TODO stop using Kubernetes API structs here - replace with our own versions (remove pb import entirely) +// TODO Add missing flags from docker-create +// TODO parse flags into a createConfig, and parse createConfig into an OCI runtime spec + +// TODO These temporary values should be replaced with sane defaults +const ( + defaultHostname = "kpod-launch" + defaultCgroupParent = "/kpod-launch" +) + +type createConfig struct { + image string + command string + args []string + pod string + privileged bool + rm bool + hostNet bool + hostPID bool + hostIPC bool + name string + labels map[string]string + workDir string + env map[string]string + detach bool + stdin bool + tty bool + devices []*pb.Device + mounts []*pb.Mount + capAdd []string + capDrop []string + dnsServers []string + dnsSearch []string + dnsOpt []string + ports []*pb.PortMapping + hostname string + cgroupParent string + sysctl string + user int64 + additionalGroups []int64 + readOnlyRootfs bool +} + +var createFlags = []cli.Flag{ + cli.StringFlag{ + Name: "pod", + Usage: "Run container in an existing pod", + }, + cli.BoolFlag{ + Name: "privileged", + Usage: "Run a privileged container", + }, + cli.BoolFlag{ + Name: "rm", + Usage: "Remove container (and pod if created) after exit", + }, + cli.StringFlag{ + Name: "network", + Usage: "Use `host` network namespace", + }, + cli.StringFlag{ + Name: "pid", + Usage: "Use `host` PID namespace", + }, + cli.StringFlag{ + Name: "ipc", + Usage: "Use `host` IPC namespace", + }, + cli.StringFlag{ + Name: "name", + Usage: "Assign a name to the container", + }, + cli.StringSliceFlag{ + Name: "label", + Usage: "Set label metadata on container", + }, + cli.StringFlag{ + Name: "workdir, w", + Usage: "Set working `directory` of container", + Value: "/", + }, + cli.StringSliceFlag{ + Name: "env, e", + Usage: "Set environment variables in container", + }, + cli.BoolFlag{ + Name: "detach, d", + Usage: "Start container detached", + }, + cli.BoolFlag{ + Name: "interactive, i", + Usage: "Keep STDIN open even if deatched", + }, + cli.BoolFlag{ + Name: "tty, t", + Usage: "Allocate a TTY for container", + }, + cli.StringSliceFlag{ + Name: "device", + Usage: "Mount devices into the container", + }, + cli.StringSliceFlag{ + Name: "volume, v", + Usage: "Mount volumes into the container", + }, + cli.StringSliceFlag{ + Name: "cap-add", + Usage: "Add capabilities to the container", + }, + cli.StringSliceFlag{ + Name: "cap-drop", + Usage: "Drop capabilities from the container", + }, + cli.StringSliceFlag{ + Name: "dns", + Usage: "Set custom DNS servers. Conflicts with --pod", + }, + cli.StringSliceFlag{ + Name: "dns-search", + Usage: "Set custom DNS search domains. Conflicts with --pod", + }, + cli.StringSliceFlag{ + Name: "dns-opt", + Usage: "Set custom DNS options. Conflicts with --pod", + }, + cli.StringSliceFlag{ + Name: "expose", + Usage: "Expose a port. Conflicts with --pod", + }, + cli.StringFlag{ + Name: "hostname, h", + Usage: "Set hostname. Conflicts with --pod", + Value: defaultHostname, + }, + cli.StringFlag{ + Name: "cgroup-parent", + Usage: "Set CGroup parent. Conflicts with --pod", + Value: defaultCgroupParent, + }, + cli.StringFlag{ + Name: "sysctl", + Usage: "Set namespaces SYSCTL. Conflicts with --pod", + }, + cli.StringFlag{ + Name: "user, u", + Usage: "Specify user to run as. Conflicts with --pod", + }, + cli.StringFlag{ + Name: "group-add", + Usage: "Specify additional groups to run as. Conflicts with --pod", + }, + cli.BoolFlag{ + Name: "read-only", + Usage: "Make root filesystem read-only. Conflicts with --pod", + }, +} + +var createCommand = cli.Command{ + Name: "create", + Usage: "create but do not start a container", + Description: `Create a new container from specified image, but do not start it`, + Flags: createFlags, + Action: createCmd, + ArgsUsage: "IMAGE [COMMAND [ARG...]]", +} + +func createCmd(c *cli.Context) error { + // TODO should allow user to create based off a directory on the host not just image + // Need CLI support for this + if len(c.Args()) != 1 { + return errors.Errorf("must specify name of image to create from") + } + if err := validateFlags(c, createFlags); err != nil { + return err + } + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "error creating libpod runtime") + } + _ = runtime.GetConfig() + + return errors.Errorf("NOT IMPLEMENTED") +} diff --git a/cmd/kpod/main.go b/cmd/kpod/main.go index 804f762a..6f19198e 100644 --- a/cmd/kpod/main.go +++ b/cmd/kpod/main.go @@ -31,6 +31,7 @@ func main() { app.Version = v app.Commands = []cli.Command{ + createCommand, diffCommand, exportCommand, historyCommand, From 65542ee3223097cf017a7c768da635a85d681f09 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 5 Oct 2017 15:12:16 -0400 Subject: [PATCH 2/4] Remove now-unnecessary "conflicts with" language from create opts Signed-off-by: Matthew Heon --- cmd/kpod/create.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go index 2197ec32..0f2b8477 100644 --- a/cmd/kpod/create.go +++ b/cmd/kpod/create.go @@ -122,45 +122,45 @@ var createFlags = []cli.Flag{ }, cli.StringSliceFlag{ Name: "dns", - Usage: "Set custom DNS servers. Conflicts with --pod", + Usage: "Set custom DNS servers", }, cli.StringSliceFlag{ Name: "dns-search", - Usage: "Set custom DNS search domains. Conflicts with --pod", + Usage: "Set custom DNS search domains", }, cli.StringSliceFlag{ Name: "dns-opt", - Usage: "Set custom DNS options. Conflicts with --pod", + Usage: "Set custom DNS options", }, cli.StringSliceFlag{ Name: "expose", - Usage: "Expose a port. Conflicts with --pod", + Usage: "Expose a port", }, cli.StringFlag{ Name: "hostname, h", - Usage: "Set hostname. Conflicts with --pod", + Usage: "Set hostname", Value: defaultHostname, }, cli.StringFlag{ Name: "cgroup-parent", - Usage: "Set CGroup parent. Conflicts with --pod", + Usage: "Set CGroup parent", Value: defaultCgroupParent, }, cli.StringFlag{ Name: "sysctl", - Usage: "Set namespaces SYSCTL. Conflicts with --pod", + Usage: "Set namespaced SYSCTLs", }, cli.StringFlag{ Name: "user, u", - Usage: "Specify user to run as. Conflicts with --pod", + Usage: "Specify user to run as", }, cli.StringFlag{ Name: "group-add", - Usage: "Specify additional groups to run as. Conflicts with --pod", + Usage: "Specify additional groups to run as", }, cli.BoolFlag{ Name: "read-only", - Usage: "Make root filesystem read-only. Conflicts with --pod", + Usage: "Make root filesystem read-only", }, } From 899f672ee97c447c0cd293e8f2b1af9ab961c74e Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 5 Oct 2017 17:40:16 -0400 Subject: [PATCH 3/4] Further add to skeleton to make lint happy Signed-off-by: Matthew Heon --- cmd/kpod/create.go | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go index 0f2b8477..de71e31b 100644 --- a/cmd/kpod/create.go +++ b/cmd/kpod/create.go @@ -1,6 +1,9 @@ package main import ( + "fmt" + + spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/urfave/cli" pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" @@ -186,7 +189,36 @@ func createCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - _ = runtime.GetConfig() - return errors.Errorf("NOT IMPLEMENTED") + createConfig, err := parseCreateOpts(c) + if err != nil { + return err + } + + runtimeSpec, err := createConfigToOCISpec(createConfig) + if err != nil { + return err + } + + ctr, err := runtime.NewContainer(runtimeSpec) + if err != nil { + return err + } + + // Should we also call ctr.Create() to make the container in runc? + + fmt.Printf("%s\n", ctr.ID()) + + return nil +} + +// Parses CLI options related to container creation into a config which can be +// parsed into an OCI runtime spec +func parseCreateOpts(c *cli.Context) (*createConfig, error) { + return nil, errors.Errorf("NOT IMPLEMENTED") +} + +// Parses information needed to create a container into an OCI runtime spec +func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { + return nil, errors.Errorf("NOT IMPLEMENTED") } From 45808ca998fbfc5e91d47ded399bad537515b51b Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Fri, 6 Oct 2017 10:43:05 -0400 Subject: [PATCH 4/4] Alphabetize kpod create flags and move them into common.go Create flags will be shared with run, so they should be in a common file. Signed-off-by: Matthew Heon --- cmd/kpod/common.go | 116 +++++++++++++++++++++++++++++++++++++++++++ cmd/kpod/create.go | 120 +++------------------------------------------ 2 files changed, 122 insertions(+), 114 deletions(-) diff --git a/cmd/kpod/common.go b/cmd/kpod/common.go index f77b3fd1..0cd11065 100644 --- a/cmd/kpod/common.go +++ b/cmd/kpod/common.go @@ -133,3 +133,119 @@ func validateFlags(c *cli.Context, flags []cli.Flag) error { } return nil } + +// Common flags shared between commands +var createFlags = []cli.Flag{ + cli.StringSliceFlag{ + Name: "cap-add", + Usage: "Add capabilities to the container", + }, + cli.StringSliceFlag{ + Name: "cap-drop", + Usage: "Drop capabilities from the container", + }, + cli.StringFlag{ + Name: "cgroup-parent", + Usage: "Set CGroup parent", + Value: defaultCgroupParent, + }, + cli.BoolFlag{ + Name: "detach, d", + Usage: "Start container detached", + }, + cli.StringSliceFlag{ + Name: "device", + Usage: "Mount devices into the container", + }, + cli.StringSliceFlag{ + Name: "dns", + Usage: "Set custom DNS servers", + }, + cli.StringSliceFlag{ + Name: "dns-opt", + Usage: "Set custom DNS options", + }, + cli.StringSliceFlag{ + Name: "dns-search", + Usage: "Set custom DNS search domains", + }, + cli.StringSliceFlag{ + Name: "env, e", + Usage: "Set environment variables in container", + }, + cli.StringSliceFlag{ + Name: "expose", + Usage: "Expose a port", + }, + cli.StringFlag{ + Name: "group-add", + Usage: "Specify additional groups to run as", + }, + cli.StringFlag{ + Name: "hostname, h", + Usage: "Set hostname", + Value: defaultHostname, + }, + cli.BoolFlag{ + Name: "interactive, i", + Usage: "Keep STDIN open even if deatched", + }, + cli.StringFlag{ + Name: "ipc", + Usage: "Use `host` IPC namespace", + }, + cli.StringSliceFlag{ + Name: "label", + Usage: "Set label metadata on container", + }, + cli.StringFlag{ + Name: "name", + Usage: "Assign a name to the container", + }, + cli.StringFlag{ + Name: "network", + Usage: "Use `host` network namespace", + }, + cli.StringFlag{ + Name: "pid", + Usage: "Use `host` PID namespace", + }, + cli.StringFlag{ + Name: "pod", + Usage: "Run container in an existing pod", + }, + cli.BoolFlag{ + Name: "privileged", + Usage: "Run a privileged container", + }, + cli.BoolFlag{ + Name: "read-only", + Usage: "Make root filesystem read-only", + }, + cli.BoolFlag{ + Name: "rm", + Usage: "Remove container (and pod if created) after exit", + }, + cli.StringFlag{ + Name: "sysctl", + Usage: "Set namespaced SYSCTLs", + }, + cli.BoolFlag{ + Name: "tty, t", + Usage: "Allocate a TTY for container", + }, + cli.StringFlag{ + Name: "user, u", + Usage: "Specify user to run as", + }, + + cli.StringSliceFlag{ + Name: "volume, v", + Usage: "Mount volumes into the container", + }, + cli.StringFlag{ + Name: "workdir, w", + Usage: "Set working `directory` of container", + Value: "/", + }, +} diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go index de71e31b..12e3b465 100644 --- a/cmd/kpod/create.go +++ b/cmd/kpod/create.go @@ -53,124 +53,16 @@ type createConfig struct { readOnlyRootfs bool } -var createFlags = []cli.Flag{ - cli.StringFlag{ - Name: "pod", - Usage: "Run container in an existing pod", - }, - cli.BoolFlag{ - Name: "privileged", - Usage: "Run a privileged container", - }, - cli.BoolFlag{ - Name: "rm", - Usage: "Remove container (and pod if created) after exit", - }, - cli.StringFlag{ - Name: "network", - Usage: "Use `host` network namespace", - }, - cli.StringFlag{ - Name: "pid", - Usage: "Use `host` PID namespace", - }, - cli.StringFlag{ - Name: "ipc", - Usage: "Use `host` IPC namespace", - }, - cli.StringFlag{ - Name: "name", - Usage: "Assign a name to the container", - }, - cli.StringSliceFlag{ - Name: "label", - Usage: "Set label metadata on container", - }, - cli.StringFlag{ - Name: "workdir, w", - Usage: "Set working `directory` of container", - Value: "/", - }, - cli.StringSliceFlag{ - Name: "env, e", - Usage: "Set environment variables in container", - }, - cli.BoolFlag{ - Name: "detach, d", - Usage: "Start container detached", - }, - cli.BoolFlag{ - Name: "interactive, i", - Usage: "Keep STDIN open even if deatched", - }, - cli.BoolFlag{ - Name: "tty, t", - Usage: "Allocate a TTY for container", - }, - cli.StringSliceFlag{ - Name: "device", - Usage: "Mount devices into the container", - }, - cli.StringSliceFlag{ - Name: "volume, v", - Usage: "Mount volumes into the container", - }, - cli.StringSliceFlag{ - Name: "cap-add", - Usage: "Add capabilities to the container", - }, - cli.StringSliceFlag{ - Name: "cap-drop", - Usage: "Drop capabilities from the container", - }, - cli.StringSliceFlag{ - Name: "dns", - Usage: "Set custom DNS servers", - }, - cli.StringSliceFlag{ - Name: "dns-search", - Usage: "Set custom DNS search domains", - }, - cli.StringSliceFlag{ - Name: "dns-opt", - Usage: "Set custom DNS options", - }, - cli.StringSliceFlag{ - Name: "expose", - Usage: "Expose a port", - }, - cli.StringFlag{ - Name: "hostname, h", - Usage: "Set hostname", - Value: defaultHostname, - }, - cli.StringFlag{ - Name: "cgroup-parent", - Usage: "Set CGroup parent", - Value: defaultCgroupParent, - }, - cli.StringFlag{ - Name: "sysctl", - Usage: "Set namespaced SYSCTLs", - }, - cli.StringFlag{ - Name: "user, u", - Usage: "Specify user to run as", - }, - cli.StringFlag{ - Name: "group-add", - Usage: "Specify additional groups to run as", - }, - cli.BoolFlag{ - Name: "read-only", - Usage: "Make root filesystem read-only", - }, -} +var createDescription = "Creates a new container from the given image or" + + " storage and prepares it for running the specified command. The" + + " container ID is then printed to stdout. You can then start it at" + + " any time with the kpod start command. The container" + + " will be created with the initial state 'created'." var createCommand = cli.Command{ Name: "create", Usage: "create but do not start a container", - Description: `Create a new container from specified image, but do not start it`, + Description: createDescription, Flags: createFlags, Action: createCmd, ArgsUsage: "IMAGE [COMMAND [ARG...]]",