Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: allow specifying devcontainer on agent in terraform#16997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
mafredri merged 23 commits intomainfrommafredri/feat-add-agent-devcontainers
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
23 commits
Select commitHold shift + click to select a range
76bf36b
feat: add agent devcontainers from provision
mafredriMar 19, 2025
1f4e5b7
make gen
mafredriMar 19, 2025
d6da3b8
implement dbmem and dbauthz
mafredriMar 19, 2025
788adad
add to agent proto/manifest
mafredriMar 19, 2025
4f6cf12
make gen
mafredriMar 19, 2025
4742f3c
implement dbmem and dbauthz
mafredriMar 19, 2025
3efbaa3
fix provisioner, add resource test
mafredriMar 19, 2025
3bb874e
add provisionerd tests
mafredriMar 19, 2025
bbbfa92
add agentapi test case
mafredriMar 19, 2025
0024156
fix
mafredriMar 19, 2025
013bb45
add fixcture
mafredriMar 19, 2025
f48d807
simplify name
mafredriMar 19, 2025
c211af4
fix fixture
mafredriMar 19, 2025
b668a21
fix dbauthz
mafredriMar 19, 2025
4649f19
fix dbauthz^2
mafredriMar 19, 2025
9a20d98
create index
mafredriMar 19, 2025
7eb0e41
dbgen workspace folder
mafredriMar 20, 2025
563107c
provisionerd proto bump
mafredriMar 20, 2025
9e71261
add rbac todo
mafredriMar 20, 2025
620ac74
update golden files
mafredriMar 20, 2025
fc4d5d7
fix e2e test
mafredriMar 20, 2025
b466e4e
fix migrations
mafredriMar 20, 2025
82df8d6
add rbac resource for workspace agent devcontainer
mafredriMar 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,530 changes: 814 additions & 716 deletionsagent/proto/agent.pb.go
View file
Open in desktop

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletionsagent/proto/agent.proto
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -95,6 +95,13 @@ message Manifest {
repeated WorkspaceAgentScript scripts = 10;
repeated WorkspaceApp apps = 11;
repeated WorkspaceAgentMetadata.Description metadata = 12;
repeated WorkspaceAgentDevcontainer devcontainers = 17;
}

message WorkspaceAgentDevcontainer {
bytes id = 1;
string workspace_folder = 2;
string config_path = 3;
}

message GetManifestRequest {}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,7 +7,7 @@
"last_seen_at": "====[timestamp]=====",
"name": "test",
"version": "v0.0.0-devel",
"api_version": "1.3",
"api_version": "1.4",
"provisioners": [
"echo"
],
Expand Down
40 changes: 31 additions & 9 deletionscoderd/agentapi/manifest.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,6 +3,7 @@ package agentapi
import (
"context"
"database/sql"
"errors"
"net/url"
"strings"
"time"
Expand DownExpand Up@@ -42,11 +43,12 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest
return nil, err
}
var (
dbApps []database.WorkspaceApp
scripts []database.WorkspaceAgentScript
metadata []database.WorkspaceAgentMetadatum
workspace database.Workspace
owner database.User
dbApps []database.WorkspaceApp
scripts []database.WorkspaceAgentScript
metadata []database.WorkspaceAgentMetadatum
workspace database.Workspace
owner database.User
devcontainers []database.WorkspaceAgentDevcontainer
)

var eg errgroup.Group
Expand DownExpand Up@@ -80,6 +82,13 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest
}
return err
})
eg.Go(func() (err error) {
devcontainers, err = a.Database.GetWorkspaceAgentDevcontainersByAgentID(ctx, workspaceAgent.ID)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return err
}
return nil
})
err = eg.Wait()
if err != nil {
return nil, xerrors.Errorf("fetching workspace agent data: %w", err)
Expand DownExpand Up@@ -125,10 +134,11 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest
DisableDirectConnections: a.DisableDirectConnections,
DerpForceWebsockets: a.DerpForceWebSockets,

DerpMap: tailnet.DERPMapToProto(a.DerpMapFn()),
Scripts: dbAgentScriptsToProto(scripts),
Apps: apps,
Metadata: dbAgentMetadataToProtoDescription(metadata),
DerpMap: tailnet.DERPMapToProto(a.DerpMapFn()),
Scripts: dbAgentScriptsToProto(scripts),
Apps: apps,
Metadata: dbAgentMetadataToProtoDescription(metadata),
Devcontainers: dbAgentDevcontainersToProto(devcontainers),
}, nil
}

