Skip to content

Commit 735e039

Browse files
committed
hub/delete-project: add explicit delete_project_data setting
1 parent 2429b15 commit 735e039

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

src/packages/database/postgres/delete-projects.ts

+28-15
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,18 @@ export async function cleanup_old_projects_data(
130130
) {
131131
const settings = await getServerSettings();
132132
const on_prem = settings.kucalc === KUCALC_ON_PREMISES;
133+
const delete_data = settings.delete_project_data;
133134
const L0 = log.extend("cleanup_old_projects_data");
134135
const L = L0.debug;
135136

136-
L("args", { max_run_m, on_prem });
137-
const start_ts = new Date();
137+
L("args", { max_run_m, on_prem, delete_data });
138+
139+
if (!delete_data) {
140+
L(`deleting project data is disabled ('delete_project_data' setting).`);
141+
return;
142+
}
138143

144+
const start_ts = new Date();
139145
const pool = getPool();
140146

141147
let numSyncStr = 0;
@@ -171,27 +177,34 @@ export async function cleanup_old_projects_data(
171177
numProj += 1;
172178
let delRows = 0;
173179

180+
// Clean up data *on* a given project. For now, remove all site licenses.
181+
await pool.query(
182+
`UPDATE projects SET site_license = NULL WHERE project_id = $1`,
183+
[project_id],
184+
);
185+
174186
if (on_prem) {
175187
L2(`delete all project files`);
176188
await deleteProjectFiles(L2, project_id);
177189

178190
L2(`deleting all shared files`);
179-
// this is something like /shared/projects/${project_id}
180-
const shared_path = pathToFiles(project_id, "");
181-
await fs.rm(shared_path, { recursive: true, force: true });
182-
183-
// for now, on-prem only as well. This gets rid of all sorts of data in tables specific to the given project.
184-
delRows += await delete_associated_project_data(L2, project_id);
191+
try {
192+
// this is something like /shared/projects/${project_id}
193+
const shared_path = pathToFiles(project_id, "");
194+
await fs.rm(shared_path, { recursive: true, force: true });
195+
} catch (err) {
196+
L2(`Unable to delete shared files: ${err}`);
197+
}
185198
}
186199

200+
// This gets rid of all sorts of data in tables specific to the given project.
201+
delRows += await delete_associated_project_data(L2, project_id);
202+
187203
// now, that we're done with that project, mark it as state.state ->> 'deleted'
188-
// in addition to the flag "deleted = true"
189-
await callback2(db.set_project_state, {
190-
project_id,
191-
state: "deleted",
192-
});
204+
// in addition to the flag "deleted = true". This also updates the state.time timestamp.
205+
await callback2(db.set_project_state, { project_id, state: "deleted" });
193206
L2(
194-
`finished deleting project data | deleted ${delRows} entries | setting state.state="deleted"`,
207+
`finished deleting project data | deleted ${delRows} entries | state.state="deleted"`,
195208
);
196209
}
197210

@@ -247,7 +260,7 @@ async function delete_associated_project_data(
247260
const { rowsDeleted } = await bulkDelete({
248261
table: "listings",
249262
field: "project_id",
250-
id: "project_id", // TODO listings has a more complex ID, is this a problem?
263+
id: "project_id", // TODO listings has a more complex ID, which means this gets rid of everything in one go. should be fine, though.
251264
value: project_id,
252265
});
253266
total += rowsDeleted;

src/packages/util/db-schema/site-defaults.ts

+7
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export type SiteSettingsKeys =
8080
| "require_license_to_create_project"
8181
| "google_analytics"
8282
| "kucalc"
83+
| "delete_project_data"
8384
| "dns"
8485
| "datastore"
8586
| "ssh_gateway"
@@ -652,6 +653,12 @@ export const site_settings_conf: SiteSettings = {
652653
to_val: split_iframe_comm_hosts,
653654
to_display: num_dns_hosts,
654655
},
656+
delete_project_data : {
657+
name :"Delete Project Data",
658+
desc: "When a project has been marked as deleted, also actually delete associated data from the database and (for OnPrem) also its files.",
659+
default: "no",
660+
to_val: to_bool,
661+
},
655662
email_enabled: {
656663
name: "Email sending enabled",
657664
desc: "Controls visibility of UI elements and if any emails are sent. This is independent of any particular email configuration!",

0 commit comments

Comments
 (0)