diff --git a/client/task_runner.go b/client/task_runner.go index 60f78c741..c7146018c 100644 --- a/client/task_runner.go +++ b/client/task_runner.go @@ -703,20 +703,6 @@ func (r *TaskRunner) prestart(resultCh chan bool) { return } - // Build the template manager - if r.templateManager == nil { - var err error - r.templateManager, err = NewTaskTemplateManager(r, r.task.Templates, - r.config, r.vaultFuture.Get(), r.taskDir, r.getTaskEnv()) - if err != nil { - err := fmt.Errorf("failed to build task's template manager: %v", err) - r.setState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskSetupFailure).SetSetupError(err).SetFailsTask()) - r.logger.Printf("[ERR] client: alloc %q, task %q %v", r.alloc.ID, r.task.Name, err) - resultCh <- false - return - } - } - for { // Download the task's artifacts if !r.artifactsDownloaded && len(r.task.Artifacts) > 0 { @@ -746,6 +732,20 @@ func (r *TaskRunner) prestart(resultCh chan bool) { return } + // Build the template manager + if r.templateManager == nil { + var err error + r.templateManager, err = NewTaskTemplateManager(r, r.task.Templates, + r.config, r.vaultFuture.Get(), r.taskDir, r.getTaskEnv()) + if err != nil { + err := fmt.Errorf("failed to build task's template manager: %v", err) + r.setState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskSetupFailure).SetSetupError(err).SetFailsTask()) + r.logger.Printf("[ERR] client: alloc %q, task %q %v", r.alloc.ID, r.task.Name, err) + resultCh <- false + return + } + } + // Block for consul-template // TODO Hooks should register themselves as blocking and then we can // perioidcally enumerate what we are still blocked on diff --git a/client/task_runner_test.go b/client/task_runner_test.go index 7db4f7ef7..adc1ca4fd 100644 --- a/client/task_runner_test.go +++ b/client/task_runner_test.go @@ -935,6 +935,84 @@ func TestTaskRunner_Template_Block(t *testing.T) { } } +func TestTaskRunner_Template_Artifact(t *testing.T) { + dir, err := os.Getwd() + if err != nil { + t.Fatal("bad: %v", err) + } + + ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Join(dir, "..")))) + defer ts.Close() + + alloc := mock.Alloc() + task := alloc.Job.TaskGroups[0].Tasks[0] + task.Driver = "mock_driver" + task.Config = map[string]interface{}{ + "exit_code": "0", + "run_for": "1s", + } + // Create an allocation that has a task that renders a template from an + // artifact + f1 := "CHANGELOG.md" + artifact := structs.TaskArtifact{ + GetterSource: fmt.Sprintf("%s/%s", ts.URL, f1), + } + task.Artifacts = []*structs.TaskArtifact{&artifact} + task.Templates = []*structs.Template{ + { + SourcePath: "CHANGELOG.md", + DestPath: "local/test", + ChangeMode: structs.TemplateChangeModeNoop, + }, + } + + upd, tr := testTaskRunnerFromAlloc(false, alloc) + tr.MarkReceived() + defer tr.Destroy(structs.NewTaskEvent(structs.TaskKilled)) + defer tr.ctx.AllocDir.Destroy() + + go tr.Run() + + select { + case <-tr.WaitCh(): + case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second): + t.Fatalf("timeout") + } + + if len(upd.events) != 4 { + t.Fatalf("should have 4 updates: %#v", upd.events) + } + + if upd.state != structs.TaskStateDead { + t.Fatalf("TaskState %v; want %v", upd.state, structs.TaskStateDead) + } + + if upd.events[0].Type != structs.TaskReceived { + t.Fatalf("First Event was %v; want %v", upd.events[0].Type, structs.TaskReceived) + } + + if upd.events[1].Type != structs.TaskDownloadingArtifacts { + t.Fatalf("Second Event was %v; want %v", upd.events[1].Type, structs.TaskDownloadingArtifacts) + } + + if upd.events[2].Type != structs.TaskStarted { + t.Fatalf("Third Event was %v; want %v", upd.events[2].Type, structs.TaskStarted) + } + + if upd.events[3].Type != structs.TaskTerminated { + t.Fatalf("Fourth Event was %v; want %v", upd.events[3].Type, structs.TaskTerminated) + } + + // Check that both files exist. + taskDir := tr.ctx.AllocDir.TaskDirs[task.Name] + if _, err := os.Stat(filepath.Join(taskDir, f1)); err != nil { + t.Fatalf("%v not downloaded", f1) + } + if _, err := os.Stat(filepath.Join(taskDir, allocdir.TaskLocal, "test")); err != nil { + t.Fatalf("template not rendered") + } +} + func TestTaskRunner_Template_NewVaultToken(t *testing.T) { alloc := mock.Alloc() task := alloc.Job.TaskGroups[0].Tasks[0]