Expand DownExpand Up@@ -228,3 +238,15 @@ func dbAppToProto(dbApp database.WorkspaceApp, agent database.WorkspaceAgent, ow
Hidden: dbApp.Hidden,
}, nil
}

func dbAgentDevcontainersToProto(devcontainers []database.WorkspaceAgentDevcontainer) []*agentproto.WorkspaceAgentDevcontainer {
ret := make([]*agentproto.WorkspaceAgentDevcontainer, len(devcontainers))
for i, dc := range devcontainers {
ret[i] = &agentproto.WorkspaceAgentDevcontainer{
Id: dc.ID[:],
WorkspaceFolder: dc.WorkspaceFolder,
ConfigPath: dc.ConfigPath,
}
}
return ret
}
44 changes: 36 additions & 8 deletionscoderd/agentapi/manifest_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -156,6 +156,19 @@ func TestGetManifest(t *testing.T) {
CollectedAt: someTime.Add(time.Hour),
},
}
devcontainers = []database.WorkspaceAgentDevcontainer{
{
ID: uuid.New(),
WorkspaceAgentID: agent.ID,
WorkspaceFolder: "/cool/folder",
},
{
ID: uuid.New(),
WorkspaceAgentID: agent.ID,
WorkspaceFolder: "/another/cool/folder",
ConfigPath: "/another/cool/folder/.devcontainer/devcontainer.json",
},
}
derpMapFn = func() *tailcfg.DERPMap {
return &tailcfg.DERPMap{
Regions: map[int]*tailcfg.DERPRegion{
Expand DownExpand Up@@ -267,6 +280,17 @@ func TestGetManifest(t *testing.T) {
Timeout: durationpb.New(time.Duration(metadata[1].Timeout)),
},
}
protoDevcontainers = []*agentproto.WorkspaceAgentDevcontainer{
{
Id: devcontainers[0].ID[:],
WorkspaceFolder: devcontainers[0].WorkspaceFolder,
},
{
Id: devcontainers[1].ID[:],
WorkspaceFolder: devcontainers[1].WorkspaceFolder,
ConfigPath: devcontainers[1].ConfigPath,
},
}
)

t.Run("OK", func(t *testing.T) {
Expand DownExpand Up@@ -299,6 +323,7 @@ func TestGetManifest(t *testing.T) {
WorkspaceAgentID: agent.ID,
Keys: nil, // all
}).Return(metadata, nil)
mDB.EXPECT().GetWorkspaceAgentDevcontainersByAgentID(gomock.Any(), agent.ID).Return(devcontainers, nil)
mDB.EXPECT().GetWorkspaceByID(gomock.Any(), workspace.ID).Return(workspace, nil)
mDB.EXPECT().GetUserByID(gomock.Any(), workspace.OwnerID).Return(owner, nil)

Expand All@@ -321,10 +346,11 @@ func TestGetManifest(t *testing.T) {
// tailnet.DERPMapToProto() is extensively tested elsewhere, so it's
// not necessary to manually recreate a big DERP map here like we
// did for apps and metadata.
DerpMap: tailnet.DERPMapToProto(derpMapFn()),
Scripts: protoScripts,
Apps: protoApps,
Metadata: protoMetadata,
DerpMap: tailnet.DERPMapToProto(derpMapFn()),
Scripts: protoScripts,
Apps: protoApps,
Metadata: protoMetadata,
Devcontainers: protoDevcontainers,
}

// Log got and expected with spew.
Expand DownExpand Up@@ -364,6 +390,7 @@ func TestGetManifest(t *testing.T) {
WorkspaceAgentID: agent.ID,
Keys: nil, // all
}).Return(metadata, nil)
mDB.EXPECT().GetWorkspaceAgentDevcontainersByAgentID(gomock.Any(), agent.ID).Return(devcontainers, nil)
mDB.EXPECT().GetWorkspaceByID(gomock.Any(), workspace.ID).Return(workspace, nil)
mDB.EXPECT().GetUserByID(gomock.Any(), workspace.OwnerID).Return(owner, nil)

Expand All@@ -386,10 +413,11 @@ func TestGetManifest(t *testing.T) {
// tailnet.DERPMapToProto() is extensively tested elsewhere, so it's
// not necessary to manually recreate a big DERP map here like we
// did for apps and metadata.
DerpMap: tailnet.DERPMapToProto(derpMapFn()),
Scripts: protoScripts,
Apps: protoApps,
Metadata: protoMetadata,
DerpMap: tailnet.DERPMapToProto(derpMapFn()),
Scripts: protoScripts,
Apps: protoApps,
Metadata: protoMetadata,
Devcontainers: protoDevcontainers,
}

// Log got and expected with spew.
Expand Down
2 changes: 2 additions & 0 deletionscoderd/apidoc/docs.go
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

2 changes: 2 additions & 0 deletionscoderd/apidoc/swagger.json
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

16 changes: 16 additions & 0 deletionscoderd/database/dbauthz/dbauthz.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -186,6 +186,7 @@ var (
rbac.ResourceNotificationMessage.Type: {policy.ActionCreate, policy.ActionRead},
// Provisionerd creates workspaces resources monitor
rbac.ResourceWorkspaceAgentResourceMonitor.Type: {policy.ActionCreate},
rbac.ResourceWorkspaceAgentDevcontainers.Type: {policy.ActionCreate},
}),
Org: map[string][]rbac.Permission{},
User: []rbac.Permission{},
Expand DownExpand Up@@ -2660,6 +2661,14 @@ func (q *querier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInstanc
return agent, nil
}

