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

Commit06dbada

Browse files
fix(coderd): ensure lifecycle executor has sufficient task permissions (#20539)
We recently made a change to the `wsbuilder` to handle task relatedlogic. Our test coverage for the lifecycle executor didn't handle thisscenario and so we missed that it had insufficient permissions.This PR adds `Update` and `Read` permissions for `Task`s in thelifecycle executor, as well as an autostart/autostop test tailored totask workspaces to verify the change.---Anthropic's Claude Sonnet 4.5 Thinking was involved in writing the tests
1 parent566146a commit06dbada

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

‎coderd/autobuild/lifecycle_executor_test.go‎

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,3 +1764,175 @@ func TestExecutorAutostartSkipsWhenNoProvisionersAvailable(t *testing.T) {
17641764

17651765
assert.Len(t,stats.Transitions,1,"should create builds when provisioners are available")
17661766
}
1767+
1768+
funcTestExecutorTaskWorkspace(t*testing.T) {
1769+
t.Parallel()
1770+
1771+
createTaskTemplate:=func(t*testing.T,client*codersdk.Client,orgID uuid.UUID,ctx context.Context,defaultTTL time.Duration) codersdk.Template {
1772+
t.Helper()
1773+
1774+
taskAppID:=uuid.New()
1775+
version:=coderdtest.CreateTemplateVersion(t,client,orgID,&echo.Responses{
1776+
Parse:echo.ParseComplete,
1777+
ProvisionPlan: []*proto.Response{
1778+
{
1779+
Type:&proto.Response_Plan{
1780+
Plan:&proto.PlanComplete{HasAiTasks:true},
1781+
},
1782+
},
1783+
},
1784+
ProvisionApply: []*proto.Response{
1785+
{
1786+
Type:&proto.Response_Apply{
1787+
Apply:&proto.ApplyComplete{
1788+
Resources: []*proto.Resource{
1789+
{
1790+
Agents: []*proto.Agent{
1791+
{
1792+
Id:uuid.NewString(),
1793+
Name:"dev",
1794+
Auth:&proto.Agent_Token{
1795+
Token:uuid.NewString(),
1796+
},
1797+
Apps: []*proto.App{
1798+
{
1799+
Id:taskAppID.String(),
1800+
Slug:"task-app",
1801+
},
1802+
},
1803+
},
1804+
},
1805+
},
1806+
},
1807+
AiTasks: []*proto.AITask{
1808+
{
1809+
AppId:taskAppID.String(),
1810+
},
1811+
},
1812+
},
1813+
},
1814+
},
1815+
},
1816+
})
1817+
coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
1818+
template:=coderdtest.CreateTemplate(t,client,orgID,version.ID)
1819+
1820+
ifdefaultTTL>0 {
1821+
_,err:=client.UpdateTemplateMeta(ctx,template.ID, codersdk.UpdateTemplateMeta{
1822+
DefaultTTLMillis:defaultTTL.Milliseconds(),
1823+
})
1824+
require.NoError(t,err)
1825+
}
1826+
1827+
returntemplate
1828+
}
1829+
1830+
createTaskWorkspace:=func(t*testing.T,client*codersdk.Client,template codersdk.Template,ctx context.Context,inputstring) codersdk.Workspace {
1831+
t.Helper()
1832+
1833+
exp:=codersdk.NewExperimentalClient(client)
1834+
task,err:=exp.CreateTask(ctx,"me", codersdk.CreateTaskRequest{
1835+
TemplateVersionID:template.ActiveVersionID,
1836+
Input:input,
1837+
})
1838+
require.NoError(t,err)
1839+
require.True(t,task.WorkspaceID.Valid,"task should have a workspace")
1840+
1841+
workspace,err:=client.Workspace(ctx,task.WorkspaceID.UUID)
1842+
require.NoError(t,err)
1843+
coderdtest.AwaitWorkspaceBuildJobCompleted(t,client,workspace.LatestBuild.ID)
1844+
1845+
returnworkspace
1846+
}
1847+
1848+
t.Run("Autostart",func(t*testing.T) {
1849+
t.Parallel()
1850+
1851+
var (
1852+
ctx=testutil.Context(t,testutil.WaitShort)
1853+
sched=mustSchedule(t,"CRON_TZ=UTC 0 * * * *")
1854+
tickCh=make(chan time.Time)
1855+
statsCh=make(chan autobuild.Stats)
1856+
client,db=coderdtest.NewWithDatabase(t,&coderdtest.Options{
1857+
AutobuildTicker:tickCh,
1858+
IncludeProvisionerDaemon:true,
1859+
AutobuildStats:statsCh,
1860+
})
1861+
admin=coderdtest.CreateFirstUser(t,client)
1862+
)
1863+
1864+
// Given: A task workspace
1865+
template:=createTaskTemplate(t,client,admin.OrganizationID,ctx,0)
1866+
workspace:=createTaskWorkspace(t,client,template,ctx,"test task for autostart")
1867+
1868+
// Given: The task workspace has an autostart schedule
1869+
err:=client.UpdateWorkspaceAutostart(ctx,workspace.ID, codersdk.UpdateWorkspaceAutostartRequest{
1870+
Schedule:ptr.Ref(sched.String()),
1871+
})
1872+
require.NoError(t,err)
1873+
1874+
// Given: That the workspace is in a stopped state.
1875+
workspace=coderdtest.MustTransitionWorkspace(t,client,workspace.ID,codersdk.WorkspaceTransitionStart,codersdk.WorkspaceTransitionStop)
1876+
1877+
p,err:=coderdtest.GetProvisionerForTags(db,time.Now(),workspace.OrganizationID,map[string]string{})
1878+
require.NoError(t,err)
1879+
1880+
// When: the autobuild executor ticks after the scheduled time
1881+
gofunc() {
1882+
tickTime:=sched.Next(workspace.LatestBuild.CreatedAt)
1883+
coderdtest.UpdateProvisionerLastSeenAt(t,db,p.ID,tickTime)
1884+
tickCh<-tickTime
1885+
close(tickCh)
1886+
}()
1887+
1888+
// Then: We expect to see a start transition
1889+
stats:=<-statsCh
1890+
require.Len(t,stats.Transitions,1,"lifecycle executor should transition the task workspace")
1891+
assert.Contains(t,stats.Transitions,workspace.ID,"task workspace should be in transitions")
1892+
assert.Equal(t,database.WorkspaceTransitionStart,stats.Transitions[workspace.ID],"should autostart the workspace")
1893+
require.Empty(t,stats.Errors,"should have no errors when managing task workspaces")
1894+
})
1895+
1896+
t.Run("Autostop",func(t*testing.T) {
1897+
t.Parallel()
1898+
1899+
var (
1900+
ctx=testutil.Context(t,testutil.WaitShort)
1901+
tickCh=make(chan time.Time)
1902+
statsCh=make(chan autobuild.Stats)
1903+
client,db=coderdtest.NewWithDatabase(t,&coderdtest.Options{
1904+
AutobuildTicker:tickCh,
1905+
IncludeProvisionerDaemon:true,
1906+
AutobuildStats:statsCh,
1907+
})
1908+
admin=coderdtest.CreateFirstUser(t,client)
1909+
)
1910+
1911+
// Given: A task workspace with an 8 hour deadline
1912+
template:=createTaskTemplate(t,client,admin.OrganizationID,ctx,8*time.Hour)
1913+
workspace:=createTaskWorkspace(t,client,template,ctx,"test task for autostop")
1914+
1915+
// Given: The workspace is currently running
1916+
workspace=coderdtest.MustWorkspace(t,client,workspace.ID)
1917+
require.Equal(t,codersdk.WorkspaceTransitionStart,workspace.LatestBuild.Transition)
1918+
require.NotZero(t,workspace.LatestBuild.Deadline,"workspace should have a deadline for autostop")
1919+
1920+
p,err:=coderdtest.GetProvisionerForTags(db,time.Now(),workspace.OrganizationID,map[string]string{})
1921+
require.NoError(t,err)
1922+
1923+
// When: the autobuild executor ticks after the deadline
1924+
gofunc() {
1925+
tickTime:=workspace.LatestBuild.Deadline.Time.Add(time.Minute)
1926+
coderdtest.UpdateProvisionerLastSeenAt(t,db,p.ID,tickTime)
1927+
tickCh<-tickTime
1928+
close(tickCh)
1929+
}()
1930+
1931+
// Then: We expect to see a stop transition
1932+
stats:=<-statsCh
1933+
require.Len(t,stats.Transitions,1,"lifecycle executor should transition the task workspace")
1934+
assert.Contains(t,stats.Transitions,workspace.ID,"task workspace should be in transitions")
1935+
assert.Equal(t,database.WorkspaceTransitionStop,stats.Transitions[workspace.ID],"should autostop the workspace")
1936+
require.Empty(t,stats.Errors,"should have no errors when managing task workspaces")
1937+
})
1938+
}

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ var (
254254
rbac.ResourceFile.Type: {policy.ActionRead},// Required to read terraform files
255255
rbac.ResourceNotificationMessage.Type: {policy.ActionCreate,policy.ActionRead},
256256
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
257+
rbac.ResourceTask.Type: {policy.ActionRead,policy.ActionUpdate},
257258
rbac.ResourceTemplate.Type: {policy.ActionRead,policy.ActionUpdate},
258259
rbac.ResourceUser.Type: {policy.ActionRead},
259260
rbac.ResourceWorkspace.Type: {policy.ActionDelete,policy.ActionRead,policy.ActionUpdate,policy.ActionWorkspaceStart,policy.ActionWorkspaceStop},

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp