Skip to content

Commit 4471b48

Browse files
committed
tryng to add VolumeSnapshot to DB and protocl
1 parent 16ade7f commit 4471b48

File tree

17 files changed

+185
-11
lines changed

17 files changed

+185
-11
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 { PrimaryColumn, Column, Entity, Index } from "typeorm";
8+
9+
import { VolumeSnapshot } from "@gitpod/gitpod-protocol";
10+
import { TypeORM } from "../typeorm";
11+
import { Transformer } from "../transformer";
12+
13+
@Entity()
14+
@Index("ind_dbsync", ["creationTime"]) // DBSync
15+
export class DBVolumeSnapshot implements VolumeSnapshot {
16+
@PrimaryColumn(TypeORM.UUID_COLUMN_TYPE)
17+
id: string;
18+
19+
@Column({
20+
type: "timestamp",
21+
precision: 6,
22+
default: () => "CURRENT_TIMESTAMP(6)",
23+
transformer: Transformer.MAP_ISO_STRING_TO_TIMESTAMP_DROP,
24+
})
25+
creationTime: string;
26+
27+
@Column(TypeORM.WORKSPACE_ID_COLUMN_TYPE)
28+
@Index("ind_originalWorkspaceId")
29+
originalWorkspaceId: string;
30+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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 { tableExists } from "./helper/helper";
9+
10+
export class VolumeSnapshotCreation1651188368768 implements MigrationInterface {
11+
public async up(queryRunner: QueryRunner): Promise<void> {
12+
await queryRunner.query(
13+
`CREATE TABLE IF NOT EXISTS d_b_volume_snapshot ( id char(36) NOT NULL, creationTime timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), originalWorkspaceId char(36) NOT NULL, PRIMARY KEY (id), KEY ind_originalWorkspaceId (originalWorkspaceId), KEY ind_dbsync (creationTime)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`,
14+
);
15+
}
16+
17+
public async down(queryRunner: QueryRunner): Promise<void> {
18+
if (await tableExists(queryRunner, "d_b_volume_snapshot")) {
19+
await queryRunner.query("DROP TABLE `d_b_volume_snapshot`");
20+
}
21+
}
22+
}

components/gitpod-db/src/typeorm/workspace-db-impl.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
WorkspaceInstanceUser,
2626
WhitelistedRepository,
2727
Snapshot,
28+
VolumeSnapshot,
2829
LayoutData,
2930
PrebuiltWorkspace,
3031
RunningWorkspaceInfo,
@@ -41,6 +42,7 @@ import { DBWorkspace } from "./entity/db-workspace";
4142
import { DBWorkspaceInstance } from "./entity/db-workspace-instance";
4243
import { DBLayoutData } from "./entity/db-layout-data";
4344
import { DBSnapshot } from "./entity/db-snapshot";
45+
import { DBVolumeSnapshot } from "./entity/db-volume-snapshot";
4446
import { DBWorkspaceInstanceUser } from "./entity/db-workspace-instance-user";
4547
import { DBRepositoryWhiteList } from "./entity/db-repository-whitelist";
4648
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
@@ -79,6 +81,10 @@ export abstract class AbstractTypeORMWorkspaceDBImpl implements WorkspaceDB {
7981
return await (await this.getManager()).getRepository<DBSnapshot>(DBSnapshot);
8082
}
8183

84+
protected async getVolumeSnapshotRepo(): Promise<Repository<DBVolumeSnapshot>> {
85+
return await (await this.getManager()).getRepository<DBVolumeSnapshot>(DBVolumeSnapshot);
86+
}
87+
8288
protected async getPrebuiltWorkspaceRepo(): Promise<Repository<DBPrebuiltWorkspace>> {
8389
return await (await this.getManager()).getRepository<DBPrebuiltWorkspace>(DBPrebuiltWorkspace);
8490
}
@@ -700,6 +706,34 @@ export abstract class AbstractTypeORMWorkspaceDBImpl implements WorkspaceDB {
700706
return snapshots.find({ where: { originalWorkspaceId: workspaceId } });
701707
}
702708

709+
public async findVolumeSnapshotById(volumeSnapshotId: string): Promise<VolumeSnapshot | undefined> {
710+
const volumeSnapshots = await this.getVolumeSnapshotRepo();
711+
return volumeSnapshots.findOne(volumeSnapshotId);
712+
}
713+
714+
public async storeVolumeSnapshot(volumeSnapshot: VolumeSnapshot): Promise<VolumeSnapshot> {
715+
const volumeSnapshots = await this.getVolumeSnapshotRepo();
716+
const dbVolumeSnapshot = volumeSnapshots as DBVolumeSnapshot;
717+
return await volumeSnapshots.save(dbVolumeSnapshot);
718+
}
719+
720+
public async deleteVolumeSnapshot(volumeSnapshotId: string): Promise<void> {
721+
const volumeSnapshots = await this.getVolumeSnapshotRepo();
722+
await volumeSnapshots.delete(volumeSnapshotId);
723+
}
724+
725+
public async updateVolumeSnapshot(
726+
volumeSnapshot: DeepPartial<VolumeSnapshot> & Pick<VolumeSnapshot, "id">,
727+
): Promise<void> {
728+
const volumeSnapshots = await this.getVolumeSnapshotRepo();
729+
await volumeSnapshots.update(volumeSnapshot.id, volumeSnapshot);
730+
}
731+
732+
public async findVolumeSnapshotsByWorkspaceId(workspaceId: string): Promise<VolumeSnapshot[]> {
733+
const volumeSnapshots = await this.getVolumeSnapshotRepo();
734+
return volumeSnapshots.find({ where: { originalWorkspaceId: workspaceId } });
735+
}
736+
703737
public async storePrebuiltWorkspace(pws: PrebuiltWorkspace): Promise<PrebuiltWorkspace> {
704738
const repo = await this.getPrebuiltWorkspaceRepo();
705739
if (pws.error && pws.error.length > 255) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
WorkspaceInstanceUser,
1414
WhitelistedRepository,
1515
Snapshot,
16+
VolumeSnapshot,
1617
LayoutData,
1718
PrebuiltWorkspace,
1819
PrebuiltWorkspaceUpdatable,
@@ -159,6 +160,12 @@ export interface WorkspaceDB {
159160
deleteSnapshot(snapshotId: string): Promise<void>;
160161
updateSnapshot(snapshot: DeepPartial<Snapshot> & Pick<Snapshot, "id">): Promise<void>;
161162

163+
findVolumeSnapshotById(volumeSnapshotId: string): Promise<VolumeSnapshot | undefined>;
164+
findVolumeSnapshotsByWorkspaceId(workspaceId: string): Promise<VolumeSnapshot[]>;
165+
storeVolumeSnapshot(snapshot: VolumeSnapshot): Promise<VolumeSnapshot>;
166+
deleteVolumeSnapshot(volumeSnapshotId: string): Promise<void>;
167+
updateVolumeSnapshot(snapshot: DeepPartial<VolumeSnapshot> & Pick<VolumeSnapshot, "id">): Promise<void>;
168+
162169
storePrebuiltWorkspace(pws: PrebuiltWorkspace): Promise<PrebuiltWorkspace>;
163170
findPrebuiltWorkspaceByCommit(cloneURL: string, commit: string): Promise<PrebuiltWorkspace | undefined>;
164171
findPrebuildsWithWorkpace(cloneURL: string): Promise<PrebuildWithWorkspace[]>;

components/gitpod-protocol/src/protocol.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,12 @@ export interface Snapshot {
482482
message?: string;
483483
}
484484

485+
export interface VolumeSnapshot {
486+
id: string;
487+
creationTime: string;
488+
originalWorkspaceId: string;
489+
}
490+
485491
export type SnapshotState = "pending" | "available" | "error";
486492

487493
export interface LayoutData {

components/ws-manager-api/core.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,9 @@ message WorkspaceConditions {
373373

374374
// stopped_by_request is true if the workspace was stopped using a StopWorkspace call
375375
WorkspaceConditionBool stopped_by_request = 11;
376+
377+
// pvc_snapshot_volume contains the name of snapshot volume that was used to save persistent volume
378+
string pvc_snapshot_volume = 12;
376379
}
377380

378381
// WorkspaceConditionBool is a trinary bool: true/false/empty

components/ws-manager-api/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/gitpod-io/generated_code_dependencies
22

33
go 1.18
4+
5+
require google.golang.org/protobuf v1.28.0 // indirect

components/ws-manager-api/go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
2+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
3+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4+
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
5+
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
6+
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

components/ws-manager-api/go/core.pb.go

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/ws-manager-api/go/core_grpc.pb.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/ws-manager-api/typescript/src/core_pb.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ export class WorkspaceConditions extends jspb.Message {
724724
setHeadlessTaskFailed(value: string): WorkspaceConditions;
725725
getStoppedByRequest(): WorkspaceConditionBool;
726726
setStoppedByRequest(value: WorkspaceConditionBool): WorkspaceConditions;
727+
getPvcSnapshotVolume(): string;
728+
setPvcSnapshotVolume(value: string): WorkspaceConditions;
727729

728730
serializeBinary(): Uint8Array;
729731
toObject(includeInstance?: boolean): WorkspaceConditions.AsObject;
@@ -747,6 +749,7 @@ export namespace WorkspaceConditions {
747749
firstUserActivity?: google_protobuf_timestamp_pb.Timestamp.AsObject,
748750
headlessTaskFailed: string,
749751
stoppedByRequest: WorkspaceConditionBool,
752+
pvcSnapshotVolume: string,
750753
}
751754
}
752755

components/ws-manager-api/typescript/src/core_pb.js

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@
1919

2020
var jspb = require('google-protobuf');
2121
var goog = jspb;
22-
var global = (function() { return this || window || global || self || Function('return this')(); }).call(null);
22+
var global = (function() {
23+
if (this) { return this; }
24+
if (typeof window !== 'undefined') { return window; }
25+
if (typeof global !== 'undefined') { return global; }
26+
if (typeof self !== 'undefined') { return self; }
27+
return Function('return this')();
28+
}.call(null));
2329

2430
var content$service$api_initializer_pb = require('@gitpod/content-service/lib');
2531
goog.object.extend(proto, content$service$api_initializer_pb);
@@ -5700,7 +5706,8 @@ proto.wsman.WorkspaceConditions.toObject = function(includeInstance, msg) {
57005706
networkNotReady: jspb.Message.getFieldWithDefault(msg, 8, 0),
57015707
firstUserActivity: (f = msg.getFirstUserActivity()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
57025708
headlessTaskFailed: jspb.Message.getFieldWithDefault(msg, 10, ""),
5703-
stoppedByRequest: jspb.Message.getFieldWithDefault(msg, 11, 0)
5709+
stoppedByRequest: jspb.Message.getFieldWithDefault(msg, 11, 0),
5710+
pvcSnapshotVolume: jspb.Message.getFieldWithDefault(msg, 12, "")
57045711
};
57055712

57065713
if (includeInstance) {
@@ -5778,6 +5785,10 @@ proto.wsman.WorkspaceConditions.deserializeBinaryFromReader = function(msg, read
57785785
var value = /** @type {!proto.wsman.WorkspaceConditionBool} */ (reader.readEnum());
57795786
msg.setStoppedByRequest(value);
57805787
break;
5788+
case 12:
5789+
var value = /** @type {string} */ (reader.readString());
5790+
msg.setPvcSnapshotVolume(value);
5791+
break;
57815792
default:
57825793
reader.skipField();
57835794
break;
@@ -5878,6 +5889,13 @@ proto.wsman.WorkspaceConditions.serializeBinaryToWriter = function(message, writ
58785889
f
58795890
);
58805891
}
5892+
f = message.getPvcSnapshotVolume();
5893+
if (f.length > 0) {
5894+
writer.writeString(
5895+
12,
5896+
f
5897+
);
5898+
}
58815899
};
58825900

58835901

@@ -6080,6 +6098,24 @@ proto.wsman.WorkspaceConditions.prototype.setStoppedByRequest = function(value)
60806098
};
60816099

60826100

6101+
/**
6102+
* optional string pvc_snapshot_volume = 12;
6103+
* @return {string}
6104+
*/
6105+
proto.wsman.WorkspaceConditions.prototype.getPvcSnapshotVolume = function() {
6106+
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, ""));
6107+
};
6108+
6109+
6110+
/**
6111+
* @param {string} value
6112+
* @return {!proto.wsman.WorkspaceConditions} returns this
6113+
*/
6114+
proto.wsman.WorkspaceConditions.prototype.setPvcSnapshotVolume = function(value) {
6115+
return jspb.Message.setProto3StringField(this, 12, value);
6116+
};
6117+
6118+
60836119

60846120

60856121

components/ws-manager/pkg/manager/annotations.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ const (
6666
// pvcWorkspaceFeatureAnnotation is set on workspaces which are using persistent_volume_claim feature
6767
pvcWorkspaceFeatureAnnotation = "gitpod.io/pvcFeature"
6868

69+
// pvcWorkspaceSnapshotVolumeAnnotation stores snapshot volume name when snapshot was created from pvc
70+
pvcWorkspaceSnapshotVolumeAnnotation = "gitpod.io/snapshotVolumeName"
71+
6972
// gitpodFinalizerName is the name of the Gitpod finalizer we use to clean up a workspace
7073
gitpodFinalizerName = "gitpod.io/finalizer"
7174

components/ws-manager/pkg/manager/create.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"github.com/gitpod-io/gitpod/common-go/kubernetes"
2828
wsk8s "github.com/gitpod-io/gitpod/common-go/kubernetes"
29+
"github.com/gitpod-io/gitpod/common-go/log"
2930
"github.com/gitpod-io/gitpod/common-go/tracing"
3031
content "github.com/gitpod-io/gitpod/content-service/pkg/initializer"
3132
regapi "github.com/gitpod-io/gitpod/registry-facade/api"
@@ -300,6 +301,7 @@ func (m *Manager) createDefiniteWorkspacePod(startContext *startWorkspaceContext
300301
return nil, xerrors.Errorf("cannot create remarshal image spec: %w", err)
301302
}
302303

304+
log.Infof("Initializer: %v", *(startContext.Request.Spec.Initializer))
303305
initCfg, err := proto.Marshal(startContext.Request.Spec.Initializer)
304306
if err != nil {
305307
return nil, xerrors.Errorf("cannot create remarshal initializer: %w", err)

components/ws-manager/pkg/manager/imagespec.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/gitpod-io/gitpod/common-go/kubernetes"
1818
wsk8s "github.com/gitpod-io/gitpod/common-go/kubernetes"
19+
"github.com/gitpod-io/gitpod/common-go/log"
1920
"github.com/gitpod-io/gitpod/common-go/tracing"
2021
csapi "github.com/gitpod-io/gitpod/content-service/api"
2122
"github.com/gitpod-io/gitpod/content-service/pkg/layer"
@@ -74,6 +75,7 @@ func (m *Manager) GetImageSpec(ctx context.Context, req *regapi.GetImageSpecRequ
7475
if err != nil {
7576
return nil, xerrors.Errorf("cannot unmarshal init config: %w", err)
7677
}
78+
log.Infof("Initializer data: %v", initializer)
7779
var cl []layer.Layer
7880
if pvcFeatureEnabled {
7981
cl, _, err = m.Content.GetContentLayerPVC(ctx, owner, workspaceID, &initializer)

0 commit comments

Comments
 (0)