grim/convey

Add script support to the run task
redux
2021-10-11, Gary Kramlich
cf227c260992
Parents 126c741a9abb
Children 5455207816fd
Add script support to the run task
  • +60 -0
    podman/run.go
  • --- a/podman/run.go Mon Oct 11 05:32:52 2021 -0500
    +++ b/podman/run.go Mon Oct 11 06:19:45 2021 -0500
    @@ -1,6 +1,10 @@
    package podman
    import (
    + "os"
    + "path/filepath"
    + "strings"
    +
    "github.com/kballard/go-shellquote"
    "github.com/opencontainers/selinux/go-selinux"
    log "github.com/sirupsen/logrus"
    @@ -19,6 +23,8 @@
    Environment yaml.StringOrSlice `yaml:"environment"`
    Hostname string `yaml:"hostname"`
    Image string `yaml:"image"`
    + Script yaml.StringOrSlice `yaml:"script"`
    + Shell string `yaml:"shell"`
    User string `yaml:"user"`
    Workdir string `yaml:"workdir"`
    Workspace string `yaml:"workspace"`
    @@ -26,6 +32,29 @@
    commandv []string
    }
    +func (r *Run) buildScript(cfgPath string, env environment.Environment) (string, error) {
    + script := env.Expandv(r.Script)
    +
    + fp, err := os.CreateTemp(cfgPath, ".convey-script-")
    + if err != nil {
    + return "", err
    + }
    +
    + if _, err = fp.Write([]byte(strings.Join(script, "\n"))); err != nil {
    + return "", err
    + }
    +
    + if err := fp.Chmod(0700); err != nil {
    + return "", err
    + }
    +
    + if err := fp.Close(); err != nil {
    + return "", err
    + }
    +
    + return fp.Name(), nil
    +}
    +
    func (r *Run) Execute(name string, logger *log.Entry, stageEnv environment.Environment, rt *runtime.Runtime) error {
    // Create a new environment based on the stage's environment. Then merge
    // the task's environment overriding anything from the stage. Finally merge
    @@ -61,6 +90,33 @@
    "--volume", volume,
    )
    + // if the user provided a script, generate the file and set all of our
    + // attributes appropriately.
    + if len(r.Script) > 0 {
    + // Overwrite any entry point that the user provided. Validate set
    + // /bin/sh if the user didn't provide one.
    + r.Entrypoint = r.Shell
    +
    + scriptFile, err := r.buildScript(rt.ConfigPath, env)
    + if err != nil {
    + os.Remove(scriptFile)
    + return err
    + }
    +
    + defer os.Remove(scriptFile)
    +
    + scriptFileBase := filepath.Base(scriptFile)
    +
    + r.commandv = []string{"/" + scriptFileBase}
    +
    + volume := scriptFile + ":/" + scriptFileBase
    + if selinux.GetEnabled() {
    + volume += ":z"
    + }
    +
    + generator.Append("--volume", volume)
    + }
    +
    // Add any annotations that the user specified.
    for _, annotation := range r.Annotations {
    generator.Append("--annotation", annotation)
    @@ -119,6 +175,10 @@
    r.commandv = cmdv
    }
    + if r.Shell == "" {
    + r.Shell = "/bin/sh"
    + }
    +
    return nil
    }