Skip to content

Commit 1cdc3e8

Browse files
johnstcnmafredri
andauthored
feat!: extract provisioner tags from coder_workspace_tags data source (#15578)
Relates to #15087 and #15427 - Extracts provisioner job tags from `coder_workspace_tags` on template version creation using `provisioner/terraform/tfparse` added in #15236 - Drops a WARN log in coderd if no matching provisioners found. - Also drops a warning message in the CLI if no provisioners are found. - To support both CLI and UI warnings, added a `codersdk.MatchedProvisioners` struct to the `TemplateVersion` response containing details of how many provisioners were around at the time of the insert. Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
1 parent 648cdd0 commit 1cdc3e8

File tree

11 files changed

+694
-95
lines changed

11 files changed

+694
-95
lines changed

cli/templatepush.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"bufio"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"io"
@@ -415,6 +416,29 @@ func createValidTemplateVersion(inv *serpent.Invocation, args createValidTemplat
415416
if err != nil {
416417
return nil, err
417418
}
419+
var tagsJSON strings.Builder
420+
if err := json.NewEncoder(&tagsJSON).Encode(version.Job.Tags); err != nil {
421+
// Fall back to the less-pretty string representation.
422+
tagsJSON.Reset()
423+
_, _ = tagsJSON.WriteString(fmt.Sprintf("%v", version.Job.Tags))
424+
}
425+
if version.MatchedProvisioners.Count == 0 {
426+
cliui.Warnf(inv.Stderr, `No provisioners are available to handle the job!
427+
Please contact your deployment administrator for assistance.
428+
Details:
429+
Provisioner job ID : %s
430+
Requested tags : %s
431+
`, version.Job.ID, tagsJSON.String())
432+
} else if version.MatchedProvisioners.Available == 0 {
433+
cliui.Warnf(inv.Stderr, `All available provisioner daemons have been silent for a while.
434+
Your build will proceed once they become available.
435+
If this persists, please contact your deployment administrator for assistance.
436+
Details:
437+
Provisioner job ID : %s
438+
Requested tags : %s
439+
Most recently seen : %s
440+
`, version.Job.ID, strings.TrimSpace(tagsJSON.String()), version.MatchedProvisioners.MostRecentlySeen.Time)
441+
}
418442

419443
err = cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
420444
Fetch: func() (codersdk.ProvisionerJob, error) {

cli/templatepush_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"runtime"
99
"strings"
1010
"testing"
11+
"time"
1112

1213
"github.com/google/uuid"
1314
"github.com/stretchr/testify/assert"
@@ -16,9 +17,12 @@ import (
1617
"github.com/coder/coder/v2/cli/clitest"
1718
"github.com/coder/coder/v2/coderd/coderdtest"
1819
"github.com/coder/coder/v2/coderd/database"
20+
"github.com/coder/coder/v2/coderd/database/dbtestutil"
1921
"github.com/coder/coder/v2/coderd/rbac"
2022
"github.com/coder/coder/v2/codersdk"
2123
"github.com/coder/coder/v2/provisioner/echo"
24+
"github.com/coder/coder/v2/provisioner/terraform/tfparse"
25+
"github.com/coder/coder/v2/provisionersdk"
2226
"github.com/coder/coder/v2/provisionersdk/proto"
2327
"github.com/coder/coder/v2/pty/ptytest"
2428
"github.com/coder/coder/v2/testutil"
@@ -406,6 +410,88 @@ func TestTemplatePush(t *testing.T) {
406410
t.Run("ProvisionerTags", func(t *testing.T) {
407411
t.Parallel()
408412

413+
t.Run("WorkspaceTagsTerraform", func(t *testing.T) {
414+
t.Parallel()
415+
ctx := testutil.Context(t, testutil.WaitShort)
416+
417+
// Start an instance **without** a built-in provisioner.
418+
// We're not actually testing that the Terraform applies.
419+
// What we test is that a provisioner job is created with the expected
420+
// tags based on the __content__ of the Terraform.
421+
store, ps := dbtestutil.NewDB(t)
422+
client := coderdtest.New(t, &coderdtest.Options{
423+
Database: store,
424+
Pubsub: ps,
425+
})
426+
427+
owner := coderdtest.CreateFirstUser(t, client)
428+
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
429+
430+
// Create a tar file with some pre-defined content
431+
tarFile := testutil.CreateTar(t, map[string]string{
432+
"main.tf": `
433+
variable "a" {
434+
type = string
435+
default = "1"
436+
}
437+
data "coder_parameter" "b" {
438+
type = string
439+
default = "2"
440+
}
441+
resource "null_resource" "test" {}
442+
data "coder_workspace_tags" "tags" {
443+
tags = {
444+
"foo": "bar",
445+
"a": var.a,
446+
"b": data.coder_parameter.b.value,
447+
}
448+
}`,
449+
})
450+
451+
// Write the tar file to disk.
452+
tempDir := t.TempDir()
453+
err := tfparse.WriteArchive(tarFile, "application/x-tar", tempDir)
454+
require.NoError(t, err)
455+
456+
// Run `coder templates push`
457+
templateName := strings.ReplaceAll(testutil.GetRandomName(t), "_", "-")
458+
var stdout, stderr strings.Builder
459+
inv, root := clitest.New(t, "templates", "push", templateName, "-d", tempDir, "--yes")
460+
inv.Stdout = &stdout
461+
inv.Stderr = &stderr
462+
clitest.SetupConfig(t, templateAdmin, root)
463+
464+
// Don't forget to clean up!
465+
cancelCtx, cancel := context.WithCancel(ctx)
466+
t.Cleanup(cancel)
467+
done := make(chan error)
468+
go func() {
469+
done <- inv.WithContext(cancelCtx).Run()
470+
}()
471+
472+
// Assert that a provisioner job was created with the desired tags.
473+
wantTags := database.StringMap(provisionersdk.MutateTags(uuid.Nil, map[string]string{
474+
"foo": "bar",
475+
"a": "1",
476+
"b": "2",
477+
}))
478+
require.Eventually(t, func() bool {
479+
jobs, err := store.GetProvisionerJobsCreatedAfter(ctx, time.Time{})
480+
if !assert.NoError(t, err) {
481+
return false
482+
}
483+
if len(jobs) == 0 {
484+
return false
485+
}
486+
return assert.EqualValues(t, wantTags, jobs[0].Tags)
487+
}, testutil.WaitShort, testutil.IntervalSlow)
488+
489+
cancel()
490+
<-done
491+
492+
require.Contains(t, stderr.String(), "No provisioners are available to handle the job!")
493+
})
494+
409495
t.Run("ChangeTags", func(t *testing.T) {
410496
t.Parallel()
411497

coderd/apidoc/docs.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy