Skip to content

Commit 2095188

Browse files
author
wg102
committed
fix: delete old notebooks (pvc)
1 parent 22bdc13 commit 2095188

19 files changed

+407
-198
lines changed

frontend/src/app/app.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { NamespaceSelectComponent } from "./main-table/namespace-select/namespac
2929
import { ResourceTableComponent } from "./main-table/resource-table/resource-table.component";
3030
import { SnackBarComponent } from "./services/snack-bar/snack-bar.component";
3131
import { ResourceFormComponent } from "./resource-form/resource-form.component";
32-
import { ConfirmDialogComponent } from "./main-table/resource-table/confirm-dialog/confirm-dialog.component";
32+
import { ConfirmDialogComponent } from "./main-table/confirm-dialog/confirm-dialog.component";
3333
import { VolumeComponent } from "./resource-form/volume/volume.component";
3434
import { FormNameComponent } from "./resource-form/form-name/form-name.component";
3535
import { FormImageComponent } from "./resource-form/form-image/form-image.component";
@@ -48,6 +48,7 @@ import { RokFormDataVolumesComponent } from "./uis/rok/rok-resource-form/rok-for
4848
import { RokErrorMsgComponent } from "./uis/rok/rok-error-msg/rok-error-msg.component";
4949
import { FormConfigurationsComponent } from "./resource-form/form-configurations/form-configurations.component";
5050
import { FormGpusComponent } from "./resource-form/form-gpus/form-gpus.component";
51+
import { VolumeTableComponent } from "./main-table/volumes-table/volume-table.component";
5152

5253

