Create snap feature

This commit is contained in:
Manuel Romero
2025-02-12 11:40:19 +01:00
parent 5238ad3810
commit 2e015a70b3
12 changed files with 79 additions and 17 deletions

View File

@@ -29,5 +29,5 @@
<link rel="stylesheet" href="styles.89804dbd9a428c1d7bdd.css"></head>
<body>
<app-root></app-root>
<script src="runtime.b2175705264e769e2e1d.js" defer></script><script src="polyfills-es5.66d659991e5a8ec6fd9f.js" nomodule defer></script><script src="polyfills.3273b4fb03b5abe684b4.js" defer></script><script src="scripts.399e476bb5562d6fc683.js" defer></script><script src="main.4272f6917bb79b0bca79.js" defer></script></body>
<script src="runtime.b2175705264e769e2e1d.js" defer></script><script src="polyfills-es5.66d659991e5a8ec6fd9f.js" nomodule defer></script><script src="polyfills.3273b4fb03b5abe684b4.js" defer></script><script src="scripts.399e476bb5562d6fc683.js" defer></script><script src="main.356bbac41f1ddb67b22f.js" defer></script></body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -29,5 +29,5 @@
<link rel="stylesheet" href="styles.89804dbd9a428c1d7bdd.css"></head>
<body>
<app-root></app-root>
<script src="runtime.b2175705264e769e2e1d.js" defer></script><script src="polyfills-es5.66d659991e5a8ec6fd9f.js" nomodule defer></script><script src="polyfills.3273b4fb03b5abe684b4.js" defer></script><script src="scripts.399e476bb5562d6fc683.js" defer></script><script src="main.4272f6917bb79b0bca79.js" defer></script></body>
<script src="runtime.b2175705264e769e2e1d.js" defer></script><script src="polyfills-es5.66d659991e5a8ec6fd9f.js" nomodule defer></script><script src="polyfills.3273b4fb03b5abe684b4.js" defer></script><script src="scripts.399e476bb5562d6fc683.js" defer></script><script src="main.356bbac41f1ddb67b22f.js" defer></script></body>
</html>

View File

@@ -43,13 +43,6 @@ services:
ports:
- "27017:27017"
cli:
build:
context: .
dockerfile: qmi-cloud-cli/Dockerfile
image: qlikgear/qmi-cloud-cli:latest
app:
build:
context: .
@@ -101,10 +94,10 @@ services:
- backend
worker:
build:
context: .
dockerfile: qmi-cloud-worker/Dockerfile
image: qlikgear/qmi-cloud-worker:latest
#build:
# context: .
# dockerfile: qmi-cloud-worker/Dockerfile
image: qlikgear/qmi-cloud-worker:latestdev
container_name: qmi-cloud-worker
restart: on-failure
environment:

View File

