summaryrefslogtreecommitdiff
path: root/cmd/podman/images/scp_utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman/images/scp_utils.go')
-rw-r--r--cmd/podman/images/scp_utils.go87
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
+}