Skip to content

Commit 98e5611

Browse files
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>
1 parent c7fc7b9 commit 98e5611

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
@@ -901,6 +901,16 @@ func setupTestDBTemplateVersion(
901901
ID: templateID,
902902
ActiveVersionID: templateVersion.ID,
903903
}))
904+
// Make sure immutable params don't break prebuilt workspace deletion logic
905+
dbgen.TemplateVersionParameter(t, db, database.TemplateVersionParameter{
906+
TemplateVersionID: templateVersion.ID,
907+
Name: "test",
908+
Description: "required & immutable param",
909+
Type: "string",
910+
DefaultValue: "",
911+
Required: true,
912+
Mutable: false,
913+
})
904914
return templateVersion.ID
905915
}
906916

@@ -999,7 +1009,7 @@ func setupTestDBWorkspace(
9991009
OrganizationID: orgID,
10001010
Error: buildError,
10011011
})
1002-
dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
1012+
workspaceBuild := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
10031013
WorkspaceID: workspace.ID,
10041014
InitiatorID: initiatorID,
10051015
TemplateVersionID: templateVersionID,
@@ -1008,6 +1018,13 @@ func setupTestDBWorkspace(
10081018
Transition: transition,
10091019
CreatedAt: clock.Now(),
10101020
})
1021+
dbgen.WorkspaceBuildParameters(t, db, []database.WorkspaceBuildParameter{
1022+
{
1023+
WorkspaceBuildID: workspaceBuild.ID,
1024+
Name: "test",
1025+
Value: "test",
1026+
},
1027+
})
10111028

10121029
return workspace
10131030
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy