Skip to content

Commit b4edac1

Browse files
evgeniy-scherbinastirby
authored andcommitted
fix: fix for prebuilds claiming and deletion (#17624)
PR contains: - fix for claiming & deleting prebuilds with immutable params - unit test for claiming scenario - unit test for deletion scenario The parameter resolver was failing when deleting/claiming prebuilds because a value for a previously-used parameter was provided to the resolver, but since the value was unchanged (it's coming from the preset) it failed in the resolver. The resolver was missing a check to see if the old value != new value; if the values match then there's no mutation of an immutable parameter. --------- Signed-off-by: Danny Kopping <dannykopping@gmail.com> (cherry picked from commit 98e5611)
1 parent 795fba9 commit b4edac1

File tree

4 files changed

+81
-13
lines changed

4 files changed

+81
-13
lines changed

codersdk/richparameters.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ type ParameterResolver struct {
164164
// resolves the correct value. It returns the value of the parameter, if valid, and an error if invalid.
165165
func (r *ParameterResolver) ValidateResolve(p TemplateVersionParameter, v *WorkspaceBuildParameter) (value string, err error) {
166166
prevV := r.findLastValue(p)
167-
if !p.Mutable && v != nil && prevV != nil {
167+
if !p.Mutable && v != nil && prevV != nil && v.Value != prevV.Value {
168168
return "", xerrors.Errorf("Parameter %q is not mutable, so it can't be updated after creating a workspace.", p.Name)
169169
}
170170
if p.Required && v == nil && prevV == nil {

codersdk/richparameters_test.go

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package codersdk_test
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -121,20 +122,60 @@ func TestParameterResolver_ValidateResolve_NewOverridesOld(t *testing.T) {
121122
func TestParameterResolver_ValidateResolve_Immutable(t *testing.T) {
122123
t.Parallel()
123124
uut := codersdk.ParameterResolver{
124-
Rich: []codersdk.WorkspaceBuildParameter{{Name: "n", Value: "5"}},
125+
Rich: []codersdk.WorkspaceBuildParameter{{Name: "n", Value: "old"}},
125126
}
126127
p := codersdk.TemplateVersionParameter{
127128
Name: "n",
128-
Type: "number",
129+
Type: "string",
129130
Required: true,
130131
Mutable: false,
131132
}
132-
v, err := uut.ValidateResolve(p, &codersdk.WorkspaceBuildParameter{
133-
Name: "n",
134-
Value: "6",
135-
})
136-
require.Error(t, err)
137-
require.Equal(t, "", v)
133+
134+
cases := []struct {
135+
name string
136+
newValue string
137+
expectedErr string
138+
}{
139+
{
140+
name: "mutation",
141+
newValue: "new", // "new" != "old"
142+
expectedErr: fmt.Sprintf("Parameter %q is not mutable", p.Name),
143+
},
144+
{
145+
// Values are case-sensitive.
146+
name: "case change",
147+
newValue: "Old", // "Old" != "old"
148+
expectedErr: fmt.Sprintf("Parameter %q is not mutable", p.Name),
149+
},
150+
{
151+
name: "default",
152+
newValue: "", // "" != "old"
153+
expectedErr: fmt.Sprintf("Parameter %q is not mutable", p.Name),
154+
},
155+
{
156+
name: "no change",
157+
newValue: "old", // "old" == "old"
158+
},
159+
}
160+
161+
for _, tc := range cases {
162+
t.Run(tc.name, func(t *testing.T) {
163+
t.Parallel()
164+
165+
v, err := uut.ValidateResolve(p, &codersdk.WorkspaceBuildParameter{
166+
Name: "n",
167+
Value: tc.newValue,
168+
})
169+
170+
if tc.expectedErr == "" {
171+
require.NoError(t, err)
172+
require.Equal(t, tc.newValue, v)
173+
} else {
174+
require.ErrorContains(t, err, tc.expectedErr)
175+
require.Equal(t, "", v)
176+
}
177+
})
178+
}
138179
}
139180

140181
func TestRichParameterValidation(t *testing.T) {

enterprise/coderd/prebuilds/claim_test.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,8 @@ func TestClaimPrebuild(t *testing.T) {
329329
require.NoError(t, err)
330330

331331
stopBuild, err := userClient.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
332-
TemplateVersionID: version.ID,
333-
Transition: codersdk.WorkspaceTransitionStop,
334-
RichParameterValues: wp,
332+
TemplateVersionID: version.ID,
333+
Transition: codersdk.WorkspaceTransitionStop,
335334
})
336335
require.NoError(t, err)
337336
coderdtest.AwaitWorkspaceBuildJobCompleted(t, userClient, stopBuild.ID)
@@ -369,6 +368,17 @@ func templateWithAgentAndPresetsWithPrebuilds(desiredInstances int32) *echo.Resp
369368
},
370369
},
371370
},
371+
// Make sure immutable params don't break claiming logic
372+
Parameters: []*proto.RichParameter{
373+
{
374+
Name: "k1",
375+
Description: "immutable param",
376+
Type: "string",
377+
DefaultValue: "",
378+
Required: false,
379+
Mutable: false,
380+
},
381+
},
372382
Presets: []*proto.Preset{
373383
{
374384
Name: "preset-a",

enterprise/coderd/prebuilds/reconcile_test.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,16 @@ func setupTestDBTemplateVersion(
970970
ID: templateID,
971971
ActiveVersionID: templateVersion.ID,
972972
}))
973+
// Make sure immutable params don't break prebuilt workspace deletion logic
974+
dbgen.TemplateVersionParameter(t, db, database.TemplateVersionParameter{
975+
TemplateVersionID: templateVersion.ID,
976+
Name: "test",
977+
Description: "required & immutable param",
978+
Type: "string",
979+
DefaultValue: "",
980+
Required: true,
981+
Mutable: false,
982+
})
973983
return templateVersion.ID
974984
}
975985

@@ -1068,7 +1078,7 @@ func setupTestDBWorkspace(
10681078
OrganizationID: orgID,
10691079
Error: buildError,
10701080
})
1071-
dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
1081+
workspaceBuild := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
10721082
WorkspaceID: workspace.ID,
10731083
InitiatorID: initiatorID,
10741084
TemplateVersionID: templateVersionID,
@@ -1077,6 +1087,13 @@ func setupTestDBWorkspace(
10771087
Transition: transition,
10781088
CreatedAt: clock.Now(),
10791089
})
1090+
dbgen.WorkspaceBuildParameters(t, db, []database.WorkspaceBuildParameter{
1091+
{
1092+
WorkspaceBuildID: workspaceBuild.ID,
1093+
Name: "test",
1094+
Value: "test",
1095+
},
1096+
})
10801097

10811098
return workspace
10821099
}

0 commit comments

Comments
 (0)