func (q *querier) GetWorkspaceAgentDevcontainersByAgentID(ctx context.Context, workspaceAgentID uuid.UUID) ([]database.WorkspaceAgentDevcontainer, error) {
_, err := q.GetWorkspaceAgentByID(ctx, workspaceAgentID)
if err != nil {
return nil, err
}
return q.db.GetWorkspaceAgentDevcontainersByAgentID(ctx, workspaceAgentID)
}

func (q *querier) GetWorkspaceAgentLifecycleStateByID(ctx context.Context, id uuid.UUID) (database.GetWorkspaceAgentLifecycleStateByIDRow, error) {
_, err := q.GetWorkspaceAgentByID(ctx, id)
if err != nil {
Expand DownExpand Up@@ -3390,6 +3399,13 @@ func (q *querier) InsertWorkspaceAgent(ctx context.Context, arg database.InsertW
return q.db.InsertWorkspaceAgent(ctx, arg)
}

func (q *querier) InsertWorkspaceAgentDevcontainers(ctx context.Context, arg database.InsertWorkspaceAgentDevcontainersParams) ([]database.WorkspaceAgentDevcontainer, error) {
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceWorkspaceAgentDevcontainers); err != nil {
return nil, err
}
return q.db.InsertWorkspaceAgentDevcontainers(ctx, arg)
}

func (q *querier) InsertWorkspaceAgentLogSources(ctx context.Context, arg database.InsertWorkspaceAgentLogSourcesParams) ([]database.WorkspaceAgentLogSource, error) {
// TODO: This is used by the agent, should we have an rbac check here?
return q.db.InsertWorkspaceAgentLogSources(ctx, arg)
Expand Down
72 changes: 72 additions & 0 deletionscoderd/database/dbauthz/dbauthz_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3074,6 +3074,36 @@ func (s *MethodTestSuite) TestWorkspace() {
})
check.Args(w.ID).Asserts(w, policy.ActionUpdate).Returns()
}))
s.Run("GetWorkspaceAgentDevcontainersByAgentID", s.Subtest(func(db database.Store, check *expects) {
u := dbgen.User(s.T(), db, database.User{})
o := dbgen.Organization(s.T(), db, database.Organization{})
tpl := dbgen.Template(s.T(), db, database.Template{
OrganizationID: o.ID,
CreatedBy: u.ID,
})
tv := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true},
OrganizationID: o.ID,
CreatedBy: u.ID,
})
w := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
TemplateID: tpl.ID,
OrganizationID: o.ID,
OwnerID: u.ID,
})
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
Type: database.ProvisionerJobTypeWorkspaceBuild,
})
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
JobID: j.ID,
WorkspaceID: w.ID,
TemplateVersionID: tv.ID,
})
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: b.JobID})
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
d := dbgen.WorkspaceAgentDevcontainer(s.T(), db, database.WorkspaceAgentDevcontainer{WorkspaceAgentID: agt.ID})
check.Args(agt.ID).Asserts(w, policy.ActionRead).Returns([]database.WorkspaceAgentDevcontainer{d})
}))
}

