Skip to content

Commit

Permalink
fix(api,worker): send spawn infos when job is failed to show the reas…
Browse files Browse the repository at this point in the history
…on (#5124)
  • Loading branch information
fsamin authored Apr 10, 2020
1 parent 2130ed2 commit 4389d5a
Show file tree
Hide file tree
Showing 16 changed files with 74 additions and 41 deletions.
2 changes: 1 addition & 1 deletion engine/api/api_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func (api *API) InitRouter() {
r.Handle("/queue/workflows/{permJobID}/book", Scope(sdk.AuthConsumerScopeRunExecution), r.POST(api.postBookWorkflowJobHandler, EnableTracing(), MaintenanceAware()), r.DELETE(api.deleteBookWorkflowJobHandler, EnableTracing(), MaintenanceAware()))
r.Handle("/queue/workflows/{permJobID}/infos", Scope(sdk.AuthConsumerScopeRunExecution), r.GET(api.getWorkflowJobHandler, EnableTracing(), MaintenanceAware()))
r.Handle("/queue/workflows/{permJobID}/vulnerability", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postVulnerabilityReportHandler, EnableTracing(), MaintenanceAware()))
r.Handle("/queue/workflows/{permJobID}/spawn/infos", Scope(sdk.AuthConsumerScopeRunExecution), r.POST(r.Asynchronous(api.postSpawnInfosWorkflowJobHandler, 1), EnableTracing(), MaintenanceAware()))
r.Handle("/queue/workflows/{permJobID}/spawn/infos", Scope(sdk.AuthConsumerScopeRunExecution), r.POST(api.postSpawnInfosWorkflowJobHandler, EnableTracing(), MaintenanceAware()))
r.Handle("/queue/workflows/{permJobID}/result", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobResultHandler, EnableTracing(), MaintenanceAware()))
r.Handle("/queue/workflows/{permJobID}/log", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobLogsHandler, MaintenanceAware()))
r.Handle("/queue/workflows/log/service", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(r.Asynchronous(api.postWorkflowJobServiceLogsHandler, 1), MaintenanceAware()))
Expand Down
4 changes: 0 additions & 4 deletions engine/api/router_middleware_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req *
if ok {
claims := jwt.Claims.(*sdk.AuthSessionJWTClaims)
sessionID := claims.StandardClaims.Id
log.Debug("authMiddleware> try to retrieve session for given jwt with id: %s", sessionID)
// Check for session based on jwt from context
session, err = authentication.CheckSession(ctx, api.mustDB(), sessionID)
if err != nil {
Expand All @@ -65,7 +64,6 @@ func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req *

if session != nil {
ctx = context.WithValue(ctxWithJWT, contextSession, session)
log.Debug("authMiddleware> try to retrieve consumer for given session with id: %s", session.ConsumerID)
// Load auth consumer for current session in database with authentified user and contacts
c, err := authentication.LoadConsumerByID(ctx, api.mustDB(), session.ConsumerID,
authentication.LoadConsumerOptions.WithAuthentifiedUser)
Expand Down Expand Up @@ -102,8 +100,6 @@ func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req *
}

if consumer != nil {
log.Debug("authMiddleware> check scope for current consumer")

ctx = context.WithValue(ctx, contextAPIConsumer, consumer)

// Checks scopes, one of expected scopes should be in actual scopes
Expand Down
13 changes: 11 additions & 2 deletions engine/api/workflow/execute_node_job_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@ func UpdateNodeJobRunStatus(ctx context.Context, db gorp.SqlExecutor, store cach
report.Merge(ctx, r)
return report, err
}

spawnInfos, err := LoadNodeRunJobInfo(ctx, db, job.ID)
if err != nil {
return report, sdk.WrapError(err, "unable to load spawn infos for runJob: %d", job.ID)
}
job.SpawnInfos = spawnInfos

syncJobInNodeRun(nodeRun, job, stageIndex)

if job.Status != sdk.StatusStopped {
Expand All @@ -209,8 +216,10 @@ func UpdateNodeJobRunStatus(ctx context.Context, db gorp.SqlExecutor, store cach
}

// AddSpawnInfosNodeJobRun saves spawn info before starting worker
func AddSpawnInfosNodeJobRun(db gorp.SqlExecutor, jobID int64, infos []sdk.SpawnInfo) error {
func AddSpawnInfosNodeJobRun(db gorp.SqlExecutor, nodeID, jobID int64, infos []sdk.SpawnInfo) error {

wnjri := &sdk.WorkflowNodeJobRunInfo{
WorkflowNodeRunID: nodeID,
WorkflowNodeJobRunID: jobID,
SpawnInfos: PrepareSpawnInfos(infos),
}
Expand Down Expand Up @@ -276,7 +285,7 @@ func TakeNodeJobRun(ctx context.Context, db gorp.SqlExecutor, store cache.Store,
return nil, nil, sdk.WrapError(err, "cannot update worker_id in node job run %d", jobID)
}

if err := AddSpawnInfosNodeJobRun(db, jobID, PrepareSpawnInfos(infos)); err != nil {
if err := AddSpawnInfosNodeJobRun(db, job.WorkflowNodeRunID, jobID, PrepareSpawnInfos(infos)); err != nil {
return nil, nil, sdk.WrapError(err, "cannot save spawn info on node job run %d", jobID)
}

Expand Down
5 changes: 3 additions & 2 deletions engine/api/workflow/execute_node_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func syncJobInNodeRun(n *sdk.WorkflowNodeRun, j *sdk.WorkflowNodeJobRun, stageIn
rj.Job = j.Job
rj.Header = j.Header
rj.Parameters = j.Parameters
rj.SpawnInfos = j.SpawnInfos
}
}
}
Expand Down Expand Up @@ -535,7 +536,7 @@ jobLoop:
}
next()

if err := AddSpawnInfosNodeJobRun(db, wjob.ID, PrepareSpawnInfos(wjob.SpawnInfos)); err != nil {
if err := AddSpawnInfosNodeJobRun(db, wjob.WorkflowNodeRunID, wjob.ID, PrepareSpawnInfos(wjob.SpawnInfos)); err != nil {
return nil, sdk.WrapError(err, "cannot save spawn info job %d", wjob.ID)
}

Expand Down Expand Up @@ -932,7 +933,7 @@ func stopWorkflowNodeJobRun(ctx context.Context, dbFunc func() *gorp.DbMap, stor
return report
}

if err := AddSpawnInfosNodeJobRun(tx, njr.ID, []sdk.SpawnInfo{stopInfos}); err != nil {
if err := AddSpawnInfosNodeJobRun(tx, njr.WorkflowNodeRunID, njr.ID, []sdk.SpawnInfo{stopInfos}); err != nil {
chanErr <- sdk.WrapError(err, "Cannot save spawn info job %d", njr.ID)
tx.Rollback()
wg.Done()
Expand Down
2 changes: 1 addition & 1 deletion engine/api/workflow/run_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ queueRun:
}

//AddSpawnInfosNodeJobRun
err := workflow.AddSpawnInfosNodeJobRun(db, j.ID, []sdk.SpawnInfo{
err := workflow.AddSpawnInfosNodeJobRun(db, j.WorkflowNodeRunID, j.ID, []sdk.SpawnInfo{
{
APITime: time.Now(),
RemoteTime: time.Now(),
Expand Down
19 changes: 9 additions & 10 deletions engine/api/workflow_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,14 @@ func (api *API) postVulnerabilityReportHandler() service.Handler {
}
}

func (api *API) postSpawnInfosWorkflowJobHandler() service.AsynchronousHandler {
return func(ctx context.Context, r *http.Request) error {
func (api *API) postSpawnInfosWorkflowJobHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
id, err := requestVarInt(r, "permJobID")
if err != nil {
return sdk.WrapError(err, "invalid id")
}

if ok := isHatchery(ctx); !ok {
if ok := isHatchery(ctx) || isWorker(ctx); !ok {
return sdk.WithStack(sdk.ErrForbidden)
}

Expand All @@ -318,13 +318,12 @@ func (api *API) postSpawnInfosWorkflowJobHandler() service.AsynchronousHandler {
}
defer tx.Rollback() // nolint

if _, err := workflow.LoadNodeJobRun(ctx, tx, api.Cache, id); err != nil {
if !sdk.ErrorIs(err, sdk.ErrWorkflowNodeRunJobNotFound) {
return err
}
return nil
jobRun, err := workflow.LoadNodeJobRun(ctx, tx, api.Cache, id)
if err != nil {
return err
}
if err := workflow.AddSpawnInfosNodeJobRun(tx, id, s); err != nil {

if err := workflow.AddSpawnInfosNodeJobRun(tx, jobRun.WorkflowNodeRunID, jobRun.ID, s); err != nil {
return err
}

Expand Down Expand Up @@ -435,7 +434,7 @@ func postJobResult(ctx context.Context, dbFunc func(context.Context) *gorp.DbMap
Message: sdk.SpawnMsg{ID: sdk.MsgSpawnInfoWorkerEnd.ID, Args: []interface{}{wr.Name, res.Duration}},
}}

if err := workflow.AddSpawnInfosNodeJobRun(tx, job.ID, workflow.PrepareSpawnInfos(infos)); err != nil {
if err := workflow.AddSpawnInfosNodeJobRun(tx, job.WorkflowNodeRunID, job.ID, workflow.PrepareSpawnInfos(infos)); err != nil {
return nil, sdk.WrapError(err, "Cannot save spawn info job %d", job.ID)
}

Expand Down
2 changes: 1 addition & 1 deletion engine/api/workflow_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ func Test_postWorkflowJobTestsResultsHandler(t *testing.T) {
req := assets.NewJWTAuthentifiedRequest(t, ctx.hatcheryToken, "POST", uri, info)
rec := httptest.NewRecorder()
router.Mux.ServeHTTP(rec, req)
require.Equal(t, 202, rec.Code)
require.Equal(t, 204, rec.Code)

//spawn
uri = router.GetRoute("POST", api.postTakeWorkflowJobHandler, map[string]string{
Expand Down
4 changes: 2 additions & 2 deletions engine/worker/internal/action/test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ func (_ TestWorker) Register(ctx context.Context) error {
func (_ TestWorker) Take(ctx context.Context, job sdk.WorkflowNodeJobRun) error {
return nil
}
func (_ TestWorker) ProcessJob(job sdk.WorkflowNodeJobRunData) (sdk.Result, error) {
return sdk.Result{}, nil
func (_ TestWorker) ProcessJob(job sdk.WorkflowNodeJobRunData) sdk.Result {
return sdk.Result{}
}
func (w TestWorker) SendLog(ctx context.Context, level workerruntime.Level, format string) {
w.t.Log("SendLog> [" + string(level) + "] " + format)
Expand Down
29 changes: 17 additions & 12 deletions engine/worker/internal/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func processActionVariables(a *sdk.Action, parent *sdk.Action, jobParameters []s
// replaces placeholder in all children recursively
for i := range a.Actions {
if err := processActionVariables(&a.Actions[i], a, jobParameters, secrets); err != nil {
return nil
return err
}
}

Expand All @@ -109,7 +109,7 @@ func (w *CurrentWorker) replaceVariablesPlaceholder(a *sdk.Action, params []sdk.
return nil
}

func (w *CurrentWorker) runJob(ctx context.Context, a *sdk.Action, jobID int64, secrets []sdk.Variable) (sdk.Result, error) {
func (w *CurrentWorker) runJob(ctx context.Context, a *sdk.Action, jobID int64, secrets []sdk.Variable) sdk.Result {
log.Info(ctx, "runJob> start job %s (%d)", a.Name, jobID)
defer func() { log.Info(ctx, "runJob> job %s (%d)", a.Name, jobID) }()

Expand All @@ -124,7 +124,7 @@ func (w *CurrentWorker) runJob(ctx context.Context, a *sdk.Action, jobID int64,
if err := w.updateStepStatus(ctx, jobID, jobStepIndex, sdk.StatusBuilding); err != nil {
jobResult.Status = sdk.StatusFail
jobResult.Reason = fmt.Sprintf("Cannot update step (%d) status (%s): %v", jobStepIndex, sdk.StatusBuilding, err)
return jobResult, err
return jobResult
}
var stepResult = sdk.Result{
Status: sdk.StatusNeverBuilt,
Expand Down Expand Up @@ -163,7 +163,7 @@ func (w *CurrentWorker) runJob(ctx context.Context, a *sdk.Action, jobID int64,
if err := w.updateStepStatus(ctx, jobID, jobStepIndex, stepResult.Status); err != nil {
jobResult.Status = sdk.StatusFail
jobResult.Reason = fmt.Sprintf("Cannot update step (%d) status (%s): %v", jobStepIndex, sdk.StatusBuilding, err)
return jobResult, err
return jobResult
}
}

Expand All @@ -178,7 +178,7 @@ func (w *CurrentWorker) runJob(ctx context.Context, a *sdk.Action, jobID int64,
if nCriticalFailed > 0 {
jobResult.Status = sdk.StatusFail
}
return jobResult, nil
return jobResult
}

func (w *CurrentWorker) runAction(ctx context.Context, a sdk.Action, jobID int64, secrets []sdk.Variable, actionName string) sdk.Result {
Expand Down Expand Up @@ -459,7 +459,7 @@ func (w *CurrentWorker) setupKeysDirectory(ctx context.Context, jobInfo sdk.Work
return kdFile, kdAbs, nil
}

func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Result, error) {
func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (res sdk.Result) {
ctx := w.currentJob.context
t0 := time.Now()

Expand All @@ -472,6 +472,8 @@ func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Resu
defer cancel()

ctx = workerruntime.SetJobID(ctx, jobInfo.NodeJobRun.ID)
ctx = workerruntime.SetStepOrder(ctx, 0)

// start logger routine with a large buffer
w.logger.logChan = make(chan sdk.Log, 100000)
go func() {
Expand All @@ -484,13 +486,16 @@ func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Resu
log.Error(ctx, "processJob> Drain logs error: %v", err)
}
}()
defer func() {
log.Error(ctx, "processJob> Status: %s | Reason: %s", res.Status, res.Reason)
}()

wdFile, wdAbs, err := w.setupWorkingDirectory(ctx, jobInfo)
if err != nil {
return sdk.Result{
Status: sdk.StatusFail,
Reason: fmt.Sprintf("Error: unable to setup workfing directory: %v", err),
}, err
}
}
ctx = workerruntime.SetWorkingDirectory(ctx, wdFile)
log.Debug("processJob> Setup workspace - %s", wdFile.Name())
Expand All @@ -500,7 +505,7 @@ func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Resu
return sdk.Result{
Status: sdk.StatusFail,
Reason: fmt.Sprintf("Error: unable to setup keys directory: %v", err),
}, err
}
}
ctx = workerruntime.SetKeysDirectory(ctx, kdFile)
log.Debug("processJob> Setup key directory - %s", kdFile.Name())
Expand All @@ -527,8 +532,8 @@ func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Resu
if err := processVariablesAndParameters(&jobInfo.NodeJobRun.Job.Action, jobParameters, jobInfo.Secrets); err != nil {
return sdk.Result{
Status: sdk.StatusFail,
Reason: fmt.Sprintf("Error: cannot process job %s parameters", jobInfo.NodeJobRun.Job.Action.Name),
}, err
Reason: fmt.Sprintf("unable to process job %s: %v", jobInfo.NodeJobRun.Job.Action.Name, err),
}
}

// Add secrets as string or password in ActionBuild.Args
Expand All @@ -544,7 +549,7 @@ func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Resu

w.currentJob.params = jobParameters

res, err := w.runJob(ctx, &jobInfo.NodeJobRun.Job.Action, jobInfo.NodeJobRun.ID, jobInfo.Secrets)
res = w.runJob(ctx, &jobInfo.NodeJobRun.Job.Action, jobInfo.NodeJobRun.ID, jobInfo.Secrets)

if len(res.NewVariables) > 0 {
log.Debug("processJob> new variables: %v", res.NewVariables)
Expand All @@ -563,5 +568,5 @@ func (w *CurrentWorker) ProcessJob(jobInfo sdk.WorkflowNodeJobRunData) (sdk.Resu
log.Error(ctx, "Cannot remove basedir content: %s", err)
}

return res, err
return res
}
14 changes: 12 additions & 2 deletions engine/worker/internal/take.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ func (w *CurrentWorker) Take(ctx context.Context, job sdk.WorkflowNodeJobRun) er
}(cancel, job.ID, tick)

//Run !
res, err := w.ProcessJob(*info)
// We keep the err for later usage
res := w.ProcessJob(*info)
tick.Stop()

res.RemoteTime = time.Now()
Expand All @@ -92,6 +91,17 @@ func (w *CurrentWorker) Take(ctx context.Context, job sdk.WorkflowNodeJobRun) er
//Wait until the logchannel is empty
res.BuildID = job.ID

// Send the reason as a spawninfo
if res.Status != sdk.StatusSuccess && res.Reason != "" {
infos := []sdk.SpawnInfo{{
RemoteTime: time.Now(),
Message: sdk.SpawnMsg{ID: sdk.MsgWorkflowError.ID, Args: []interface{}{res.Reason}},
}}
if err := w.Client().QueueJobSendSpawnInfo(ctx, job.ID, infos); err != nil {
log.Error(ctx, "processJob> Unable to send spawn info: %v", err)
}
}

var lasterr error
for try := 1; try <= 10; try++ {
log.Info(ctx, "takeWorkflowJob> Sending build result...")
Expand Down
2 changes: 1 addition & 1 deletion engine/worker/pkg/workerruntime/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ type Runtime interface {
Name() string
Register(ctx context.Context) error
Take(ctx context.Context, job sdk.WorkflowNodeJobRun) error
ProcessJob(job sdk.WorkflowNodeJobRunData) (sdk.Result, error)
ProcessJob(job sdk.WorkflowNodeJobRunData) sdk.Result
SendLog(ctx context.Context, level Level, format string)
InstallKey(key sdk.Variable) (*KeyResponse, error)
InstallKeyTo(key sdk.Variable, destinationPath string) (*KeyResponse, error)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ require (
github.com/spf13/viper v1.4.0
github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.4.0
github.com/stretchr/testify v1.5.1
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect
github.com/ugorji/go v1.1.7 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 h1:hNna6Fi0eP1f2sMBe/rJicDmaHmoXGe1Ta84FPYHLuE=
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
Expand Down
1 change: 1 addition & 0 deletions sdk/interpolate/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/ovh/cds/sdk/interpolate
require (
github.com/aokoli/goutils v1.1.0
github.com/huandu/xstrings v1.2.0
github.com/stretchr/testify v1.5.1
)

go 1.13
10 changes: 10 additions & 0 deletions sdk/interpolate/go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
github.com/aokoli/goutils v1.1.0 h1:jy4ghdcYvs5EIoGssZNslIASX5m+KNMfyyKvRQ0TEVE=
github.com/aokoli/goutils v1.1.0/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
4 changes: 2 additions & 2 deletions sdk/interpolate/interpolate.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,12 @@ func Do(input string, vars map[string]string) (string, error) {

t, err := template.New("input").Funcs(InterpolateHelperFuncs).Parse(input)
if err != nil {
return "", fmt.Errorf("Invalid template format: %s", err.Error())
return "", fmt.Errorf("invalid template format \"%s\": %s", input, err.Error())
}

var buff bytes.Buffer
if err := t.Execute(&buff, data); err != nil {
return "", fmt.Errorf("Failed to execute template: %s", err.Error())
return "", fmt.Errorf("failed to execute template: %s", err.Error())
}

return buff.String(), nil
Expand Down

0 comments on commit 4389d5a

Please sign in to comment.