5354
@NgModule({
@@ -77,6 +78,7 @@ import { FormGpusComponent } from "./resource-form/form-gpus/form-gpus.component
7778
RokErrorMsgComponent,
7879
FormConfigurationsComponent,
7980
FormGpusComponent,
81+
VolumeTableComponent,
8082
],
8183
imports: [
8284
BrowserModule,

frontend/src/app/main-table/main-table.component.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@
88
<!-- The Table showing our Resource -->
99
<div class="parent" [class.spacing]="ns.dashboardConnected()">
1010
<div class="spacer"></div>
11-
<app-resource-table></app-resource-table>
11+
<app-resource-table
12+
[notebooks]="resources"
13+
(deleteNotebookEvent)="deleteResource($event)"
14+
></app-resource-table>
1215
<div class="spacer"></div>
1316
</div>
17+
18+
<!-- The Table showing the persistent volume claims -->
19+
<div class="parent spacing">
20+
<div class="spacer"></div>
21+
<app-volume-table
22+
[custompvcs]="customPvcs"
23+
(deletePvcEvent)="deletePvc($event)"
24+
>
25+
</app-volume-table>
26+
<div class="spacer"></div>
27+
</div>
28+

frontend/src/app/main-table/main-table.component.scss

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,94 @@
99
.spacing {
1010
padding-top: 1.5rem;
1111
}
12+
13+
.card {
14+
width: 900px;
15+
padding: 0px;
16+
border-radius: 5px;
17+
background: white;
18+
}
19+
20+
table {
21+
width: 100%;
22+
}
23+
24+
.header {
25+
display: flex;
26+
align-items: center;
27+
padding: 0px 16px 0px 16px;
28+
height: 64px;
29+
}
30+
31+
.header p {
32+
font-weight: 400;
33+
font-size: 20px;
34+
}
35+
36+
.cdk-column-actions {
37+
text-align: center;
38+
}
39+
40+
.mat-icon {
41+
line-height: 0.85;
42+
}
43+
44+
td.mat-cell:last-of-type,
45+
td.mat-footer-cell:last-of-type,
46+
th.mat-header-cell:last-of-type {
47+
padding-right: 0px;
48+
}
49+
50+
.inline {
51+
display: inline-block;
52+
}
53+
54+
// Status Icons
55+
.running {
56+
color: green;
57+
}
58+
59+
.warning {
60+
color: orange;
61+
}
62+
63+
.error {
64+
color: red;
65+
}
66+
67+
.status {
68+
display: inline-flex;
69+
vertical-align: middle;
70+
}
71+
72+
.delete {
73+
color: red;
74+
}
75+
76+
// Flex
77+
.parent {
78+
display: flex;
79+
}
80+
81+
.spacer {
82+
flex-grow: 1;
83+
}
84+
85+
th,
86+
td {
87+
overflow: hidden;
88+
text-overflow: ellipsis;
89+
}
90+
91+
td.mat-column-image,
92+
td.mat-column-name {
93+
max-width: 200px;
94+
}
95+
96+
td.mat-column-cpu {
97+
width: 40px;
98+
}
99+
100+
td.mat-column-actions{
101+
text-align: center;
102+
}
Lines changed: 130 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,143 @@
11
import { Component, OnInit } from "@angular/core";
22
import { NamespaceService } from "../services/namespace.service";
3+
import { KubernetesService } from "src/app/services/kubernetes.service";
4+
5+
import { Subscription } from "rxjs";
6+
import { isEqual } from "lodash";
7+
import { first } from "rxjs/operators";
8+
9+
import { ExponentialBackoff } from "src/app/utils/polling";
10+
import { MatDialog } from "@angular/material/dialog";
11+
import { ConfirmDialogComponent } from "./confirm-dialog/confirm-dialog.component";
12+
import { Pvc, Volume, Resource } from "../utils/types";
13+
314

415
@Component({
516
selector: "app-main-table",
617
templateUrl: "./main-table.component.html",
718
styleUrls: ["./main-table.component.scss"]
819
})
920
export class MainTableComponent implements OnInit {
21+
currNamespace = "";
1022
namespaces = [];
11-
currNamespace: string;
23+
resources = [];
24+
usedPVCs: Set<string> = new Set<string>();
25+
pvcs: Volume[] = [];
26+
customPvcs: Pvc[] = [];
27+
28+
subscriptions = new Subscription();
29+
poller: ExponentialBackoff;
30+
31+
constructor(
32+
public ns: NamespaceService,
33+
private k8s: KubernetesService,
34+
private dialog: MatDialog
35+
) {}
36+
37+
ngOnInit() {
38+
this.poller = new ExponentialBackoff({ interval: 2000, retries: 3 });
39+
const resourcesSub = this.poller.start().subscribe(() => {
40+
if (!this.currNamespace) {
41+
return;
42+
}
43+
44+
let getVolumes = this.k8s.getVolumes(this.currNamespace).toPromise().then(
45+
pvcs => {
46+
if(isEqual(this.pvcs, pvcs)){
47+
return;
48+
}
49+
this.pvcs = pvcs;
50+
}
51+
);
52+
53+
let getResource = this.k8s.getResource(this.currNamespace).toPromise().then(
54+
resources => {
55+
if (isEqual(this.resources, resources)){
56+
return;
57+
}
58+
this.resources = resources;
59+
this.usedPVCs.clear();
60+
this.resources.forEach(res => {this.usedPVCs.add(res.volumes.forEach(element => {this.usedPVCs.add(element);}))})
61+
});
62+
63+
Promise.all([getVolumes, getResource])
64+
.then(val => {
65+
this.customPvcs = [];
66+
this.pvcs.forEach(vol => {
67+
this.customPvcs.push({pvc:vol, ismounted:this.usedPVCs.has(vol.name)});
68+
});
69+
});
70+
});
71+
72+
// Keep track of the selected namespace
73+
const namespaceSub = this.ns
74+
.getSelectedNamespace()
75+
.subscribe(namespace => {
76+
this.currNamespace = namespace;
77+
this.poller.reset();
78+
});
79+
80+
this.subscriptions.add(resourcesSub);
81+
this.subscriptions.add(namespaceSub);
82+
}
83+
84+
deleteResource(rsrc: Resource): void {
85+
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
86+
width: "fit-content",
87+
data: {
88+
title: "You are about to delete Notebook Server: " + rsrc.name,
89+
message:
90+
"Are you sure you want to delete this Notebook Server? " +
91+
"Your data might be lost if the Server is not backed by persistent storage.",
92+
yes: "delete",
93+
no: "cancel"
94+
}
95+
});
96+
97+
dialogRef
98+
.afterClosed()
99+
.pipe(first())
100+
.subscribe(result => {
101+
if (!result || result !== "delete") {
102+
return;
103+
}
104+
105+
this.k8s
106+
.deleteResource(rsrc.namespace, rsrc.name)
107+
.pipe(first())
108+
.subscribe(r => {
109+
this.poller.reset();
110+
});
111+
});
112+
}
113+
114+
deletePvc(p: Pvc): void {
115+
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
116+
width: "fit-content",
117+
data: {
118+
title: "You are about to delete the PVC: " + p.pvc.name,
119+
message:
120+
"Are you sure you want to delete this Persistent Volume Claim? ",
121+
yes: "delete",
122+
no: "cancel"
123+
}
124+
});
125+
126+
dialogRef
127+
.afterClosed()
128+
.pipe(first())
129+
.subscribe(result => {
130+
if (result !== "delete") {
131+
return;
132+
}
12133

13-
constructor(public ns: NamespaceService) {}
134+
this.k8s
135+
.deletePersistentStorageClaim(p.pvc.namespace, p.pvc.name)
136+
.pipe(first())
137+
.subscribe(r => {
138+
this.poller.reset();
139+
});
140+
});
141+
}
14142

