Skip to content

Commit 0678bd6

Browse files
committed
[gitpod-db][server] Refactor workspace instance 'attributedTeamId' to an explicit, not-team-specific 'usageAttributionId'
1 parent 96cc345 commit 0678bd6

File tree

6 files changed

+43
-16
lines changed

6 files changed

+43
-16
lines changed

components/gitpod-db/src/typeorm/entity/db-workspace-instance.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,5 @@ export class DBWorkspaceInstance implements WorkspaceInstance {
107107
default: "",
108108
transformer: Transformer.MAP_EMPTY_STR_TO_UNDEFINED,
109109
})
110-
attributedTeamId?: string;
110+
usageAttributionId?: string;
111111
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License-AGPL.txt in the project root for license information.
5+
*/
6+
7+
import { MigrationInterface, QueryRunner } from "typeorm";
8+
import { columnExists } from "./helper/helper";
9+
10+
const TABLE_NAME = "d_b_workspace_instance";
11+
const COLUMN_NAME = "usageAttributionId";
12+
13+
export class WorkspaceInstanceUsageAttributionId1655988518555 implements MigrationInterface {
14+
public async up(queryRunner: QueryRunner): Promise<void> {
15+
if (!(await columnExists(queryRunner, TABLE_NAME, COLUMN_NAME))) {
16+
await queryRunner.query(
17+
`ALTER TABLE ${TABLE_NAME} ADD COLUMN ${COLUMN_NAME} varchar(255) NOT NULL DEFAULT '', ALGORITHM=INPLACE, LOCK=NONE`,
18+
);
19+
}
20+
}
21+
22+
public async down(queryRunner: QueryRunner): Promise<void> {
23+
if (await columnExists(queryRunner, TABLE_NAME, COLUMN_NAME)) {
24+
await queryRunner.query(
25+
`ALTER TABLE ${TABLE_NAME} DROP COLUMN ${COLUMN_NAME}, ALGORITHM=INPLACE, LOCK=NONE`,
26+
);
27+
}
28+
}
29+
}

components/gitpod-db/src/workspace-db.spec.db.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class WorkspaceDBSpec {
6666
ideImage: "unknown",
6767
},
6868
deleted: false,
69-
attributedTeamId: undefined,
69+
usageAttributionId: "",
7070
};
7171
readonly wsi2: WorkspaceInstance = {
7272
workspaceId: this.ws.id,
@@ -89,7 +89,7 @@ class WorkspaceDBSpec {
8989
ideImage: "unknown",
9090
},
9191
deleted: false,
92-
attributedTeamId: undefined,
92+
usageAttributionId: "",
9393
};
9494
readonly ws2: Workspace = {
9595
id: "2",
@@ -127,7 +127,7 @@ class WorkspaceDBSpec {
127127
ideImage: "unknown",
128128
},
129129
deleted: false,
130-
attributedTeamId: undefined,
130+
usageAttributionId: "",
131131
};
132132

133133
readonly ws3: Workspace = {
@@ -165,7 +165,7 @@ class WorkspaceDBSpec {
165165
ideImage: "unknown",
166166
},
167167
deleted: false,
168-
attributedTeamId: undefined,
168+
usageAttributionId: "",
169169
};
170170

171171
async before() {

components/gitpod-protocol/src/workspace-instance.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ export interface WorkspaceInstance {
6464
workspaceClass?: string;
6565

6666
/**
67-
* Identifies the team to which this instance's runtime should be attributed to
67+
* Identifies the team or user to which this instance's runtime should be attributed to
6868
* (e.g. for usage analytics or billing purposes).
69-
* If unset, the usage should be attributed to the workspace's owner (ws.ownerId).
7069
*/
71-
attributedTeamId?: string;
70+
usageAttributionId?: string;
7271
}
7372

7473
// WorkspaceInstanceStatus describes the current state of a workspace instance

components/server/src/user/user-service.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,25 +207,24 @@ export class UserService {
207207
}
208208

209209
/**
210-
* Identifies the team to which a workspace instance's running time should be attributed to
210+
* Identifies the team or user to which a workspace instance's running time should be attributed to
211211
* (e.g. for usage analytics or billing purposes).
212-
* If no specific team is identified, the usage will be attributed to the user instead (default).
213212
*
214213
* @param user
215214
* @param projectId
216215
*/
217-
async getWorkspaceUsageAttributionTeamId(user: User, projectId?: string): Promise<string | undefined> {
216+
async getWorkspaceUsageAttributionId(user: User, projectId?: string): Promise<string | undefined> {
218217
if (!projectId) {
219218
// No project -- attribute to the user.
220-
return undefined;
219+
return `user:${user.id}`;
221220
}
222221
const project = await this.projectDb.findProjectById(projectId);
223222
if (!project?.teamId) {
224223
// The project doesn't exist, or it isn't owned by a team -- attribute to the user.
225-
return undefined;
224+
return `user:${user.id}`;
226225
}
227226
// Attribute workspace usage to the team that currently owns this project.
228-
return project.teamId;
227+
return `team:${project.teamId}`;
229228
}
230229

231230
/**

components/server/src/workspace/workspace-starter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ export class WorkspaceStarter {
722722
configuration.featureFlags = featureFlags;
723723
}
724724

725-
const attributedTeamId = await this.userService.getWorkspaceUsageAttributionTeamId(user, workspace.projectId);
725+
const usageAttributionId = await this.userService.getWorkspaceUsageAttributionId(user, workspace.projectId);
726726

727727
const now = new Date().toISOString();
728728
const instance: WorkspaceInstance = {
@@ -737,7 +737,7 @@ export class WorkspaceStarter {
737737
phase: "preparing",
738738
},
739739
configuration,
740-
attributedTeamId,
740+
usageAttributionId,
741741
};
742742
if (WithReferrerContext.is(workspace.context)) {
743743
this.analytics.track({

0 commit comments

Comments
 (0)