Skip to content

Commit c0e169e

Browse files
authored
feat: support custom order of agent metadata (#12066)
1 parent e659957 commit c0e169e

23 files changed

+438
-316
lines changed

coderd/database/dbmem/dbmem.go

+1
Original file line numberDiff line numberDiff line change
@@ -5687,6 +5687,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentMetadata(_ context.Context, arg databa
56875687
Key: arg.Key,
56885688
Timeout: arg.Timeout,
56895689
Interval: arg.Interval,
5690+
DisplayOrder: arg.DisplayOrder,
56905691
}
56915692

56925693
q.workspaceAgentMetadata = append(q.workspaceAgentMetadata, metadatum)

coderd/database/dump.sql

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE workspace_agent_metadata DROP COLUMN display_order;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ALTER TABLE workspace_agent_metadata ADD COLUMN display_order integer NOT NULL DEFAULT 0;
2+
3+
COMMENT ON COLUMN workspace_agent_metadata.display_order
4+
IS 'Specifies the order in which to display agent metadata in user interfaces.';

coderd/database/models.go

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

+7-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspaceagents.sql

+3-2
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ INSERT INTO
103103
key,
104104
script,
105105
timeout,
106-
interval
106+
interval,
107+
display_order
107108
)
108109
VALUES
109-
($1, $2, $3, $4, $5, $6);
110+
($1, $2, $3, $4, $5, $6, $7);
110111

