diff --git a/controllers/jenkins/pipeline/json_converter.go b/controllers/jenkins/pipeline/json_converter.go index 2ed030e6..59404809 100644 --- a/controllers/jenkins/pipeline/json_converter.go +++ b/controllers/jenkins/pipeline/json_converter.go @@ -112,6 +112,7 @@ func (r *JenkinsfileReconciler) reconcileJenkinsfileEditMode(pip *v1alpha3.Pipel // Users are able to clean jenkinsfile if jenkinsfile != "" { var toJSONResult core.GenericResult + jenkinsfile = strings.ReplaceAll(jenkinsfile, "\\", "\\\\") // escape backslash if toJSONResult, err = coreClient.ToJSON(jenkinsfile); err != nil || toJSONResult.GetStatus() != "success" { r.log.Error(err, "failed to convert jenkinsfile to json format") if err != nil { @@ -168,9 +169,13 @@ func (r *JenkinsfileReconciler) reconcileJSONEditMode(pip *v1alpha3.Pipeline, pi err = r.updateAnnotations(pip.Annotations, pipelineKey) return } + jenkinsfile := toResult.GetResult() + jenkinsfile = strings.ReplaceAll(jenkinsfile, "\\\\", "\\") // unescape backslash + jenkinsfile = strings.ReplaceAll(jenkinsfile, `\'`, `'`) // unescape single quote + pip.Annotations[v1alpha3.PipelineJenkinsfileEditModeAnnoKey] = "" pip.Annotations[v1alpha3.PipelineJenkinsfileValidateAnnoKey] = v1alpha3.PipelineJenkinsfileValidateSuccess - err = r.updateAnnotationsAndJenkinsfile(pip.Annotations, toResult.GetResult(), pipelineKey) + err = r.updateAnnotationsAndJenkinsfile(pip.Annotations, jenkinsfile, pipelineKey) } return } diff --git a/pkg/api/devops/v1alpha3/steptemplate_render.go b/pkg/api/devops/v1alpha3/steptemplate_render.go index 5a8cf324..004d55e3 100644 --- a/pkg/api/devops/v1alpha3/steptemplate_render.go +++ b/pkg/api/devops/v1alpha3/steptemplate_render.go @@ -137,6 +137,10 @@ func dslRender(dslTpl string, param map[string]interface{}, secret *v1.Secret) ( func shellRender(shellTpl string, param map[string]interface{}, secret *v1.Secret) (output string, err error) { if output, err = dslRender(shellTpl, param, secret); err == nil { + escapedOutput := strings.ReplaceAll(output, `\`, `\\`) + escapedOutput = strings.ReplaceAll(escapedOutput, "\n", "\\n") + escapedOutput = strings.ReplaceAll(escapedOutput, `"`, `\"`) + output = fmt.Sprintf(`{ "arguments": [ { @@ -148,7 +152,7 @@ func shellRender(shellTpl string, param map[string]interface{}, secret *v1.Secre } ], "name": "sh" -}`, strings.ReplaceAll(output, "\n", "\\n")) +}`, escapedOutput) } return } diff --git a/pkg/api/devops/v1alpha3/steptemplate_render_test.go b/pkg/api/devops/v1alpha3/steptemplate_render_test.go index b429d6cd..ab9cf324 100644 --- a/pkg/api/devops/v1alpha3/steptemplate_render_test.go +++ b/pkg/api/devops/v1alpha3/steptemplate_render_test.go @@ -28,8 +28,16 @@ import ( func Test_handler_stepTemplateRender(t *testing.T) { stepTemplate := &StepTemplateSpec{ - Template: `echo 1`, - Runtime: "shell", + Template: `cat > log.sh << EOF + for ((i=1; i<=1000000; i++)) + do + echo "Log message number \\$i: This is a sample log message." + done +EOF + + cat log.sh + bash log.sh`, + Runtime: "shell", } stepTemplateWithParameters := &StepTemplateSpec{ Template: `docker login -u $USERNAMEVARIABLE -p $PASSWORDVARIABLE @@ -74,7 +82,7 @@ docker build {{.param.context}} -t {{.param.tag}} -f {{.param.dockerfile.path}}` "key": "script", "value": { "isLiteral": true, - "value": "echo 1" + "value": "cat > log.sh << EOF\n for ((i=1; i<=1000000; i++))\n do\n echo \"Log message number \\\\$i: This is a sample log message.\"\n done\nEOF\n\n cat log.sh\n bash log.sh" } } ],