github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/varlinkapi/funcs.go (about) 1 package varlinkapi 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/containers/image/v5/types" 10 "github.com/containers/podman/v2/libpod/image" 11 "github.com/google/shlex" 12 "github.com/pkg/errors" 13 ) 14 15 func GetSystemContext(authfile string) (*types.SystemContext, error) { 16 if authfile != "" { 17 if _, err := os.Stat(authfile); err != nil { 18 return nil, errors.Wrapf(err, "error checking authfile path %s", authfile) 19 } 20 } 21 return image.GetSystemContext("", authfile, false), nil 22 } 23 24 func substituteCommand(cmd string) (string, error) { 25 var ( 26 newCommand string 27 ) 28 29 // Replace cmd with "/proc/self/exe" if "podman" or "docker" is being 30 // used. If "/usr/bin/docker" is provided, we also sub in podman. 31 // Otherwise, leave the command unchanged. 32 if cmd == "podman" || filepath.Base(cmd) == "docker" { 33 newCommand = "/proc/self/exe" 34 } else { 35 newCommand = cmd 36 } 37 38 // If cmd is an absolute or relative path, check if the file exists. 39 // Throw an error if it doesn't exist. 40 if strings.Contains(newCommand, "/") || strings.HasPrefix(newCommand, ".") { 41 res, err := filepath.Abs(newCommand) 42 if err != nil { 43 return "", err 44 } 45 if _, err := os.Stat(res); !os.IsNotExist(err) { 46 return res, nil 47 } else if err != nil { 48 return "", err 49 } 50 } 51 52 return newCommand, nil 53 } 54 55 // GenerateCommand takes a label (string) and converts it to an executable command 56 func GenerateCommand(command, imageName, name, globalOpts string) ([]string, error) { 57 var ( 58 newCommand []string 59 ) 60 if name == "" { 61 name = imageName 62 } 63 64 cmd, err := shlex.Split(command) 65 if err != nil { 66 return nil, err 67 } 68 69 prog, err := substituteCommand(cmd[0]) 70 if err != nil { 71 return nil, err 72 } 73 newCommand = append(newCommand, prog) 74 75 for _, arg := range cmd[1:] { 76 var newArg string 77 switch arg { 78 case "IMAGE": 79 newArg = imageName 80 case "$IMAGE": 81 newArg = imageName 82 case "IMAGE=IMAGE": 83 newArg = fmt.Sprintf("IMAGE=%s", imageName) 84 case "IMAGE=$IMAGE": 85 newArg = fmt.Sprintf("IMAGE=%s", imageName) 86 case "NAME": 87 newArg = name 88 case "NAME=NAME": 89 newArg = fmt.Sprintf("NAME=%s", name) 90 case "NAME=$NAME": 91 newArg = fmt.Sprintf("NAME=%s", name) 92 case "$NAME": 93 newArg = name 94 case "$GLOBAL_OPTS": 95 newArg = globalOpts 96 default: 97 newArg = arg 98 } 99 newCommand = append(newCommand, newArg) 100 } 101 return newCommand, nil 102 } 103 104 // GenerateRunEnvironment merges the current environment variables with optional 105 // environment variables provided by the user 106 func GenerateRunEnvironment(name, imageName string, opts map[string]string) []string { 107 newEnv := os.Environ() 108 newEnv = append(newEnv, fmt.Sprintf("NAME=%s", name)) 109 newEnv = append(newEnv, fmt.Sprintf("IMAGE=%s", imageName)) 110 111 if opts["opt1"] != "" { 112 newEnv = append(newEnv, fmt.Sprintf("OPT1=%s", opts["opt1"])) 113 } 114 if opts["opt2"] != "" { 115 newEnv = append(newEnv, fmt.Sprintf("OPT2=%s", opts["opt2"])) 116 } 117 if opts["opt3"] != "" { 118 newEnv = append(newEnv, fmt.Sprintf("OPT3=%s", opts["opt3"])) 119 } 120 return newEnv 121 }