aboutsummaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/imagefilters/filters.go24
-rw-r--r--cmd/podman/images.go3
-rw-r--r--cmd/podman/kill.go73
-rw-r--r--cmd/podman/play_kube.go51
4 files changed, 106 insertions, 45 deletions
diff --git a/cmd/podman/imagefilters/filters.go b/cmd/podman/imagefilters/filters.go
index d01eb7436..2932d61c0 100644
--- a/cmd/podman/imagefilters/filters.go
+++ b/cmd/podman/imagefilters/filters.go
@@ -2,11 +2,14 @@ package imagefilters
import (
"context"
+ "fmt"
+ "path/filepath"
"strings"
"time"
"github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/pkg/inspect"
+ "github.com/sirupsen/logrus"
)
// ResultFilter is a mock function for image filtering
@@ -61,6 +64,27 @@ func LabelFilter(ctx context.Context, labelfilter string) ResultFilter {
}
}
+// ReferenceFilter allows you to filter by image name
+// Replacing all '/' with '|' so that filepath.Match() can work
+// '|' character is not valid in image name, so this is safe
+func ReferenceFilter(ctx context.Context, referenceFilter string) ResultFilter {
+ filter := fmt.Sprintf("*%s*", referenceFilter)
+ filter = strings.Replace(filter, "/", "|", -1)
+ return func(i *adapter.ContainerImage) bool {
+ for _, name := range i.Names() {
+ newName := strings.Replace(name, "/", "|", -1)
+ match, err := filepath.Match(filter, newName)
+ if err != nil {
+ logrus.Errorf("failed to match %s and %s, %q", name, referenceFilter, err)
+ }
+ if match {
+ return true
+ }
+ }
+ return false
+ }
+}
+
// OutputImageFilter allows you to filter by an a specific image name
func OutputImageFilter(userImage *adapter.ContainerImage) ResultFilter {
return func(i *adapter.ContainerImage) bool {
diff --git a/cmd/podman/images.go b/cmd/podman/images.go
index 26e51bef7..a4f2e5e10 100644
--- a/cmd/podman/images.go
+++ b/cmd/podman/images.go
@@ -375,6 +375,9 @@ func CreateFilterFuncs(ctx context.Context, r *adapter.LocalRuntime, filters []s
case "label":
labelFilter := strings.Join(splitFilter[1:], "=")
filterFuncs = append(filterFuncs, imagefilters.LabelFilter(ctx, labelFilter))
+ case "reference":
+ referenceFilter := strings.Join(splitFilter[1:], "=")
+ filterFuncs = append(filterFuncs, imagefilters.ReferenceFilter(ctx, referenceFilter))
default:
return nil, errors.Errorf("invalid filter %s ", splitFilter[0])
}
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index 76d2516b7..82a257e23 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -2,16 +2,15 @@ package main
import (
"fmt"
- "syscall"
+ "reflect"
+
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/opentracing/opentracing-go"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
- "github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/docker/docker/pkg/signal"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -51,54 +50,44 @@ func init() {
// killCmd kills one or more containers with a signal
func killCmd(c *cliconfig.KillValues) error {
- var (
- killFuncs []shared.ParallelWorkerInput
- killSignal uint = uint(syscall.SIGTERM)
- )
+ if c.Bool("trace") {
+ span, _ := opentracing.StartSpanFromContext(Ctx, "killCmd")
+ defer span.Finish()
+ }
+
+ // Check if the signalString provided by the user is valid
+ // Invalid signals will return err
+ killSignal, err := signal.ParseSignal(c.Signal)
+ if err != nil {
+ return err
+ }
rootless.SetSkipStorageSetup(true)
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
- if c.Signal != "" {
- // Check if the signalString provided by the user is valid
- // Invalid signals will return err
- sysSignal, err := signal.ParseSignal(c.Signal)
- if err != nil {
- return err
- }
- killSignal = uint(sysSignal)
- }
-
- containers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateRunning, "running")
+ ok, failures, err := runtime.KillContainers(getContext(), c, killSignal)
if err != nil {
- if len(containers) == 0 {
- return err
- }
- fmt.Println(err.Error())
+ return err
}
- for _, ctr := range containers {
- con := ctr
- f := func() error {
- return con.Kill(killSignal)
- }
-
- killFuncs = append(killFuncs, shared.ParallelWorkerInput{
- ContainerID: con.ID(),
- ParallelFunc: f,
- })
+ for _, id := range ok {
+ fmt.Println(id)
}
- maxWorkers := shared.Parallelize("kill")
- if c.GlobalIsSet("max-workers") {
- maxWorkers = c.GlobalFlags.MaxWorks
- }
- logrus.Debugf("Setting maximum workers to %d", maxWorkers)
+ if len(failures) > 0 {
+ keys := reflect.ValueOf(failures).MapKeys()
+ lastKey := keys[len(keys)-1].String()
+ lastErr := failures[lastKey]
+ delete(failures, lastKey)
- killErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, killFuncs)
- return printParallelOutput(killErrors, errCount)
+ for _, err := range failures {
+ outputError(err)
+ }
+ return lastErr
+ }
+ return nil
}
diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go
index ac46ad5c6..1910b68b5 100644
--- a/cmd/podman/play_kube.go
+++ b/cmd/podman/play_kube.go
@@ -25,6 +25,11 @@ import (
"k8s.io/api/core/v1"
)
+const (
+ // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
+ createDirectoryPermission = 0755
+)
+
var (
playKubeCommand cliconfig.KubePlayValues
playKubeDescription = "Play a Pod and its containers based on a Kubrernetes YAML"
@@ -144,12 +149,41 @@ func playKubeYAMLCmd(c *cliconfig.KubePlayValues) error {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify)
}
+ // map from name to mount point
+ volumes := make(map[string]string)
+ for _, volume := range podYAML.Spec.Volumes {
+ hostPath := volume.VolumeSource.HostPath
+ if hostPath == nil {
+ return errors.Errorf("HostPath is currently the only supported VolumeSource")
+ }
+ if hostPath.Type != nil {
+ switch *hostPath.Type {
+ case v1.HostPathDirectoryOrCreate:
+ if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
+ if err := os.Mkdir(hostPath.Path, createDirectoryPermission); err != nil {
+ return errors.Errorf("Error creating HostPath %s at %s", volume.Name, hostPath.Path)
+ }
+ }
+ case v1.HostPathDirectory:
+ // do nothing here because we will verify the path exists in validateVolumeHostDir
+ break
+ default:
+ return errors.Errorf("Directories are the only supported HostPath type")
+ }
+ }
+ if err := validateVolumeHostDir(hostPath.Path); err != nil {
+ return errors.Wrapf(err, "Error in parsing HostPath in YAML")
+ }
+ fmt.Println(volume.Name)
+ volumes[volume.Name] = hostPath.Path
+ }
+
for _, container := range podYAML.Spec.Containers {
newImage, err := runtime.ImageRuntime().New(ctx, container.Image, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image2.SigningOptions{}, false, nil)
if err != nil {
return err
}
- createConfig := kubeContainerToCreateConfig(container, runtime, newImage, namespaces)
+ createConfig, err := kubeContainerToCreateConfig(container, runtime, newImage, namespaces, volumes)
if err != nil {
return err
}
@@ -194,7 +228,7 @@ func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
}
// kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container
-func kubeContainerToCreateConfig(containerYAML v1.Container, runtime *libpod.Runtime, newImage *image2.Image, namespaces map[string]string) *createconfig.CreateConfig {
+func kubeContainerToCreateConfig(containerYAML v1.Container, runtime *libpod.Runtime, newImage *image2.Image, namespaces map[string]string, volumes map[string]string) (*createconfig.CreateConfig, error) {
var (
containerConfig createconfig.CreateConfig
envs map[string]string
@@ -239,6 +273,17 @@ func kubeContainerToCreateConfig(containerYAML v1.Container, runtime *libpod.Run
for _, e := range containerYAML.Env {
envs[e.Name] = e.Value
}
+
+ for _, volume := range containerYAML.VolumeMounts {
+ host_path, exists := volumes[volume.Name]
+ if !exists {
+ return nil, errors.Errorf("Volume mount %s specified for container but not configured in volumes", volume.Name)
+ }
+ if err := validateVolumeCtrDir(volume.MountPath); err != nil {
+ return nil, errors.Wrapf(err, "error in parsing MountPath")
+ }
+ containerConfig.Volumes = append(containerConfig.Volumes, fmt.Sprintf("%s:%s", host_path, volume.MountPath))
+ }
containerConfig.Env = envs
- return &containerConfig
+ return &containerConfig, nil
}