Skip to content

Commit 3e5f91d

Browse files
committed
Delete versions are unusable
1 parent 1de0a5d commit 3e5f91d

File tree

5 files changed

+66
-22
lines changed

5 files changed

+66
-22
lines changed

coderd/database/queries/templateversions.sql

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -151,26 +151,41 @@ SET
151151
deleted = true,
152152
updated_at = @updated_at
153153
FROM
154-
(SELECT active_version_id FROM templates WHERE id = @template_id) AS active_version
154+
-- Delete all versions that are returned from this query.
155+
(
156+
SELECT
157+
id
158+
FROM
159+
-- Scope a prune to a single template and ignore already deleted template versions
160+
(SELECT * FROM template_versions WHERE template_id = @template_id AND deleted = false) AS template_versions
161+
LEFT JOIN
162+
provisioner_jobs ON template_versions.job_id = provisioner_jobs.id
163+
LEFT JOIN
164+
templates ON template_versions.template_id = templates.id
165+
WHERE
166+
-- Actively used template versions (meaning the latest build is using
167+
-- the version) are never pruned. A "restart" command on the workspace,
168+
-- even if failed, would use the version. So it cannot be pruned until
169+
-- the build is outdated.
170+
-- TODO: This is an issue for "deleted workspaces", since a deleted workspace
171+
-- has a build with the transition "delete". This will prevent that template
172+
-- version from ever being pruned. We need a method to prune deleted workspaces.
173+
template_versions.id != ANY(
174+
SELECT DISTINCT ON(workspace_id)
175+
template_version_id
176+
FROM
177+
workspace_builds
178+
ORDER BY build_number DESC
179+
)
180+
-- Also never delete the active template version
181+
AND active_version_id != template_versions.id
182+
AND CASE
183+
WHEN @job_status != '' THEN
184+
provisioner_jobs.job_status = @job_status
185+
ELSE
186+
true
187+
END
188+
189+
) AS deleted_versions
155190
WHERE
156-
-- Actively used template versions (meaning the latest build is using
157-
-- the version) are never pruned. A "restart" command on the workspace,
158-
-- even if failed, would use the version. So it cannot be pruned until
159-
-- the build is outdated.
160-
-- TODO: This is an issue for "deleted workspaces", since a deleted workspace
161-
-- has a build with the transition "delete". This will prevent that template
162-
-- version from ever being pruned. We need a method to prune deleted workspaces.
163-
template_versions.id != ANY(
164-
SELECT DISTINCT ON(workspace_id)
165-
template_version_id
166-
FROM
167-
workspace_builds
168-
ORDER BY build_number DESC
169-
)
170-
-- Also never delete the active template version
171-
AND template_versions.id != ANY(active_version)
172-
-- Ignore already deleted versions.
173-
AND template_versions.deleted = false
174-
-- Scope a prune to a single template.
175-
AND template_id = @template_id :: uuid
176-
RETURNING id;
191+
id = ANY(deleted_versions);

coderd/templates.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
193193
})
194194
return
195195
}
196+
if templateVersion.Deleted {
197+
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
198+
Message: fmt.Sprintf("Template version %s is deleted.", createTemplate.VersionID),
199+
Validations: []codersdk.ValidationError{
200+
{Field: "template_version_id", Detail: "Template version is deleted"},
201+
},
202+
})
203+
return
204+
}
196205
templateVersionAudit.Old = templateVersion
197206
if templateVersion.TemplateID.Valid {
198207
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{

coderd/templateversions.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,12 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque
10401040
})
10411041
return
10421042
}
1043+
if version.Deleted {
1044+
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
1045+
Message: "The provided template version is deleted.",
1046+
})
1047+
return
1048+
}
10431049

10441050
err = api.Database.InTx(func(store database.Store) error {
10451051
err = store.UpdateTemplateActiveVersionByID(ctx, database.UpdateTemplateActiveVersionByIDParams{
@@ -1384,6 +1390,7 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
13841390
Message: version.Message,
13851391
Job: job,
13861392
Readme: version.Readme,
1393+
Deleted: version.Deleted,
13871394
CreatedBy: codersdk.MinimalUser{
13881395
ID: version.CreatedBy,
13891396
Username: version.CreatedByUsername,

coderd/workspaces.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,18 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
356356
})
357357
return
358358
}
359+
if templateVersion.Deleted {
360+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
361+
Message: "Template version has been deleted.",
362+
Validations: []codersdk.ValidationError{
363+
{
364+
Field: "template_version_id",
365+
Detail: "template version deleted and unusable",
366+
},
367+
},
368+
})
369+
return
370+
}
359371

360372
templateID = templateVersion.TemplateID.UUID
361373
}

codersdk/templateversions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type TemplateVersion struct {
2929
Job ProvisionerJob `json:"job"`
3030
Readme string `json:"readme"`
3131
CreatedBy MinimalUser `json:"created_by"`
32+
Deleted bool `json:"deleted"`
3233

3334
Warnings []TemplateVersionWarning `json:"warnings,omitempty" enums:"DEPRECATED_PARAMETERS"`
3435
}

0 commit comments

Comments
 (0)