Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e401764

Browse files
committed
feat: persist generated coder_app id
Signed-off-by: Danny Kopping <[email protected]>
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)