111112
-- name: UpdateWorkspaceAgentMetadata :exec
112113
WITH metadata AS (

coderd/provisionerdserver/provisionerdserver.go

+1
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
15381538
Key: md.Key,
15391539
Timeout: md.Timeout,
15401540
Interval: md.Interval,
1541+
DisplayOrder: int32(md.Order),
15411542
}
15421543
err := db.InsertWorkspaceAgentMetadata(ctx, p)
15431544
if err != nil {

coderd/workspaceagents.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -1590,10 +1590,18 @@ func appendUnique[T comparable](dst, src []T) []T {
15901590
}
15911591

15921592
func convertWorkspaceAgentMetadata(db []database.WorkspaceAgentMetadatum) []codersdk.WorkspaceAgentMetadata {
1593+
// Sort the input database slice by DisplayOrder and then by Key before processing
1594+
sort.Slice(db, func(i, j int) bool {
1595+
if db[i].DisplayOrder == db[j].DisplayOrder {
1596+
return db[i].Key < db[j].Key
1597+
}
1598+
return db[i].DisplayOrder < db[j].DisplayOrder
1599+
})
1600+
15931601
// An empty array is easier for clients to handle than a null.
1594-
result := make([]codersdk.WorkspaceAgentMetadata, 0, len(db))
1595-
for _, datum := range db {
1596-
result = append(result, codersdk.WorkspaceAgentMetadata{
1602+
result := make([]codersdk.WorkspaceAgentMetadata, len(db))
1603+
for i, datum := range db {
1604+
result[i] = codersdk.WorkspaceAgentMetadata{
15971605
Result: codersdk.WorkspaceAgentMetadataResult{
15981606
Value: datum.Value,
15991607
Error: datum.Error,
@@ -1607,12 +1615,8 @@ func convertWorkspaceAgentMetadata(db []database.WorkspaceAgentMetadatum) []code
16071615
Interval: datum.Interval,
16081616
Timeout: datum.Timeout,
16091617
},
1610-
})
1618+
}
16111619
}
1612-
// Sorting prevents the metadata from jumping around in the frontend.
1613-
sort.Slice(result, func(i, j int) bool {
1614-
return result[i].Description.Key < result[j].Description.Key
1615-
})
16161620
return result
16171621
}
16181622

coderd/workspaceagents_test.go

+86
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,92 @@ func TestWorkspaceAgent_Metadata(t *testing.T) {
12481248
post(ctx, "unknown", unknownKeyMetadata)
12491249
}
12501250

1251+
func TestWorkspaceAgent_Metadata_DisplayOrder(t *testing.T) {
1252+
t.Parallel()
1253+
1254+
client, db := coderdtest.NewWithDatabase(t, nil)
1255+
user := coderdtest.CreateFirstUser(t, client)
1256+
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
1257+
OrganizationID: user.OrganizationID,
1258+
OwnerID: user.UserID,
1259+
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
1260+
agents[0].Metadata = []*proto.Agent_Metadata{
1261+
{
1262+
DisplayName: "First Meta",
1263+
Key: "foo1",
1264+
Script: "echo hi",
1265+
Interval: 10,
1266+
Timeout: 3,
1267+
Order: 2,
1268+
},
1269+
{
1270+
DisplayName: "Second Meta",
1271+
Key: "foo2",
1272+
Script: "echo howdy",
1273+
Interval: 10,
1274+
Timeout: 3,
1275+
Order: 1,
1276+
},
1277+
{
1278+
DisplayName: "Third Meta",
1279+
Key: "foo3",
1280+
Script: "echo howdy",
1281+
Interval: 10,
1282+
Timeout: 3,
1283+
Order: 2,
1284+
},
1285+
{
1286+
DisplayName: "Fourth Meta",
1287+
Key: "foo4",
1288+
Script: "echo howdy",
1289+
Interval: 10,
1290+
Timeout: 3,
1291+
Order: 3,
1292+
},
1293+
}
1294+
return agents
1295+
}).Do()
1296+
1297+
workspace, err := client.Workspace(context.Background(), r.Workspace.ID)
1298+
require.NoError(t, err)
1299+
for _, res := range workspace.LatestBuild.Resources {
1300+
for _, a := range res.Agents {
1301+
require.Equal(t, codersdk.WorkspaceAgentLifecycleCreated, a.LifecycleState)
1302+
}
1303+
}
1304+
1305+
ctx := testutil.Context(t, testutil.WaitMedium)
1306+
workspace, err = client.Workspace(ctx, workspace.ID)
1307+
require.NoError(t, err, "get workspace")
1308+
1309+
agentID := workspace.LatestBuild.Resources[0].Agents[0].ID
1310+
1311+
var update []codersdk.WorkspaceAgentMetadata
1312+
1313+
// Setup is complete, reset the context.
1314+
ctx = testutil.Context(t, testutil.WaitMedium)
1315+
updates, errors := client.WatchWorkspaceAgentMetadata(ctx, agentID)
1316+
1317+
recvUpdate := func() []codersdk.WorkspaceAgentMetadata {
1318+
select {
1319+
case <-ctx.Done():
1320+
t.Fatalf("context done: %v", ctx.Err())
1321+
case err := <-errors:
1322+
t.Fatalf("error watching metadata: %v", err)
1323+
case update := <-updates:
1324+
return update
1325+
}
1326+
return nil
1327+
}
1328+
1329+
update = recvUpdate()
1330+
require.Len(t, update, 4)
1331+
require.Equal(t, "Second Meta", update[0].Description.DisplayName)
1332+
require.Equal(t, "First Meta", update[1].Description.DisplayName)
1333+
require.Equal(t, "Third Meta", update[2].Description.DisplayName)
1334+
require.Equal(t, "Fourth Meta", update[3].Description.DisplayName)
1335+
}
1336+
12511337
type testWAMErrorStore struct {
12521338
database.Store
12531339
err atomic.Pointer[error]

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ require (
9696
github.com/coder/flog v1.1.0
9797
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0
9898
github.com/coder/retry v1.5.1
99-
github.com/coder/terraform-provider-coder v0.13.0
99+
github.com/coder/terraform-provider-coder v0.14.1
100100
github.com/coder/wgtunnel v0.1.13-0.20231127054351-578bfff9b92a
101101
github.com/coreos/go-oidc/v3 v3.9.0
102102
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ github.com/coder/ssh v0.0.0-20231128192721-70855dedb788 h1:YoUSJ19E8AtuUFVYBpXuO
204204
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788/go.mod h1:aGQbuCLyhRLMzZF067xc84Lh7JDs1FKwCmF1Crl9dxQ=
205205
github.com/coder/tailscale v1.1.1-0.20231205095743-61c97bad8c8b h1:ut/aL6oI8TjGdg4JI8+bKB9w5j73intbe0dJAmcmYyQ=
206206
github.com/coder/tailscale v1.1.1-0.20231205095743-61c97bad8c8b/go.mod h1:L8tPrwSi31RAMEMV8rjb0vYTGs7rXt8rAHbqY/p41j4=
207-
github.com/coder/terraform-provider-coder v0.13.0 h1:MjW7O+THAiqIYcxyiuBoGbFEduqgjp7tUZhSkiwGxwo=
208-
github.com/coder/terraform-provider-coder v0.13.0/go.mod h1:g2bDO+IkYqMSMxMdziOlyZsVh5BP/8wBIDvhIkSJ4rg=
207+
github.com/coder/terraform-provider-coder v0.14.1 h1:a97th+fVIs9i5kBj7WTOA4ssAAxaOTvwISLaYl4mbKw=
208+
github.com/coder/terraform-provider-coder v0.14.1/go.mod h1:pACHRoXSHBGyY696mLeQ1hR/Ag1G2wFk5bw0mT5Zp2g=
209209
github.com/coder/wgtunnel v0.1.13-0.20231127054351-578bfff9b92a h1:KhR9LUVllMZ+e9lhubZ1HNrtJDgH5YLoTvpKwmrGag4=
210210
github.com/coder/wgtunnel v0.1.13-0.20231127054351-578bfff9b92a/go.mod h1:QzfptVUdEO+XbkzMKx1kw13i9wwpJlfI1RrZ6SNZ0hA=
211211
github.com/coder/wireguard-go v0.0.0-20230807234434-d825b45ccbf5 h1:eDk/42Kj4xN4yfE504LsvcFEo3dWUiCOaBiWJ2uIH2A=

provisioner/terraform/resources.go

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type agentMetadata struct {
2525
Script string `mapstructure:"script"`
2626
Interval int64 `mapstructure:"interval"`
2727
Timeout int64 `mapstructure:"timeout"`
28+
Order int64 `mapstructure:"order"`
2829
}
2930

3031
// A mapping of attributes on the "coder_agent" resource.
@@ -209,6 +210,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
209210
Script: item.Script,
210211
Interval: item.Interval,
211212
Timeout: item.Timeout,
213+
Order: item.Order,
212214
})
213215
}
214216

provisioner/terraform/resources_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ func TestConvertResources(t *testing.T) {
250250
Script: "ps -ef | wc -l",
251251
Interval: 5,
252252
Timeout: 1,
253+
Order: 7,
253254
}},
254255
ConnectionTimeoutSeconds: 120,
255256
DisplayApps: &displayApps,

provisioner/terraform/testdata/resource-metadata/resource-metadata.tf

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
coder = {
44
source = "coder/coder"
5-
version = "0.7.0"
5+
version = "0.14.1"
66
}
77
}
88
}
@@ -16,6 +16,7 @@ resource "coder_agent" "main" {
1616
script = "ps -ef | wc -l"
1717
interval = 5
1818
timeout = 1
19+
order = 7
1920
}
2021
}
2122

provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.dot

+8-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)