mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
Merge branch 'main' of github.com:/coder/coder into dk/prebuilds
This commit is contained in:
@ -1932,10 +1932,25 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
|
||||
appSlugs = make(map[string]struct{})
|
||||
)
|
||||
for _, prAgent := range protoResource.Agents {
|
||||
if _, ok := agentNames[prAgent.Name]; ok {
|
||||
// Similar logic is duplicated in terraform/resources.go.
|
||||
if prAgent.Name == "" {
|
||||
return xerrors.Errorf("agent name cannot be empty")
|
||||
}
|
||||
// In 2025-02 we removed support for underscores in agent names. To
|
||||
// provide a nicer error message, we check the regex first and check
|
||||
// for underscores if it fails.
|
||||
if !provisioner.AgentNameRegex.MatchString(prAgent.Name) {
|
||||
if strings.Contains(prAgent.Name, "_") {
|
||||
return xerrors.Errorf("agent name %q contains underscores which are no longer supported, please use hyphens instead (regex: %q)", prAgent.Name, provisioner.AgentNameRegex.String())
|
||||
}
|
||||
return xerrors.Errorf("agent name %q does not match regex %q", prAgent.Name, provisioner.AgentNameRegex.String())
|
||||
}
|
||||
// Agent names must be case-insensitive-unique, to be unambiguous in
|
||||
// `coder_app`s and CoderVPN DNS names.
|
||||
if _, ok := agentNames[strings.ToLower(prAgent.Name)]; ok {
|
||||
return xerrors.Errorf("duplicate agent name %q", prAgent.Name)
|
||||
}
|
||||
agentNames[prAgent.Name] = struct{}{}
|
||||
agentNames[strings.ToLower(prAgent.Name)] = struct{}{}
|
||||
|
||||
var instanceID sql.NullString
|
||||
if prAgent.GetInstanceId() != "" {
|
||||
@ -2109,10 +2124,13 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
|
||||
}
|
||||
|
||||
for _, app := range prAgent.Apps {
|
||||
// Similar logic is duplicated in terraform/resources.go.
|
||||
slug := app.Slug
|
||||
if slug == "" {
|
||||
return xerrors.Errorf("app must have a slug or name set")
|
||||
}
|
||||
// Contrary to agent names above, app slugs were never permitted to
|
||||
// contain uppercase letters or underscores.
|
||||
if !provisioner.AppSlugRegex.MatchString(slug) {
|
||||
return xerrors.Errorf("app slug %q does not match regex %q", slug, provisioner.AppSlugRegex.String())
|
||||
}
|
||||
|
@ -1883,6 +1883,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
Auth: &sdkproto.Agent_Token{
|
||||
Token: "bananas",
|
||||
},
|
||||
@ -1896,6 +1897,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
Apps: []*sdkproto.App{{
|
||||
Slug: "a",
|
||||
}, {
|
||||
@ -1903,7 +1905,116 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
}},
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, "duplicate app slug")
|
||||
require.ErrorContains(t, err, `duplicate app slug, must be unique per template: "a"`)
|
||||
err = insert(dbmem.New(), uuid.New(), &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev1",
|
||||
Apps: []*sdkproto.App{{
|
||||
Slug: "a",
|
||||
}},
|
||||
}, {
|
||||
Name: "dev2",
|
||||
Apps: []*sdkproto.App{{
|
||||
Slug: "a",
|
||||
}},
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, `duplicate app slug, must be unique per template: "a"`)
|
||||
})
|
||||
t.Run("AppSlugInvalid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbmem.New()
|
||||
job := uuid.New()
|
||||
err := insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
Apps: []*sdkproto.App{{
|
||||
Slug: "dev_1",
|
||||
}},
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, `app slug "dev_1" does not match regex`)
|
||||
err = insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
Apps: []*sdkproto.App{{
|
||||
Slug: "dev--1",
|
||||
}},
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, `app slug "dev--1" does not match regex`)
|
||||
err = insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
Apps: []*sdkproto.App{{
|
||||
Slug: "Dev",
|
||||
}},
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, `app slug "Dev" does not match regex`)
|
||||
})
|
||||
t.Run("DuplicateAgentNames", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbmem.New()
|
||||
job := uuid.New()
|
||||
// case-insensitive-unique
|
||||
err := insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
}, {
|
||||
Name: "Dev",
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, "duplicate agent name")
|
||||
err = insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
}, {
|
||||
Name: "dev",
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, "duplicate agent name")
|
||||
})
|
||||
t.Run("AgentNameInvalid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbmem.New()
|
||||
job := uuid.New()
|
||||
err := insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "Dev",
|
||||
}},
|
||||
})
|
||||
require.NoError(t, err) // uppercase is still allowed
|
||||
err = insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev_1",
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, `agent name "dev_1" contains underscores`) // custom error for underscores
|
||||
err = insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev--1",
|
||||
}},
|
||||
})
|
||||
require.ErrorContains(t, err, `agent name "dev--1" does not match regex`)
|
||||
})
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
@ -1981,6 +2092,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
DisplayApps: &sdkproto.DisplayApps{
|
||||
Vscode: true,
|
||||
VscodeInsiders: true,
|
||||
@ -2009,6 +2121,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
DisplayApps: &sdkproto.DisplayApps{},
|
||||
}},
|
||||
})
|
||||
@ -2033,6 +2146,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
Name: "dev",
|
||||
DisplayApps: &sdkproto.DisplayApps{},
|
||||
ResourcesMonitoring: &sdkproto.ResourcesMonitoring{
|
||||
Memory: &sdkproto.MemoryResourceMonitor{
|
||||
|
Reference in New Issue
Block a user