@@ -322,7 +322,7 @@ router.get('/:id/logs', passport.ensureAuthenticated, async (req, res, next) =>
*/
router.get('/:id/snapshots', passport.ensureAuthenticated, async (req, res, next) => {
try {
const snaps = await db.snapshot.get({"provision": req.params.id});
const snaps = await db.snapshot.get({"provision": req.params.id}, null, null, null, '["provision","owner"]');
return res.json(snaps);
} catch (error) {

View File

@@ -23,6 +23,7 @@ const routes: Routes = [
{ path: 'error', component: ErrorComponent},
{ path: 'scenarios', component: ScenariosSectionComponent, canActivate: [AuthGuard]},
{ path: 'provision/:id', component: ProvComponent, canActivate: [AuthGuard]},
{ path: 'snapshots/:id', component: ProvComponent, canActivate: [AuthGuard]},
{ path: 'provisions', component: ProvisionsComponent, canActivate: [AuthGuard]},
{ path: 'sharedprovision', component: ProvisionsSharedComponent, canActivate: [AuthGuard]},
{ path: 'cost-analysis', component: CostComponent, canActivate: [AuthGuard]},

View File

@@ -336,6 +336,39 @@
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<h4 class="card-title">Snapshots
<button *ngIf="creating" disabled mdbBtn color="dark-green" class="waves-light" style="margin-left: 5px;" size="sm" mdbWavesEffect >
<span>Creating </span>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</button>
<button *ngIf="!creating" mdbBtn color="dark-green" class="waves-light" style="margin-left: 5px;" size="sm" mdbWavesEffect (click)="createNewSnap()">+ Create New</button>
</h4>
<div class="card-body" *ngIf="snapshots.length">
<table class="table table-sm">
<thead>
<tr>
<th>CreatedAt</th>
<th>By</th>
<th>Snapshot Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of snapshots; let i = index">
<td style="min-width: 120px">
{{ item.created | date: "MMM dd, yyyy - H:mm" }}
</td>
<td>{{item.owner? item.owner.displayName : 'QMI Platform'}}</td>
<td style="min-width: 130px">{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<h4 class="card-title">Events</h4>

View File

@@ -20,7 +20,9 @@ export class ProvComponent implements OnInit {
subscription: Subscription;
provisionId;
provision;
creating: boolean = false;
events;
snapshots;
private _userId;
logstype: String = 'provision';
logShow: boolean = false;
@@ -44,6 +46,13 @@ s
es.unsubscribe();
});
}
private _refreshSnapshots() {
var es = this._provisionsService.getSnapshots(this.provisionId).subscribe(res=> {
this.snapshots = res.results;
es.unsubscribe();
});
}
private _refreshShares() {
var ss = this._provisionsService.getSharesForProvision(this.provision.user._id, this.provisionId).subscribe(res=> {
@@ -58,6 +67,7 @@ s
this.provision = provision;
this._refreshEvents();
this._refreshShares();
this._refreshSnapshots();
});
this._qlikService.costSubject.subscribe(function(value){
@@ -66,6 +76,15 @@ s
}
createNewSnap(): void {
this.creating = true;
var instantSubs = this._provisionsService.createSnapshots(this.provision._id).subscribe( provisions=>{
instantSubs.unsubscribe();
this._refreshSnapshots();
this.creating = false;
});
}
getCost(id) : string {
if (this.costData && this.costData[id] ) {

View File

@@ -164,6 +164,14 @@ export class ProvisionsService {
}*/
getSnapshots(id) : Observable<any> {
return this.httpClient.get(`${environment.apiVersionPath}/provisions/${id}/snapshots`);
}
createSnapshots(id) : Observable<any> {
return this.httpClient.post(`${environment.apiVersionPath}/provisions/${id}/snapshots`, null);
}
getProvisionLogs(id) : Observable<any> {
return this.httpClient.get(`${environment.apiVersionPath}/provisions/${id}/logs`, {responseType: 'text'});
}

View File

@@ -119,6 +119,9 @@
<button style="margin-right: 3px;" title="Renew 24x7 period" *ngIf="(!provision.isDestroyed && provision.status === 'provisioned' && provision.statusVms === 'Running') && (!provision.schedule || provision.schedule.is24x7)" (click)="openConfirmExtendModal(provision)" class="lui-button">
<mdb-icon fas icon="redo-alt"></mdb-icon>
</button>
<button style="margin-right: 3px;" title="Stop" *ngIf="(provision.vmImage && provision.vmImage.vm1 || provision.options && provision.options.vm1) && !provision.isDestroyed && provision.status === 'provisioned'" (click)="openSnapshotModal(provision)" class="lui-button">
<mdb-icon fas icon="camera"></mdb-icon>
</button>
</td>
</tr>
</tbody>

View File

@@ -9,6 +9,7 @@ import { Subscription } from 'rxjs';
import { ProvisionModalComponent } from '../modals/edit-provision.component';
import * as moment from 'moment-timezone';
import { QlikService } from '../services/qs.service';
import { Router } from '@angular/router';
@Component({
selector: 'table-provisions',
@@ -54,7 +55,7 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
maxVisibleItems: number = 25;
constructor(private modalService: MDBModalService, private _alertService: AlertService, private cdRef: ChangeDetectorRef, private _provisionsService: ProvisionsService, private _qlikService: QlikService) {
constructor(private modalService: MDBModalService, private _alertService: AlertService, private cdRef: ChangeDetectorRef, private _provisionsService: ProvisionsService, private _qlikService: QlikService, private router: Router) {
}
@@ -179,6 +180,10 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
});
}
openSnapshotModal(provision){
this.router.navigate(['/snapshots', provision._id]);
}
openRemoteAccess(provision) {
let url = provision.outputs.WEB_RDP_ACCESS_WITH_GUACAMOLE || provision.outputs.WEB_SSH_ACCESS_WITH_GUACAMOLE;
window.open(url, provision._id);