diff --git a/pkg/entrypoint/entrypointer.go b/pkg/entrypoint/entrypointer.go index f0ec0cfe470..1df657dbd99 100644 --- a/pkg/entrypoint/entrypointer.go +++ b/pkg/entrypoint/entrypointer.go @@ -33,6 +33,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/pipeline" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/names" "github.com/tektoncd/pipeline/pkg/pod" "github.com/tektoncd/pipeline/pkg/result" "github.com/tektoncd/pipeline/pkg/spire" @@ -361,6 +362,8 @@ func getStepResultPath(stepName string, resultName string) string { return filepath.Join(pipeline.StepsDir, stepName, "results", resultName) } +// findReplacement looks for any usage of step results in an input string. +// If found, it loads the results from the previous steps and provides the replacement value. func findReplacement(s string) (string, []string, error) { value := strings.TrimSuffix(strings.TrimPrefix(s, "$("), ")") stepName, resultName, arrayIdx, objectKey, paramType, err := v1.ParseStepExpression(value) @@ -387,11 +390,8 @@ func findReplacement(s string) (string, []string, error) { return replaceWithString, replaceWithArray, nil } -// applyStepResultSubstitutions applies the runtime step result substitutions in env. -func (e *Entrypointer) applyStepResultSubstitutions() error { - pattern := `\$\(steps\..*\.results\..*\)` - stepResultRegex := regexp.MustCompile(pattern) - // env +// replaceCommandAndArgs performs replacements for step results in environment variables. +func replaceEnv() error { for _, e := range os.Environ() { pair := strings.SplitN(e, "=", 2) matches := stepResultRegex.FindAllStringSubmatch(pair[1], -1) @@ -403,7 +403,14 @@ func (e *Entrypointer) applyStepResultSubstitutions() error { os.Setenv(pair[0], strings.ReplaceAll(pair[1], m[0], replaceWith)) } } - // script + return nil +} + +// replaceScript performs replacements for step results in the script file. +// It reads the original script file, performs the replacements and writes a new file +// since the original script location is unknown. +// It then updates the command to execute the new file. +func replaceScript(e *Entrypointer) error { if strings.HasPrefix(e.Command[0], "/tekton/scripts") { fileContentBytes, err := os.ReadFile(e.Command[0]) if err != nil { @@ -420,7 +427,7 @@ func (e *Entrypointer) applyStepResultSubstitutions() error { fileContents = strings.ReplaceAll(fileContents, m[0], replaceWith) } // copy the modified contents to a different file. - newFilePath := filepath.Join(e.StepMetadataDir, "script") + newFilePath := filepath.Join(e.StepMetadataDir, names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("script")) err := os.WriteFile(newFilePath, []byte(fileContents), 0755) if err != nil { return err @@ -429,7 +436,11 @@ func (e *Entrypointer) applyStepResultSubstitutions() error { e.Command[0] = newFilePath } } - // command + args + return nil +} + +// replaceCommandAndArgs performs replacements for step results in e.Command +func replaceCommandAndArgs(command []string) ([]string, error) { newCommand := []string{} for _, c := range e.Command { matches := stepResultRegex.FindAllStringSubmatch(c, -1) @@ -437,7 +448,7 @@ func (e *Entrypointer) applyStepResultSubstitutions() error { for _, m := range matches { replaceWithString, replaceWithArray, err := findReplacement(m[0]) if err != nil { - return err + return nil, err } // if replacing with an array if len(replaceWithArray) > 1 { @@ -453,6 +464,26 @@ func (e *Entrypointer) applyStepResultSubstitutions() error { newCommand = append(newCommand, c) } } + return newCommand, nil +} + +// applyStepResultSubstitutions applies the runtime step result substitutions in env, script and command. +func (e *Entrypointer) applyStepResultSubstitutions() error { + pattern := `\$\(steps\..*\.results\..*\)` + stepResultRegex := regexp.MustCompile(pattern) + // env + if err := replaceEnv(); err != nil { + return err + } + // script + if err := replaceScript(e); err != nil { + return err + } + // command + args + newCommand, err := replaceCommandAndArgs(e.Command) + if err != nil { + return err + } e.Command = newCommand return nil }