summaryrefslogtreecommitdiff
path: root/cmd/podman/common/util.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman/common/util.go')
-rw-r--r--cmd/podman/common/util.go274
1 files changed, 0 insertions, 274 deletions
diff --git a/cmd/podman/common/util.go b/cmd/podman/common/util.go
deleted file mode 100644
index cdfff9d6f..000000000
--- a/cmd/podman/common/util.go
+++ /dev/null
@@ -1,274 +0,0 @@
-package common
-
-import (
- "io/ioutil"
- "net"
- "strconv"
- "strings"
-
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-// ReadPodIDFile reads the specified file and returns its content (i.e., first
-// line).
-func ReadPodIDFile(path string) (string, error) {
- content, err := ioutil.ReadFile(path)
- if err != nil {
- return "", errors.Wrap(err, "error reading pod ID file")
- }
- return strings.Split(string(content), "\n")[0], nil
-}
-
-// ReadPodIDFiles reads the specified files and returns their content (i.e.,
-// first line).
-func ReadPodIDFiles(files []string) ([]string, error) {
- ids := []string{}
- for _, file := range files {
- id, err := ReadPodIDFile(file)
- if err != nil {
- return nil, err
- }
- ids = append(ids, id)
- }
- return ids, nil
-}
-
-// ParseFilters transforms one filter format to another and validates input
-func ParseFilters(filter []string) (map[string][]string, error) {
- // TODO Remove once filter refactor is finished and url.Values done.
- filters := map[string][]string{}
- for _, f := range filter {
- t := strings.SplitN(f, "=", 2)
- filters = make(map[string][]string)
- if len(t) < 2 {
- return map[string][]string{}, errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
- }
- filters[t[0]] = append(filters[t[0]], t[1])
- }
- return filters, nil
-}
-
-// createExpose parses user-provided exposed port definitions and converts them
-// into SpecGen format.
-// TODO: The SpecGen format should really handle ranges more sanely - we could
-// be massively inflating what is sent over the wire with a large range.
-func createExpose(expose []string) (map[uint16]string, error) {
- toReturn := make(map[uint16]string)
-
- for _, e := range expose {
- // Check for protocol
- proto := "tcp"
- splitProto := strings.Split(e, "/")
- if len(splitProto) > 2 {
- return nil, errors.Errorf("invalid expose format - protocol can only be specified once")
- } else if len(splitProto) == 2 {
- proto = splitProto[1]
- }
-
- // Check for a range
- start, len, err := parseAndValidateRange(splitProto[0])
- if err != nil {
- return nil, err
- }
-
- var index uint16
- for index = 0; index < len; index++ {
- portNum := start + index
- protocols, ok := toReturn[portNum]
- if !ok {
- toReturn[portNum] = proto
- } else {
- newProto := strings.Join(append(strings.Split(protocols, ","), strings.Split(proto, ",")...), ",")
- toReturn[portNum] = newProto
- }
- }
- }
-
- return toReturn, nil
-}
-
-// CreatePortBindings iterates ports mappings into SpecGen format.
-func CreatePortBindings(ports []string) ([]types.PortMapping, error) {
- // --publish is formatted as follows:
- // [[hostip:]hostport[-endPort]:]containerport[-endPort][/protocol]
- toReturn := make([]types.PortMapping, 0, len(ports))
-
- for _, p := range ports {
- var (
- ctrPort string
- proto, hostIP, hostPort *string
- )
-
- splitProto := strings.Split(p, "/")
- switch len(splitProto) {
- case 1:
- // No protocol was provided
- case 2:
- proto = &(splitProto[1])
- default:
- return nil, errors.Errorf("invalid port format - protocol can only be specified once")
- }
-
- remainder := splitProto[0]
- haveV6 := false
-
- // Check for an IPv6 address in brackets
- splitV6 := strings.Split(remainder, "]")
- switch len(splitV6) {
- case 1:
- // Do nothing, proceed as before
- case 2:
- // We potentially have an IPv6 address
- haveV6 = true
- if !strings.HasPrefix(splitV6[0], "[") {
- return nil, errors.Errorf("invalid port format - IPv6 addresses must be enclosed by []")
- }
- if !strings.HasPrefix(splitV6[1], ":") {
- return nil, errors.Errorf("invalid port format - IPv6 address must be followed by a colon (':')")
- }
- ipNoPrefix := strings.TrimPrefix(splitV6[0], "[")
- hostIP = &ipNoPrefix
- remainder = strings.TrimPrefix(splitV6[1], ":")
- default:
- return nil, errors.Errorf("invalid port format - at most one IPv6 address can be specified in a --publish")
- }
-
- splitPort := strings.Split(remainder, ":")
- switch len(splitPort) {
- case 1:
- if haveV6 {
- return nil, errors.Errorf("invalid port format - must provide host and destination port if specifying an IP")
- }
- ctrPort = splitPort[0]
- case 2:
- hostPort = &(splitPort[0])
- ctrPort = splitPort[1]
- case 3:
- if haveV6 {
- return nil, errors.Errorf("invalid port format - when v6 address specified, must be [ipv6]:hostPort:ctrPort")
- }
- hostIP = &(splitPort[0])
- hostPort = &(splitPort[1])
- ctrPort = splitPort[2]
- default:
- return nil, errors.Errorf("invalid port format - format is [[hostIP:]hostPort:]containerPort")
- }
-
- newPort, err := parseSplitPort(hostIP, hostPort, ctrPort, proto)
- if err != nil {
- return nil, err
- }
-
- toReturn = append(toReturn, newPort)
- }
-
- return toReturn, nil
-}
-
-// parseSplitPort parses individual components of the --publish flag to produce
-// a single port mapping in SpecGen format.
-func parseSplitPort(hostIP, hostPort *string, ctrPort string, protocol *string) (types.PortMapping, error) {
- newPort := types.PortMapping{}
- if ctrPort == "" {
- return newPort, errors.Errorf("must provide a non-empty container port to publish")
- }
- ctrStart, ctrLen, err := parseAndValidateRange(ctrPort)
- if err != nil {
- return newPort, errors.Wrapf(err, "error parsing container port")
- }
- newPort.ContainerPort = ctrStart
- newPort.Range = ctrLen
-
- if protocol != nil {
- if *protocol == "" {
- return newPort, errors.Errorf("must provide a non-empty protocol to publish")
- }
- newPort.Protocol = *protocol
- }
- if hostIP != nil {
- if *hostIP == "" {
- return newPort, errors.Errorf("must provide a non-empty container host IP to publish")
- } else if *hostIP != "0.0.0.0" {
- // If hostIP is 0.0.0.0, leave it unset - CNI treats
- // 0.0.0.0 and empty differently, Docker does not.
- testIP := net.ParseIP(*hostIP)
- if testIP == nil {
- return newPort, errors.Errorf("cannot parse %q as an IP address", *hostIP)
- }
- newPort.HostIP = testIP.String()
- }
- }
- if hostPort != nil {
- if *hostPort == "" {
- // Set 0 as a placeholder. The server side of Specgen
- // will find a random, open, unused port to use.
- newPort.HostPort = 0
- } else {
- hostStart, hostLen, err := parseAndValidateRange(*hostPort)
- if err != nil {
- return newPort, errors.Wrapf(err, "error parsing host port")
- }
- if hostLen != ctrLen {
- return newPort, errors.Errorf("host and container port ranges have different lengths: %d vs %d", hostLen, ctrLen)
- }
- newPort.HostPort = hostStart
- }
- }
-
- hport := newPort.HostPort
- logrus.Debugf("Adding port mapping from %d to %d length %d protocol %q", hport, newPort.ContainerPort, newPort.Range, newPort.Protocol)
-
- return newPort, nil
-}
-
-// Parse and validate a port range.
-// Returns start port, length of range, error.
-func parseAndValidateRange(portRange string) (uint16, uint16, error) {
- splitRange := strings.Split(portRange, "-")
- if len(splitRange) > 2 {
- return 0, 0, errors.Errorf("invalid port format - port ranges are formatted as startPort-stopPort")
- }
-
- if splitRange[0] == "" {
- return 0, 0, errors.Errorf("port numbers cannot be negative")
- }
-
- startPort, err := parseAndValidatePort(splitRange[0])
- if err != nil {
- return 0, 0, err
- }
-
- var rangeLen uint16 = 1
- if len(splitRange) == 2 {
- if splitRange[1] == "" {
- return 0, 0, errors.Errorf("must provide ending number for port range")
- }
- endPort, err := parseAndValidatePort(splitRange[1])
- if err != nil {
- return 0, 0, err
- }
- if endPort <= startPort {
- return 0, 0, errors.Errorf("the end port of a range must be higher than the start port - %d is not higher than %d", endPort, startPort)
- }
- // Our range is the total number of ports
- // involved, so we need to add 1 (8080:8081 is
- // 2 ports, for example, not 1)
- rangeLen = endPort - startPort + 1
- }
-
- return startPort, rangeLen, nil
-}
-
-// Turn a single string into a valid U16 port.
-func parseAndValidatePort(port string) (uint16, error) {
- num, err := strconv.Atoi(port)
- if err != nil {
- return 0, errors.Wrapf(err, "invalid port number")
- }
- if num < 1 || num > 65535 {
- return 0, errors.Errorf("port numbers must be between 1 and 65535 (inclusive), got %d", num)
- }
- return uint16(num), nil
-}