diff options
Diffstat (limited to 'cmd/podman/images/scp_utils.go')
-rw-r--r-- | cmd/podman/images/scp_utils.go | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/cmd/podman/images/scp_utils.go b/cmd/podman/images/scp_utils.go new file mode 100644 index 000000000..ebb874c1c --- /dev/null +++ b/cmd/podman/images/scp_utils.go @@ -0,0 +1,87 @@ +package images + +import ( + "strings" + + "github.com/containers/image/v5/docker/reference" + "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/pkg/errors" +) + +// parseImageSCPArg returns the valid connection, and source/destination data based off of the information provided by the user +// arg is a string containing one of the cli arguments returned is a filled out source/destination options structs as well as a connections array and an error if applicable +func parseImageSCPArg(arg string) (*entities.ImageScpOptions, []string, error) { + location := entities.ImageScpOptions{} + var err error + cliConnections := []string{} + + switch { + case strings.Contains(arg, "@localhost"): // image transfer between users + location.User = strings.Split(arg, "@")[0] + location, err = validateImagePortion(location, arg) + if err != nil { + return nil, nil, err + } + case strings.Contains(arg, "::"): + location, err = validateImagePortion(location, arg) + if err != nil { + return nil, nil, err + } + location.Remote = true + cliConnections = append(cliConnections, arg) + default: + location.Image = arg + } + return &location, cliConnections, nil +} + +// validateImagePortion is a helper function to validate the image name in an SCP argument +func validateImagePortion(location entities.ImageScpOptions, arg string) (entities.ImageScpOptions, error) { + if remoteArgLength(arg, 1) > 0 { + err := validateImageName(strings.Split(arg, "::")[1]) + if err != nil { + return location, err + } + location.Image = strings.Split(arg, "::")[1] // this will get checked/set again once we validate connections + } + return location, nil +} + +// validateSCPArgs takes the array of source and destination options and checks for common errors +func validateSCPArgs(locations []*entities.ImageScpOptions) (bool, error) { + if len(locations) > 2 { + return false, errors.Wrapf(define.ErrInvalidArg, "cannot specify more than two arguments") + } + switch { + case len(locations[0].Image) > 0 && len(locations[1].Image) > 0: + return false, errors.Wrapf(define.ErrInvalidArg, "cannot specify an image rename") + case len(locations[0].Image) == 0 && len(locations[1].Image) == 0: + return false, errors.Wrapf(define.ErrInvalidArg, "a source image must be specified") + case len(locations[0].Image) == 0 && len(locations[1].Image) != 0: + if locations[0].Remote && locations[1].Remote { + return true, nil // we need to flip the cliConnections array so the save/load connections are in the right place + } + } + return false, nil +} + +// validateImageName makes sure that the image given is valid and no injections are occurring +// we simply use this for error checking, bot setting the image +func validateImageName(input string) error { + // ParseNormalizedNamed transforms a shortname image into its + // full name reference so busybox => docker.io/library/busybox + // we want to keep our shortnames, so only return an error if + // we cannot parse what the user has given us + _, err := reference.ParseNormalizedNamed(input) + return err +} + +// remoteArgLength is a helper function to simplify the extracting of host argument data +// returns an int which contains the length of a specified index in a host::image string +func remoteArgLength(input string, side int) int { + if strings.Contains(input, "::") { + return len((strings.Split(input, "::"))[side]) + } + return -1 +} |