summaryrefslogtreecommitdiff
path: root/cmd/kpod
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/kpod')
-rw-r--r--cmd/kpod/create.go15
-rw-r--r--cmd/kpod/exec.go86
-rw-r--r--cmd/kpod/history.go13
-rw-r--r--cmd/kpod/images.go13
-rw-r--r--cmd/kpod/main.go2
-rw-r--r--cmd/kpod/ps.go150
-rw-r--r--cmd/kpod/rename.go49
-rw-r--r--cmd/kpod/rm.go9
-rw-r--r--cmd/kpod/rmi.go1
-rw-r--r--cmd/kpod/run.go15
-rw-r--r--cmd/kpod/spec.go34
-rw-r--r--cmd/kpod/spec_test.go2
-rw-r--r--cmd/kpod/start.go13
13 files changed, 163 insertions, 239 deletions
diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go
index 9e810af6e..1b340f96d 100644
--- a/cmd/kpod/create.go
+++ b/cmd/kpod/create.go
@@ -131,13 +131,14 @@ var createDescription = "Creates a new container from the given image or" +
" will be created with the initial state 'created'."
var createCommand = cli.Command{
- Name: "create",
- Usage: "create but do not start a container",
- Description: createDescription,
- Flags: createFlags,
- Action: createCmd,
- ArgsUsage: "IMAGE [COMMAND [ARG...]]",
- SkipArgReorder: true,
+ Name: "create",
+ Usage: "create but do not start a container",
+ Description: createDescription,
+ Flags: createFlags,
+ Action: createCmd,
+ ArgsUsage: "IMAGE [COMMAND [ARG...]]",
+ SkipArgReorder: true,
+ UseShortOptionHandling: true,
}
func createCmd(c *cli.Context) error {
diff --git a/cmd/kpod/exec.go b/cmd/kpod/exec.go
new file mode 100644
index 000000000..f76983810
--- /dev/null
+++ b/cmd/kpod/exec.go
@@ -0,0 +1,86 @@
+package main
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/pkg/errors"
+ "github.com/projectatomic/libpod/libpod"
+ "github.com/urfave/cli"
+)
+
+var (
+ execFlags = []cli.Flag{
+ cli.StringSliceFlag{
+ Name: "env, e",
+ Usage: "Set environment variables",
+ },
+ cli.BoolFlag{
+ Name: "privileged",
+ Usage: "Give the process extended Linux capabilities inside the container. The default is false",
+ },
+ cli.BoolFlag{
+ Name: "tty, t",
+ Usage: "Allocate a pseudo-TTY. The default is false",
+ },
+ cli.StringFlag{
+ Name: "user, u",
+ Usage: "Sets the username or UID used and optionally the groupname or GID for the specified command",
+ },
+ }
+ execDescription = `
+ kpod exec
+
+ Run a command in a running container
+`
+
+ execCommand = cli.Command{
+ Name: "exec",
+ Usage: "Run a process in a running container",
+ Description: execDescription,
+ Flags: execFlags,
+ Action: execCmd,
+ ArgsUsage: "CONTAINER-NAME",
+ }
+)
+
+func execCmd(c *cli.Context) error {
+ var envs []string
+ args := c.Args()
+ if len(args) < 1 {
+ return errors.Errorf("you must provide one container name or id")
+ }
+ if len(args) < 2 {
+ return errors.Errorf("you must provide a command to exec")
+ }
+ cmd := args[1:]
+ runtime, err := getRuntime(c)
+ if err != nil {
+ return errors.Wrapf(err, "error creating libpod runtime")
+ }
+ defer runtime.Shutdown(false)
+
+ ctr, err := runtime.LookupContainer(args[0])
+ if err != nil {
+ return errors.Wrapf(err, "unable to exec into %s", args[0])
+ }
+ // Create a list of keys provided by the user
+ var userEnvKeys []string
+ for _, env := range c.StringSlice("env") {
+ splitEnv := strings.Split(env, "=")
+ userEnvKeys = append(userEnvKeys, splitEnv[0])
+ }
+
+ envs = append(envs, c.StringSlice("env")...)
+
+ // if the default key isnt in the user-provided list, add the default
+ // key and value to the environment variables. this is needed to set
+ // PATH for example.
+ for k, v := range defaultEnvVariables {
+ if !libpod.StringInSlice(k, userEnvKeys) {
+ envs = append(envs, fmt.Sprintf("%s=%s", k, v))
+ }
+ }
+
+ return ctr.Exec(c.Bool("tty"), c.Bool("privileged"), envs, cmd, c.String("user"))
+}
diff --git a/cmd/kpod/history.go b/cmd/kpod/history.go
index eba5b8b35..211a843d0 100644
--- a/cmd/kpod/history.go
+++ b/cmd/kpod/history.go
@@ -71,12 +71,13 @@ var (
historyDescription = "Displays the history of an image. The information can be printed out in an easy to read, " +
"or user specified format, and can be truncated."
historyCommand = cli.Command{
- Name: "history",
- Usage: "Show history of a specified image",
- Description: historyDescription,
- Flags: historyFlags,
- Action: historyCmd,
- ArgsUsage: "",
+ Name: "history",
+ Usage: "Show history of a specified image",
+ Description: historyDescription,
+ Flags: historyFlags,
+ Action: historyCmd,
+ ArgsUsage: "",
+ UseShortOptionHandling: true,
}
)
diff --git a/cmd/kpod/images.go b/cmd/kpod/images.go
index 71bc877c9..7b020c984 100644
--- a/cmd/kpod/images.go
+++ b/cmd/kpod/images.go
@@ -72,12 +72,13 @@ var (
imagesDescription = "lists locally stored images."
imagesCommand = cli.Command{
- Name: "images",
- Usage: "list images in local storage",
- Description: imagesDescription,
- Flags: imagesFlags,
- Action: imagesCmd,
- ArgsUsage: "",
+ Name: "images",
+ Usage: "list images in local storage",
+ Description: imagesDescription,
+ Flags: imagesFlags,
+ Action: imagesCmd,
+ ArgsUsage: "",
+ UseShortOptionHandling: true,
}
)
diff --git a/cmd/kpod/main.go b/cmd/kpod/main.go
index dfa57d689..708031dc9 100644
--- a/cmd/kpod/main.go
+++ b/cmd/kpod/main.go
@@ -37,6 +37,7 @@ func main() {
attachCommand,
createCommand,
diffCommand,
+ execCommand,
exportCommand,
historyCommand,
imagesCommand,
@@ -53,7 +54,6 @@ func main() {
psCommand,
pullCommand,
pushCommand,
- renameCommand,
rmCommand,
rmiCommand,
runCommand,
diff --git a/cmd/kpod/ps.go b/cmd/kpod/ps.go
index 13d72429e..cfcd38dc1 100644
--- a/cmd/kpod/ps.go
+++ b/cmd/kpod/ps.go
@@ -11,14 +11,12 @@ import (
"github.com/docker/go-units"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/fields"
"fmt"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/kpod/formats"
- "github.com/projectatomic/libpod/libkpod"
"github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/oci"
"github.com/urfave/cli"
@@ -61,7 +59,7 @@ type psTemplateParams struct {
// psJSONParams is only used when the JSON format is specified,
// and is better for data processing from JSON.
-// psJSONParams will be populated by data from libkpod.ContainerData,
+// psJSONParams will be populated by data from libpod.Container,
// the members of the struct are the sama data types as their sources.
type psJSONParams struct {
ID string `json:"id"`
@@ -133,12 +131,13 @@ var (
}
psDescription = "Prints out information about the containers"
psCommand = cli.Command{
- Name: "ps",
- Usage: "List containers",
- Description: psDescription,
- Flags: psFlags,
- Action: psCmd,
- ArgsUsage: "",
+ Name: "ps",
+ Usage: "List containers",
+ Description: psDescription,
+ Flags: psFlags,
+ Action: psCmd,
+ ArgsUsage: "",
+ UseShortOptionHandling: true,
}
)
@@ -349,29 +348,6 @@ func (p *psTemplateParams) headerMap() map[string]string {
return values
}
-// getContainers gets the containers that match the flags given
-func getContainers(containers []*libkpod.ContainerData, opts psOptions) []*libkpod.ContainerData {
- var containersOutput []*libkpod.ContainerData
- if opts.last >= 0 && opts.last < len(containers) {
- for i := 0; i < opts.last; i++ {
- containersOutput = append(containersOutput, containers[i])
- }
- return containersOutput
- }
- if opts.latest {
- return []*libkpod.ContainerData{containers[0]}
- }
- if opts.all || opts.last >= len(containers) {
- return containers
- }
- for _, ctr := range containers {
- if ctr.State.Status == oci.ContainerStateRunning {
- containersOutput = append(containersOutput, ctr)
- }
- }
- return containersOutput
-}
-
// getTemplateOutput returns the modified container information
func getTemplateOutput(containers []*libpod.Container, opts psOptions) ([]psTemplateParams, error) {
var psOutput []psTemplateParams
@@ -683,113 +659,3 @@ func findContainer(containers []*oci.Container, ref string) (*oci.Container, err
}
return nil, errors.Errorf("could not find container")
}
-
-// matchesFilter checks if a container matches all the filter parameters
-func matchesFilter(ctrData *libkpod.ContainerData, params *FilterParamsPS) bool {
- if params == nil {
- return true
- }
- if params.id != "" && !matchesID(ctrData, params.id) {
- return false
- }
- if params.name != "" && !matchesName(ctrData, params.name) {
- return false
- }
- if !params.before.IsZero() && !matchesBeforeContainer(ctrData, params.before) {
- return false
- }
- if !params.since.IsZero() && !matchesSinceContainer(ctrData, params.since) {
- return false
- }
- if params.exited > 0 && !matchesExited(ctrData, params.exited) {
- return false
- }
- if params.status != "" && !matchesStatus(ctrData, params.status) {
- return false
- }
- if params.ancestor != "" && !matchesAncestor(ctrData, params.ancestor) {
- return false
- }
- if params.label != "" && !matchesLabel(ctrData, params.label) {
- return false
- }
- if params.volume != "" && !matchesVolume(ctrData, params.volume) {
- return false
- }
- return true
-}
-
-// GetContainersMatchingFilter returns a slice of all the containers that match the provided filter parameters
-func getContainersMatchingFilter(containers []*oci.Container, filter *FilterParamsPS, server *libkpod.ContainerServer) []*libkpod.ContainerData {
- var filteredCtrs []*libkpod.ContainerData
- for _, ctr := range containers {
- ctrData, err := server.GetContainerData(ctr.ID(), true)
- if err != nil {
- logrus.Warn("unable to get container data for matched container")
- }
- if filter == nil || matchesFilter(ctrData, filter) {
- filteredCtrs = append(filteredCtrs, ctrData)
- }
- }
- return filteredCtrs
-}
-
-// matchesID returns true if the id's match
-func matchesID(ctrData *libkpod.ContainerData, id string) bool {
- return strings.HasPrefix(ctrData.ID, id)
-}
-
-// matchesBeforeContainer returns true if the container was created before the filter image
-func matchesBeforeContainer(ctrData *libkpod.ContainerData, beforeTime time.Time) bool {
- return ctrData.State.Created.Before(beforeTime)
-}
-
-// matchesSincecontainer returns true if the container was created since the filter image
-func matchesSinceContainer(ctrData *libkpod.ContainerData, sinceTime time.Time) bool {
- return ctrData.State.Created.After(sinceTime)
-}
-
-// matchesLabel returns true if the container label matches that of the filter label
-func matchesLabel(ctrData *libkpod.ContainerData, label string) bool {
- pair := strings.SplitN(label, "=", 2)
- if val, ok := ctrData.Labels[pair[0]]; ok {
- if len(pair) == 2 && val == pair[1] {
- return true
- }
- if len(pair) == 1 {
- return true
- }
- return false
- }
- return false
-}
-
-// matchesName returns true if the names are identical
-func matchesName(ctrData *libkpod.ContainerData, name string) bool {
- return ctrData.Name == name
-}
-
-// matchesExited returns true if the exit codes are identical
-func matchesExited(ctrData *libkpod.ContainerData, exited int32) bool {
- return ctrData.State.ExitCode == exited
-}
-
-// matchesStatus returns true if the container status matches that of filter status
-func matchesStatus(ctrData *libkpod.ContainerData, status string) bool {
- return ctrData.State.Status == status
-}
-
-// matchesAncestor returns true if filter ancestor is in container image name
-func matchesAncestor(ctrData *libkpod.ContainerData, ancestor string) bool {
- return strings.Contains(ctrData.FromImage, ancestor)
-}
-
-// matchesVolue returns true if the volume mounted or path to volue of the container matches that of filter volume
-func matchesVolume(ctrData *libkpod.ContainerData, volume string) bool {
- for _, vol := range ctrData.Mounts {
- if strings.Contains(vol.Source, volume) {
- return true
- }
- }
- return false
-}
diff --git a/cmd/kpod/rename.go b/cmd/kpod/rename.go
deleted file mode 100644
index 749dd756d..000000000
--- a/cmd/kpod/rename.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package main
-
-import (
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/libkpod"
- "github.com/urfave/cli"
-)
-
-var (
- renameDescription = "Rename a container. Container may be created, running, paused, or stopped"
- renameFlags = []cli.Flag{}
- renameCommand = cli.Command{
- Name: "rename",
- Usage: "rename a container",
- Description: renameDescription,
- Action: renameCmd,
- ArgsUsage: "CONTAINER NEW-NAME",
- Flags: renameFlags,
- }
-)
-
-func renameCmd(c *cli.Context) error {
- if len(c.Args()) != 2 {
- return errors.Errorf("Rename requires a src container name/ID and a dest container name")
- }
- if err := validateFlags(c, renameFlags); err != nil {
- return err
- }
-
- config, err := getConfig(c)
- if err != nil {
- return errors.Wrapf(err, "Could not get config")
- }
- server, err := libkpod.New(config)
- if err != nil {
- return errors.Wrapf(err, "could not get container server")
- }
- defer server.Shutdown()
- err = server.Update()
- if err != nil {
- return errors.Wrapf(err, "could not update list of containers")
- }
-
- err = server.ContainerRename(c.Args().Get(0), c.Args().Get(1))
- if err != nil {
- return errors.Wrapf(err, "could not rename container")
- }
- return nil
-}
diff --git a/cmd/kpod/rm.go b/cmd/kpod/rm.go
index 511679770..2f767457f 100644
--- a/cmd/kpod/rm.go
+++ b/cmd/kpod/rm.go
@@ -25,10 +25,11 @@ var (
Name: "rm",
Usage: fmt.Sprintf(`kpod rm will remove one or more containers from the host. The container name or ID can be used.
This does not remove images. Running containers will not be removed without the -f option.`),
- Description: rmDescription,
- Flags: rmFlags,
- Action: rmCmd,
- ArgsUsage: "",
+ Description: rmDescription,
+ Flags: rmFlags,
+ Action: rmCmd,
+ ArgsUsage: "",
+ UseShortOptionHandling: true,
}
)
diff --git a/cmd/kpod/rmi.go b/cmd/kpod/rmi.go
index b69b3b514..1b4cb7390 100644
--- a/cmd/kpod/rmi.go
+++ b/cmd/kpod/rmi.go
@@ -27,6 +27,7 @@ var (
Action: rmiCmd,
ArgsUsage: "IMAGE-NAME-OR-ID [...]",
Flags: rmiFlags,
+ UseShortOptionHandling: true,
}
)
diff --git a/cmd/kpod/run.go b/cmd/kpod/run.go
index eb3dee88c..934096c21 100644
--- a/cmd/kpod/run.go
+++ b/cmd/kpod/run.go
@@ -13,13 +13,14 @@ import (
var runDescription = "Runs a command in a new container from the given image"
var runCommand = cli.Command{
- Name: "run",
- Usage: "run a command in a new container",
- Description: runDescription,
- Flags: createFlags,
- Action: runCmd,
- ArgsUsage: "IMAGE [COMMAND [ARG...]]",
- SkipArgReorder: true,
+ Name: "run",
+ Usage: "run a command in a new container",
+ Description: runDescription,
+ Flags: createFlags,
+ Action: runCmd,
+ ArgsUsage: "IMAGE [COMMAND [ARG...]]",
+ SkipArgReorder: true,
+ UseShortOptionHandling: true,
}
func runCmd(c *cli.Context) error {
diff --git a/cmd/kpod/spec.go b/cmd/kpod/spec.go
index b2a439a9b..5d6fe8879 100644
--- a/cmd/kpod/spec.go
+++ b/cmd/kpod/spec.go
@@ -300,6 +300,16 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
return nil, errors.Wrapf(err, "error getting volume mounts")
}
configSpec.Mounts = append(configSpec.Mounts, mounts...)
+ for _, mount := range configSpec.Mounts {
+ for _, opt := range mount.Options {
+ switch opt {
+ case "private", "rprivate", "slave", "rslave", "shared", "rshared":
+ if err := g.SetLinuxRootPropagation(opt); err != nil {
+ return nil, errors.Wrapf(err, "error setting root propagation for %q", mount.Destination)
+ }
+ }
+ }
+ }
// HANDLE CAPABILITIES
if err := setupCapabilities(config, configSpec); err != nil {
@@ -442,24 +452,25 @@ func (c *createConfig) GetVolumeMounts() ([]spec.Mount, error) {
options = strings.Split(spliti[2], ",")
}
options = append(options, "rbind")
- // var foundrw, foundro,
- var foundz, foundZ bool
+ var foundrw, foundro, foundz, foundZ bool
+ var rootProp string
for _, opt := range options {
switch opt {
- // case "rw":
- // foundrw = true
- // case "ro":
- // foundro = true
+ case "rw":
+ foundrw = true
+ case "ro":
+ foundro = true
case "z":
foundz = true
case "Z":
foundZ = true
+ case "private", "rprivate", "slave", "rslave", "shared", "rshared":
+ rootProp = opt
}
}
- // if !foundro && !foundrw {
- // // rw option is default
- // options = append(options, "rw")
- // }
+ if !foundrw && !foundro {
+ options = append(options, "rw")
+ }
if foundz {
if err := label.Relabel(spliti[0], c.mountLabel, true); err != nil {
return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
@@ -470,6 +481,9 @@ func (c *createConfig) GetVolumeMounts() ([]spec.Mount, error) {
return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
}
}
+ if rootProp == "" {
+ options = append(options, "rprivate")
+ }
m = append(m, spec.Mount{
Destination: spliti[1],
diff --git a/cmd/kpod/spec_test.go b/cmd/kpod/spec_test.go
index 1eedb0e2a..799d6b235 100644
--- a/cmd/kpod/spec_test.go
+++ b/cmd/kpod/spec_test.go
@@ -13,7 +13,7 @@ func TestCreateConfig_GetVolumeMounts(t *testing.T) {
Destination: "/foobar",
Type: "bind",
Source: "foobar",
- Options: []string{"ro", "rbind"},
+ Options: []string{"ro", "rbind", "rprivate"},
}
config := createConfig{
volumes: []string{"foobar:/foobar:ro"},
diff --git a/cmd/kpod/start.go b/cmd/kpod/start.go
index fcc4c9736..c874c541c 100644
--- a/cmd/kpod/start.go
+++ b/cmd/kpod/start.go
@@ -34,12 +34,13 @@ var (
`
startCommand = cli.Command{
- Name: "start",
- Usage: "Start one or more containers",
- Description: startDescription,
- Flags: startFlags,
- Action: startCmd,
- ArgsUsage: "CONTAINER-NAME [CONTAINER-NAME ...]",
+ Name: "start",
+ Usage: "Start one or more containers",
+ Description: startDescription,
+ Flags: startFlags,
+ Action: startCmd,
+ ArgsUsage: "CONTAINER-NAME [CONTAINER-NAME ...]",
+ UseShortOptionHandling: true,
}
)