diff options
author | Valentin Rothberg <vrothberg@suse.com> | 2018-10-12 13:18:36 +0200 |
---|---|---|
committer | Valentin Rothberg <vrothberg@suse.com> | 2018-10-24 14:02:43 +0200 |
commit | 606a5cec8fa177fe64cff4ccf7cac05900fbe86c (patch) | |
tree | eaed8639a17fb03e9efb7b0c1d9d2d3be3ecd89b /cmd/podman/shared/funcs.go | |
parent | cde41c0b84e55a4325937f9c577afa6ccc129b9a (diff) | |
download | podman-606a5cec8fa177fe64cff4ccf7cac05900fbe86c.tar.gz podman-606a5cec8fa177fe64cff4ccf7cac05900fbe86c.tar.bz2 podman-606a5cec8fa177fe64cff4ccf7cac05900fbe86c.zip |
runlabel: run any command
As discussed [1], the runlabel command should execute any command
specified in a label. The reasoning behind is that we cannot restrict
which options are passed to Podman which thereby has full access to the
host (runlabels must be used with care).
With the updated semantics, runlabel will substitute the commands with a
basepath equal to "docker" or "podman" with "/proc/self/exe", and
otherwise leave the command unchanged to execute any other command on
the host.
[1] https://github.com/containers/libpod/pull/1607#issuecomment-428321382
Signed-off-by: Valentin Rothberg <vrothberg@suse.com>
Diffstat (limited to 'cmd/podman/shared/funcs.go')
-rw-r--r-- | cmd/podman/shared/funcs.go | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go index 485944f29..a92e0d547 100644 --- a/cmd/podman/shared/funcs.go +++ b/cmd/podman/shared/funcs.go @@ -3,11 +3,39 @@ package shared import ( "fmt" "os" + "path/filepath" "strings" ) +func substituteCommand(cmd string) (string, error) { + // If cmd is an absolute or relative path, check if the file exists. + // Throw an error if it doesn't exist. + if strings.Contains(cmd, "/") || strings.HasPrefix(cmd, ".") { + res, err := filepath.Abs(cmd) + if err != nil { + return "", err + } + if _, err := os.Stat(res); !os.IsNotExist(err) { + return res, nil + } else if err != nil { + return "", err + } + } + + // Replace cmd with "/proc/self/exe" if "podman" or "docker" is being + // used. Otherwise, leave the command unchanged. + switch cmd { + case "podman": + fallthrough + case "docker": + return "/proc/self/exe", nil + default: + return cmd, nil + } +} + // GenerateCommand takes a label (string) and converts it to an executable command -func GenerateCommand(command, imageName, name string) []string { +func GenerateCommand(command, imageName, name string) ([]string, error) { var ( newCommand []string ) @@ -15,8 +43,13 @@ func GenerateCommand(command, imageName, name string) []string { name = imageName } cmd := strings.Split(command, " ") - // Replace the first element of cmd with "/proc/self/exe" - newCommand = append(newCommand, "/proc/self/exe") + + prog, err := substituteCommand(cmd[0]) + if err != nil { + return nil, err + } + newCommand = append(newCommand, prog) + for _, arg := range cmd[1:] { var newArg string switch arg { @@ -37,7 +70,7 @@ func GenerateCommand(command, imageName, name string) []string { } newCommand = append(newCommand, newArg) } - return newCommand + return newCommand, nil } // GenerateRunEnvironment merges the current environment variables with optional |