Skip to content

Commit e401764

Browse files
committed
feat: persist generated coder_app id
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent 725bc37 commit e401764

File tree

9 files changed

+83
-28
lines changed

9 files changed

+83
-28
lines changed

coderd/agentapi/apps.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (a *AppsAPI) BatchUpdateAppHealths(ctx context.Context, req *agentproto.Bat
9292
Health: app.Health,
9393
})
9494
if err != nil {
95-
return nil, xerrors.Errorf("update workspace app health for app %q (%q): %w", err, app.ID, app.Slug)
95+
return nil, xerrors.Errorf("update workspace app health for app %q (%q): %w", app.ID, app.Slug, err)
9696
}
9797
}
9898

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2595,8 +2595,16 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
25952595
openIn = database.WorkspaceAppOpenInSlimWindow
25962596
}
25972597

2598+
if app.Id == "" || app.Id == uuid.Nil.String() {
2599+
app.Id = uuid.NewString()
2600+
}
2601+
id, err := uuid.Parse(app.Id)
2602+
if err != nil {
2603+
return xerrors.Errorf("parse app uuid: %w", err)
2604+
}
2605+
25982606
dbApp, err := db.InsertWorkspaceApp(ctx, database.InsertWorkspaceAppParams{
2599-
ID: uuid.New(),
2607+
ID: id,
26002608
CreatedAt: dbtime.Now(),
26012609
AgentID: dbAgent.ID,
26022610
Slug: slug,

coderd/workspaceagents_test.go

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

33
import (
44
"context"
5+
"database/sql"
56
"encoding/json"
67
"fmt"
78
"maps"
@@ -1506,39 +1507,52 @@ func TestWorkspaceAgentAppHealth(t *testing.T) {
15061507
t.Parallel()
15071508
client, db := coderdtest.NewWithDatabase(t, nil)
15081509
user := coderdtest.CreateFirstUser(t, client)
1509-
apps := []*proto.App{
1510-
{
1511-
Slug: "code-server",
1512-
Command: "some-command",
1513-
Url: "http://localhost:3000",
1514-
Icon: "/code.svg",
1515-
},
1516-
{
1517-
Slug: "code-server-2",
1518-
DisplayName: "code-server-2",
1519-
Command: "some-command",
1520-
Url: "http://localhost:3000",
1521-
Icon: "/code.svg",
1522-
Healthcheck: &proto.Healthcheck{
1523-
Url: "http://localhost:3000",
1524-
Interval: 5,
1525-
Threshold: 6,
1526-
},
1527-
},
1528-
}
1510+
1511+
// When using WithAgent() here and setting some *proto.App instances on the agent, Do() ends up trying to insert duplicate records.
15291512
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
15301513
OrganizationID: user.OrganizationID,
15311514
OwnerID: user.UserID,
1532-
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
1533-
agents[0].Apps = apps
1534-
return agents
15351515
}).Do()
15361516

1517+
res := dbgen.WorkspaceResource(t, db, database.WorkspaceResource{JobID: r.Build.JobID})
1518+
agent := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{ResourceID: res.ID})
1519+
1520+
// It's simpler to call db.InsertWorkspaceApp directly than dbgen.WorkspaceApp because it's more terse and direct;
1521+
// the latter sets a bunch of defaults which make this test hard.
1522+
_, err := db.InsertWorkspaceApp(dbauthz.AsSystemRestricted(t.Context()), database.InsertWorkspaceAppParams{
1523+
ID: uuid.New(),
1524+
Slug: "code-server",
1525+
AgentID: agent.ID,
1526+
Icon: "/code.svg",
1527+
Command: sql.NullString{String: "some-command", Valid: true},
1528+
Url: sql.NullString{String: "http://localhost:3000", Valid: true},
1529+
SharingLevel: database.AppSharingLevelOwner,
1530+
Health: database.WorkspaceAppHealthDisabled,
1531+
OpenIn: database.WorkspaceAppOpenInWindow,
1532+
})
1533+
require.NoError(t, err)
1534+
_, err = db.InsertWorkspaceApp(dbauthz.AsSystemRestricted(t.Context()), database.InsertWorkspaceAppParams{
1535+
ID: uuid.New(),
1536+
Slug: "code-server-2",
1537+
DisplayName: "code-server-2",
1538+
AgentID: agent.ID,
1539+
Icon: "/code.svg",
1540+
Command: sql.NullString{String: "some-command", Valid: true},
1541+
Url: sql.NullString{String: "http://localhost:3000", Valid: true},
1542+
HealthcheckInterval: 5,
1543+
HealthcheckUrl: "http://localhost:3000",
1544+
HealthcheckThreshold: 6,
1545+
Health: database.WorkspaceAppHealthInitializing,
1546+
SharingLevel: database.AppSharingLevelOwner,
1547+
OpenIn: database.WorkspaceAppOpenInWindow,
1548+
})
1549+
require.NoError(t, err)
1550+
15371551
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
15381552
defer cancel()
15391553

15401554
agentClient := agentsdk.New(client.URL)
1541-
agentClient.SetSessionToken(r.AgentToken)
1555+
agentClient.SetSessionToken(agent.AuthToken.String())
15421556
conn, err := agentClient.ConnectRPC(ctx)
15431557
require.NoError(t, err)
15441558
defer func() {

provisioner/terraform/resources.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88

99
"github.com/awalterschulze/gographviz"
10+
"github.com/google/uuid"
1011
tfjson "github.com/hashicorp/terraform-json"
1112
"github.com/mitchellh/mapstructure"
1213
"golang.org/x/xerrors"
@@ -93,6 +94,7 @@ type agentDisplayAppsAttributes struct {
9394

9495
// A mapping of attributes on the "coder_app" resource.
9596
type agentAppAttributes struct {
97+
ID string `mapstructure:"id"`
9698
AgentID string `mapstructure:"agent_id"`
9799
// Slug is required in terraform, but to avoid breaking existing users we
98100
// will default to the resource name if it is not specified.
@@ -522,7 +524,17 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
522524
continue
523525
}
524526

527+
id := attrs.ID
528+
if id == "" {
529+
// This should never happen since the "id" attribute is set on creation:
530+
// https://github.com/coder/terraform-provider-coder/blob/cfa101df4635e405e66094fa7779f9a89d92f400/provider/app.go#L37
531+
logger.Warn(ctx, "coder_app's id was unexpectedly empty", slog.F("name", attrs.Name))
532+
533+
id = uuid.NewString()
534+
}
535+
525536
agent.Apps = append(agent.Apps, &proto.App{
537+
Id: id,
526538
Slug: attrs.Slug,
527539
DisplayName: attrs.DisplayName,
528540
Command: attrs.Command,

provisioner/terraform/resources_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,9 @@ func TestConvertResources(t *testing.T) {
967967
if agent.GetInstanceId() != "" {
968968
agent.Auth = &proto.Agent_InstanceId{}
969969
}
970+
for _, app := range agent.Apps {
971+
app.Id = ""
972+
}
970973
}
971974
}
972975

@@ -1037,6 +1040,9 @@ func TestConvertResources(t *testing.T) {
10371040
if agent.GetInstanceId() != "" {
10381041
agent.Auth = &proto.Agent_InstanceId{}
10391042
}
1043+
for _, app := range agent.Apps {
1044+
app.Id = ""
1045+
}
10401046
}
10411047
}
10421048
// Convert expectedNoMetadata and resources into a

provisionerd/proto/version.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import "github.com/coder/coder/v2/apiversion"
3737
// - Add new field named `scheduling` to `Prebuild`, with fields for timezone
3838
// and schedule rules to define cron-based scaling of prebuilt workspace
3939
// instances based on time patterns.
40+
// - Added new field named `id` to `App`, which transports the ID generated by the coder_app provider to be persisted.
4041
const (
4142
CurrentMajor = 1
4243
CurrentMinor = 7

provisionersdk/proto/provisioner.pb.go

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

provisionersdk/proto/provisioner.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ message App {
266266
bool hidden = 11;
267267
AppOpenIn open_in = 12;
268268
string group = 13;
269+
string id = 14;
269270
}
270271

271272
// Healthcheck represents configuration for checking for app readiness.

site/e2e/provisionerGenerated.ts

Lines changed: 4 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