15-
ngOnInit() {}
16143
}

frontend/src/app/main-table/resource-table/resource-table.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<mat-divider></mat-divider>
1515

16-
<table mat-table [dataSource]="dataSource" [trackBy]="trackByFn" matSort>
16+
<table mat-table [dataSource]="notebooks" matSort>
1717
<!-- Status Column -->
1818
<ng-container matColumnDef="status">
1919
<th mat-header-cell *matHeaderCellDef>Status</th>
Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +0,0 @@
1-
.card {
2-
width: 900px;
3-
padding: 0px;
4-
border-radius: 5px;
5-
background: white;
6-
}
7-
8-
table {
9-
width: 100%;
10-
}
11-
12-
.header {
13-
display: flex;
14-
align-items: center;
15-
padding: 0px 16px 0px 16px;
16-
height: 64px;
17-
}
18-
19-
.header p {
20-
font-weight: 400;
21-
font-size: 20px;
22-
}
23-
24-
.cdk-column-actions {
25-
text-align: center;
26-
}
27-
28-
.mat-icon {
29-
line-height: 0.85;
30-
}
31-
32-
td.mat-cell:last-of-type,
33-
td.mat-footer-cell:last-of-type,
34-
th.mat-header-cell:last-of-type {
35-
padding-right: 0px;
36-
}
37-
38-
.inline {
39-
display: inline-block;
40-
}
41-
42-
// Status Icons
43-
.running {
44-
color: green;
45-
}
46-
47-
.warning {
48-
color: orange;
49-
}
50-
51-
.error {
52-
color: red;
53-
}
54-
55-
.status {
56-
display: inline-flex;
57-
vertical-align: middle;
58-
}
59-
60-
.delete {
61-
color: red;
62-
}
63-
64-
// Flex
65-
.parent {
66-
display: flex;
67-
}
68-
69-
.spacer {
70-
flex-grow: 1;
71-
}
72-
73-
th,
74-
td {
75-
overflow: hidden;
76-
text-overflow: ellipsis;
77-
}
78-
79-
td.mat-column-image,
80-
td.mat-column-name {
81-
max-width: 200px;
82-
}
83-
84-
td.mat-column-cpu {
85-
width: 40px;
86-
}

0 commit comments

Comments
 (0)