diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/imagefilters/filters.go | 24 | ||||
-rw-r--r-- | cmd/podman/images.go | 3 | ||||
-rw-r--r-- | cmd/podman/kill.go | 73 | ||||
-rw-r--r-- | cmd/podman/play_kube.go | 51 |
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 } |