func (s *MethodTestSuite) TestWorkspacePortSharing() {
Expand DownExpand Up@@ -5021,3 +5051,45 @@ func (s *MethodTestSuite) TestResourcesMonitor() {
check.Args(agt.ID).Asserts(w, policy.ActionRead).Returns(monitors)
}))
}

func (s *MethodTestSuite) TestResourcesProvisionerdserver() {
createAgent := func(t *testing.T, db database.Store) (database.WorkspaceAgent, database.WorkspaceTable) {
t.Helper()

u := dbgen.User(t, db, database.User{})
o := dbgen.Organization(t, db, database.Organization{})
tpl := dbgen.Template(t, db, database.Template{
OrganizationID: o.ID,
CreatedBy: u.ID,
})
tv := dbgen.TemplateVersion(t, db, database.TemplateVersion{
TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true},
OrganizationID: o.ID,
CreatedBy: u.ID,
})
w := dbgen.Workspace(t, db, database.WorkspaceTable{
TemplateID: tpl.ID,
OrganizationID: o.ID,
OwnerID: u.ID,
})
j := dbgen.ProvisionerJob(t, db, nil, database.ProvisionerJob{
Type: database.ProvisionerJobTypeWorkspaceBuild,
})
b := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
JobID: j.ID,
WorkspaceID: w.ID,
TemplateVersionID: tv.ID,
})
res := dbgen.WorkspaceResource(t, db, database.WorkspaceResource{JobID: b.JobID})
agt := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{ResourceID: res.ID})

return agt, w
}

s.Run("InsertWorkspaceAgentDevcontainers", s.Subtest(func(db database.Store, check *expects) {
agt, _ := createAgent(s.T(), db)
check.Args(database.InsertWorkspaceAgentDevcontainersParams{
WorkspaceAgentID: agt.ID,
}).Asserts(rbac.ResourceWorkspaceAgentDevcontainers, policy.ActionCreate)
}))
}
12 changes: 12 additions & 0 deletionscoderd/database/dbgen/dbgen.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,18 @@ func WorkspaceAgentScriptTiming(t testing.TB, db database.Store, orig database.W
panic("failed to insert workspace agent script timing")
}

func WorkspaceAgentDevcontainer(t testing.TB, db database.Store, orig database.WorkspaceAgentDevcontainer) database.WorkspaceAgentDevcontainer {
devcontainers, err := db.InsertWorkspaceAgentDevcontainers(genCtx, database.InsertWorkspaceAgentDevcontainersParams{
WorkspaceAgentID: takeFirst(orig.WorkspaceAgentID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
ID: []uuid.UUID{takeFirst(orig.ID, uuid.New())},
WorkspaceFolder: []string{takeFirst(orig.WorkspaceFolder, "/workspace")},
ConfigPath: []string{takeFirst(orig.ConfigPath, "")},
})
require.NoError(t, err, "insert workspace agent devcontainer")
return devcontainers[0]
}

func Workspace(t testing.TB, db database.Store, orig database.WorkspaceTable) database.WorkspaceTable {
t.Helper()

Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp