diff options
-rw-r--r-- | cmd/podman/containers/kill.go | 2 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 5 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 13 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 11 | ||||
-rw-r--r-- | test/e2e/kill_test.go | 13 | ||||
-rw-r--r-- | vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go | 3 | ||||
-rw-r--r-- | vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go | 4 | ||||
-rw-r--r-- | vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go | 144 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
11 files changed, 149 insertions, 54 deletions
diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index 36e3e5f59..990a6e3e7 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -111,7 +111,7 @@ func kill(_ *cobra.Command, args []string) error { } for _, r := range responses { if r.Err == nil { - fmt.Println(r.Id) + fmt.Println(r.RawInput) } else { errs = append(errs, r.Err) } @@ -50,7 +50,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 - github.com/rootless-containers/rootlesskit v0.13.0 + github.com/rootless-containers/rootlesskit v0.13.1 github.com/sirupsen/logrus v1.7.0 github.com/spf13/cobra v1.1.3 github.com/spf13/pflag v1.0.5 @@ -528,8 +528,8 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rootless-containers/rootlesskit v0.13.0 h1:41nnfB7yFxtHSeQHYupSvVxAJWh/hjmn03w6UjH7nv8= -github.com/rootless-containers/rootlesskit v0.13.0/go.mod h1:DwE/9ASct8sj7bueOXqKiwcdzyZ+yV6qhTAtJUO7988= +github.com/rootless-containers/rootlesskit v0.13.1 h1:QIMHxf00SaUinpJ2r9vwD4z6E3Yq8kk/aZ6ItNXIPHA= +github.com/rootless-containers/rootlesskit v0.13.1/go.mod h1:DwE/9ASct8sj7bueOXqKiwcdzyZ+yV6qhTAtJUO7988= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index b89c42eab..116da888d 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -110,8 +110,9 @@ type KillOptions struct { } type KillReport struct { - Err error - Id string //nolint + Err error + Id string //nolint + RawInput string } type RestartOptions struct { diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 9bef97a5c..0ee4048d1 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -208,15 +208,22 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin if err != nil { return nil, err } - ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod) + ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, ic.Libpod) if err != nil { return nil, err } + ctrMap := map[string]string{} + if len(rawInputs) == len(ctrs) { + for i := range ctrs { + ctrMap[ctrs[i].ID()] = rawInputs[i] + } + } reports := make([]*entities.KillReport, 0, len(ctrs)) for _, con := range ctrs { reports = append(reports, &entities.KillReport{ - Id: con.ID(), - Err: con.Kill(uint(sig)), + Id: con.ID(), + Err: con.Kill(uint(sig)), + RawInput: ctrMap[con.ID()], }) } return reports, nil diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 5a83faaf0..b0a07cd27 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -124,16 +124,21 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin } func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, opts entities.KillOptions) ([]*entities.KillReport, error) { - ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, false, namesOrIds) + ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, opts.All, false, namesOrIds) if err != nil { return nil, err } + ctrMap := map[string]string{} + for i := range ctrs { + ctrMap[ctrs[i].ID] = rawInputs[i] + } options := new(containers.KillOptions).WithSignal(opts.Signal) reports := make([]*entities.KillReport, 0, len(ctrs)) for _, c := range ctrs { reports = append(reports, &entities.KillReport{ - Id: c.ID, - Err: containers.Kill(ic.ClientCtx, c.ID, options), + Id: c.ID, + Err: containers.Kill(ic.ClientCtx, c.ID, options), + RawInput: ctrMap[c.ID], }) } return reports, nil diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index c1c1b003e..6d6fe788b 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -51,6 +51,19 @@ var _ = Describe("Podman kill", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) + It("podman container kill a running container by short id", func() { + session := podmanTest.RunTopContainer("") + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + cid := session.OutputToString() + + result := podmanTest.Podman([]string{"container", "kill", cid[:5]}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.OutputToString()).To(Equal(cid[:5])) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) + It("podman kill a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go index b9f2d1802..9fb801162 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp/tcp.go @@ -5,6 +5,7 @@ import ( "io" "net" "os" + "strconv" "sync" "github.com/rootless-containers/rootlesskit/pkg/port" @@ -12,7 +13,7 @@ import ( ) func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, logWriter io.Writer) error { - ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", spec.ParentIP, spec.ParentPort)) + ln, err := net.Listen("tcp", net.JoinHostPort(spec.ParentIP, strconv.Itoa(spec.ParentPort))) if err != nil { fmt.Fprintf(logWriter, "listen: %v\n", err) return err diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go index d8f646b5d..fbff2b081 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go @@ -1,10 +1,10 @@ package udp import ( - "fmt" "io" "net" "os" + "strconv" "github.com/pkg/errors" @@ -14,7 +14,7 @@ import ( ) func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, logWriter io.Writer) error { - addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", spec.ParentIP, spec.ParentPort)) + addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(spec.ParentIP, strconv.Itoa(spec.ParentPort))) if err != nil { return err } diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go index 1c531cac8..a885a76ca 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go @@ -4,76 +4,135 @@ import ( "net" "strconv" "strings" + "text/scanner" "github.com/pkg/errors" "github.com/rootless-containers/rootlesskit/pkg/port" ) -// ParsePortSpec parses a Docker-like representation of PortSpec. +// ParsePortSpec parses a Docker-like representation of PortSpec, but with +// support for both "parent IP" and "child IP" (optional); // e.g. "127.0.0.1:8080:80/tcp", or "127.0.0.1:8080:10.0.2.100:80/tcp" -func ParsePortSpec(s string) (*port.Spec, error) { - splitBySlash := strings.SplitN(s, "/", 2) - if len(splitBySlash) != 2 { - return nil, errors.Errorf("unexpected PortSpec string: %q", s) +// +// Format is as follows: +// +// <parent IP>:<parent port>[:<child IP>]:<child port>/<proto> +// +// Note that (child IP being optional) the format can either contain 5 or 4 +// components. When using IPv6 IP addresses, addresses must use square brackets +// to prevent the colons being mistaken for delimiters. For example: +// +// [::1]:8080:[::2]:80/udp +func ParsePortSpec(portSpec string) (*port.Spec, error) { + const ( + parentIP = iota + parentPort = iota + childIP = iota + childPort = iota + proto = iota + ) + + var ( + s scanner.Scanner + err error + parts = make([]string, 5) + index = parentIP + delimiter = ':' + ) + + // First get the "proto" and "parent-port" at the end. These parts are + // required, whereas "ParentIP" is optional. Removing them first makes + // it easier to parse the remaining parts, as otherwise the third part + // could be _either_ an IP-address _or_ a Port. + + // Get the proto + protoPos := strings.LastIndex(portSpec, "/") + if protoPos < 0 { + return nil, errors.Errorf("missing proto in PortSpec string: %q", portSpec) } - proto := splitBySlash[1] - switch proto { - case "tcp", "udp", "sctp": - default: - return nil, errors.Errorf("unexpected Proto in PortSpec string: %q", s) + parts[proto] = portSpec[protoPos+1:] + err = validateProto(parts[proto]) + if err != nil { + return nil, errors.Wrapf(err, "invalid PortSpec string: %q", portSpec) } - splitByColon := strings.SplitN(splitBySlash[0], ":", 4) - switch len(splitByColon) { - case 3, 4: - default: - return nil, errors.Errorf("unexpected PortSpec string: %q", s) + // Get the parent port + portPos := strings.LastIndex(portSpec, ":") + if portPos < 0 { + return nil, errors.Errorf("unexpected PortSpec string: %q", portSpec) } + parts[childPort] = portSpec[portPos+1 : protoPos] + + // Scan the remainder "<IP-address>:<port>[:<IP-address>]" + s.Init(strings.NewReader(portSpec[:portPos])) + + for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { + if index > childPort { + return nil, errors.Errorf("unexpected PortSpec string: %q", portSpec) + } - parentIP := splitByColon[0] - if net.IP(parentIP) == nil { - return nil, errors.Errorf("unexpected ParentIP in PortSpec string: %q", s) + switch tok { + case '[': + // Start of IPv6 IP-address; value ends at closing bracket (]) + delimiter = ']' + continue + case delimiter: + if delimiter == ']' { + // End of IPv6 IP-address + delimiter = ':' + // Skip the next token, which should be a colon delimiter (:) + tok = s.Scan() + } + index++ + continue + default: + parts[index] += s.TokenText() + } } - parentPort, err := strconv.Atoi(splitByColon[1]) - if err != nil { - return nil, errors.Wrapf(err, "unexpected ParentPort in PortSpec string: %q", s) + if parts[parentIP] != "" && net.ParseIP(parts[parentIP]) == nil { + return nil, errors.Errorf("unexpected ParentIP in PortSpec string: %q", portSpec) + } + if parts[childIP] != "" && net.ParseIP(parts[childIP]) == nil { + return nil, errors.Errorf("unexpected ParentIP in PortSpec string: %q", portSpec) } - var childIP string - if len(splitByColon) == 4 { - childIP = splitByColon[2] - if net.IP(childIP) == nil { - return nil, errors.Errorf("unexpected ChildIP in PortSpec string: %q", s) - } + ps := &port.Spec{ + Proto: parts[proto], + ParentIP: parts[parentIP], + ChildIP: parts[childIP], } - childPort, err := strconv.Atoi(splitByColon[len(splitByColon)-1]) + ps.ParentPort, err = strconv.Atoi(parts[parentPort]) if err != nil { - return nil, errors.Wrapf(err, "unexpected ChildPort in PortSpec string: %q", s) + return nil, errors.Wrapf(err, "unexpected ChildPort in PortSpec string: %q", portSpec) } - return &port.Spec{ - Proto: proto, - ParentIP: parentIP, - ParentPort: parentPort, - ChildIP: childIP, - ChildPort: childPort, - }, nil + ps.ChildPort, err = strconv.Atoi(parts[childPort]) + if err != nil { + return nil, errors.Wrapf(err, "unexpected ParentPort in PortSpec string: %q", portSpec) + } + + return ps, nil } // ValidatePortSpec validates *port.Spec. // existingPorts can be optionally passed for detecting conflicts. func ValidatePortSpec(spec port.Spec, existingPorts map[int]*port.Status) error { - if spec.Proto != "tcp" && spec.Proto != "udp" { - return errors.Errorf("unknown proto: %q", spec.Proto) + if err := validateProto(spec.Proto); err != nil { + return err } if spec.ParentIP != "" { if net.ParseIP(spec.ParentIP) == nil { return errors.Errorf("invalid ParentIP: %q", spec.ParentIP) } } + if spec.ChildIP != "" { + if net.ParseIP(spec.ChildIP) == nil { + return errors.Errorf("invalid ChildIP: %q", spec.ChildIP) + } + } if spec.ParentPort <= 0 || spec.ParentPort > 65535 { return errors.Errorf("invalid ParentPort: %q", spec.ParentPort) } @@ -90,3 +149,12 @@ func ValidatePortSpec(spec port.Spec, existingPorts map[int]*port.Status) error } return nil } + +func validateProto(proto string) error { + switch proto { + case "tcp", "udp", "sctp": + return nil + default: + return errors.Errorf("unknown proto: %q", proto) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7240ac6b6..44e87e54c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -515,7 +515,7 @@ github.com/prometheus/common/model # github.com/prometheus/procfs v0.0.3 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs -# github.com/rootless-containers/rootlesskit v0.13.0 +# github.com/rootless-containers/rootlesskit v0.13.1 github.com/rootless-containers/rootlesskit/pkg/msgutil github.com/rootless-containers/rootlesskit/pkg/port github.com/rootless-containers/rootlesskit/pkg/port/builtin |