Skip to content

Prepare merging of "workspace cluster" DB tables #8539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions chart/templates/db-migrations-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ spec:
- name: db-migrations
image: "{{ template "gitpod.comp.imageFull" (dict "root" . "gp" .Values "comp" $.Values.components.dbMigrations) }}"
env:
- name: INSTALLATION_SHORTNAME
value: "{{ $.Values.installation.shortname }}"
- name: "DB_USERNAME"
value: "{{ $.Values.db.username }}"
- name: "DB_PASSWORD"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export class DBWorkspaceCluster implements WorkspaceCluster {
@PrimaryColumn()
name: string;

@PrimaryColumn({
default: '',
})
/** This column is going to replace 'govern' in the near future. During the transition period - and to ease transition/reduce x-team dependencies - we make this part of the PK. */
governedBy: string;

@Column({
type: "varchar",
length: 255,
Expand Down Expand Up @@ -58,6 +64,7 @@ export class DBWorkspaceCluster implements WorkspaceCluster {
maxScore: number;

@Column()
/** @deprecated */
govern: boolean;

@Column({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License-AGPL.txt in the project root for license information.
*/

import { MigrationInterface, QueryRunner } from "typeorm";
import { columnExists } from "./helper/helper";

export class GovernedBy1645797755961 implements MigrationInterface {

public async up(queryRunner: QueryRunner): Promise<void> {
if (!process.env.INSTALLATION_SHORTNAME) {
throw new Error("Migration requires `INSTALLATION_SHORTNAME` to be set!");
}

const TABLE_NAME = "d_b_workspace_cluster";
const COLUMN_NAME = "governedBy";

if (!(await columnExists(queryRunner, TABLE_NAME, COLUMN_NAME))) {
await queryRunner.query(`ALTER TABLE ${TABLE_NAME} ADD COLUMN ${COLUMN_NAME} varchar(255) NOT NULL DEFAULT ''`);
}

await queryRunner.query(`UPDATE TABLE ${TABLE_NAME} SET governedBy = '${process.env.INSTALLATION_SHORTNAME}' WHERE govern = TRUE`);
await queryRunner.query(`ALTER TABLE ${TABLE_NAME} DROP PRIMARY KEY, ADD PRIMARY KEY(name, ${COLUMN_NAME})`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
}
}
11 changes: 6 additions & 5 deletions components/gitpod-db/src/typeorm/workspace-cluster-db-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* See License-AGPL.txt in the project root for license information.
*/

import { Repository, EntityManager, DeepPartial } from "typeorm";
import { injectable, inject } from "inversify";
import { TypeORM } from "./typeorm";
import { Repository, EntityManager, DeepPartial } from "typeorm";
import { injectable, inject } from "inversify";
import { TypeORM } from "./typeorm";
import { WorkspaceClusterDB } from "../workspace-cluster-db";
import { DBWorkspaceCluster } from "./entity/db-workspace-cluster";
import { WorkspaceCluster, WorkspaceClusterFilter, WorkspaceClusterWoTLS } from "@gitpod/gitpod-protocol/lib/workspace-cluster";
Expand Down Expand Up @@ -48,6 +48,7 @@ import { WorkspaceCluster, WorkspaceClusterFilter, WorkspaceClusterWoTLS } from
maxScore: 0,
state: "available",
govern: false,
governedBy: "",
admissionConstraints: [],
};

Expand All @@ -61,8 +62,8 @@ import { WorkspaceCluster, WorkspaceClusterFilter, WorkspaceClusterWoTLS } from
if (predicate.minScore !== undefined) {
qb = qb.andWhere("wsc.score >= :minScore", predicate);
}
if (predicate.govern !== undefined) {
qb = qb.andWhere("wsc.govern = :govern", predicate);
if (predicate.governedBy !== undefined) {
qb = qb.andWhere("wsc.governedBy = :governedBy", predicate);
}
if (predicate.url !== undefined) {
qb = qb.andWhere("wsc.url = :url", predicate);
Expand Down
9 changes: 6 additions & 3 deletions components/gitpod-protocol/src/workspace-cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import { PermissionName } from './permission';

export interface WorkspaceCluster {
// Name of the workspace cluster.
// This is the string set in each
// Must be identical to the installationShortname of the cluster it represents!
// This is the string that is set to every WorkspaceInstance.region field
name: string;

// URL of the cluster's ws-manager API
Expand All @@ -31,8 +30,12 @@ export interface WorkspaceCluster {
score: number;

// True if this bridge should control this cluster
/** @deprecated */
govern: boolean;

/** Contains the application cluster's installationShortname (e.g., eu01) that is in charge to govern this cluster */
governedBy: string;

// An optional set of constraints that limit who can start workspaces on the cluster
admissionConstraints?: AdmissionConstraint[];
}
Expand Down Expand Up @@ -99,6 +102,6 @@ export interface WorkspaceClusterDB {
*/
findFiltered(predicate: DeepPartial<WorkspaceClusterFilter>): Promise<WorkspaceClusterWoTLS[]>;
}
export interface WorkspaceClusterFilter extends Pick<WorkspaceCluster, "state" | "govern" | "url"> {
export interface WorkspaceClusterFilter extends Pick<WorkspaceCluster, "state" | "governedBy" | "url"> {
minScore: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ class TestClientProvider {
c.bind(WorkspaceManagerClientProviderCompositeSource).toSelf().inSingletonScope();
c.bind(WorkspaceManagerClientProviderSource).toDynamicValue((): WorkspaceManagerClientProviderSource => {
const cluster: WorkspaceCluster[] = [
{ name: "c1", govern: true, maxScore: 100, score: 0, state: "cordoned", url: "", admissionConstraints: [] },
{ name: "c2", govern: true, maxScore: 100, score: 50, state: "cordoned", url: "", admissionConstraints: [] },
{ name: "c3", govern: false, maxScore: 100, score: 50, state: "cordoned", url: "", admissionConstraints: [] },
{ name: "a1", govern: true, maxScore: 100, score: 0, state: "available", url: "", admissionConstraints: [] },
{ name: "a2", govern: true, maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [] },
{ name: "a3", govern: false, maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [] },
{ name: "c1", govern: true, governedBy: "app1", maxScore: 100, score: 0, state: "cordoned", url: "", admissionConstraints: [] },
{ name: "c2", govern: true, governedBy: "app1", maxScore: 100, score: 50, state: "cordoned", url: "", admissionConstraints: [] },
{ name: "c3", govern: false, governedBy: "app1", maxScore: 100, score: 50, state: "cordoned", url: "", admissionConstraints: [] },
{ name: "a1", govern: true, governedBy: "app1", maxScore: 100, score: 0, state: "available", url: "", admissionConstraints: [] },
{ name: "a2", govern: true, governedBy: "app1", maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [] },
{ name: "a3", govern: false, governedBy: "app1", maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [] },
{
name: "con1", govern: true, maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [
name: "con1", govern: true, governedBy: "app1", maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [
{ type: "has-permission", permission: "new-workspace-cluster" },
]
},
{
name: "con2", govern: true, maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [
name: "con2", govern: true, governedBy: "app1", maxScore: 100, score: 50, state: "available", url: "", admissionConstraints: [
{ type: "has-permission", permission: "monitor" }, // This is meant to representent a permission that does not take special predence (cmp. constraints.ts)
]
},
Expand Down
6 changes: 6 additions & 0 deletions components/ws-manager-bridge-api/cluster-service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ message RegisterRequest {
// DEPRECATED
// repeated AdmissionPreference admission_preference = 6;
reserved 6;

optional string governed_by = 7;
}

message RegisterResponse {}
Expand All @@ -38,6 +40,7 @@ message TlsConfig {
message RegistrationHints {
Preferability perfereability = 1;
bool cordoned = 2;
// DEPRECATED
bool govern = 3;
}

Expand Down Expand Up @@ -67,13 +70,16 @@ message ClusterStatus {
ClusterState state = 3;
int32 score = 4;
int32 max_score = 5;
// DEPRECATED
bool governed = 6;
repeated AdmissionConstraint admission_constraint = 7;
bool static = 8;

// DEPRECATED
// repeated AdmissionPreference admission_preference = 9;
reserved 9;

string governed_by = 10;
}

enum ClusterState {
Expand Down
Loading