Commit 1e8214b5 authored by Chris Hines's avatar Chris Hines
Browse files

allow for appication actions and instance actions

parent cf18bbbe
Pipeline #7921 passed with stages
in 4 minutes and 42 seconds
......@@ -27,7 +27,7 @@
<button *ngIf="(authService.loggedOutAuthZ | async).length > 0" mat-menu-item routerLink="/login"><mat-icon>exit_to_app</mat-icon>More services</button>
<div *ngFor="let id of (computeSitesService.appidentities | async)">
<button mat-button fxFlex
[routerLink]="['/launch',id.displayName()]"
[routerLink]="['/launch',id.displayName(),'accountinfo']"
routerLinkActive #rla="routerLinkActive"
[disabled]="rla.isActive"
[routerLinkActiveOptions]="{'exact': false}"
......
......@@ -12,7 +12,7 @@
<div fxFlex></div>
<div fxFlex fxLayout="row">
<div fxFlex *ngIf="!nocancel"> <button mat-button (click)="onCancel()" > Cancel </button> </div>
<div *ngFor="let action of jobdata.app.actions">
<div *ngFor="let action of jobdata.app.instactions">
<div fxFlex *ngIf="action.states === undefined || action.states === null || action.states.indexOf(jobdata.state) != -1">
<button mat-button (click)="onConnect(action)">{{ action.name }}</button>
</div>
......
......@@ -10,9 +10,12 @@
<iframe [src]="appconfigsafeurl" style="border: none; border-style: none; border-width: 0px; width: 100%" [style.height]="appconfigheight+'px'" #batchbuilderiframe></iframe>
</div>-->
<div *ngIf="appSubject | async as app">
<div fxLayout="row" fxLayoutAlign="space-around">
<button *ngIf="appconfigsafeurl !== null" mat-flat-button (click)="configdialog()" color="primary">Configure</button>
<button mat-flat-button (click)="launch()" color="primary" #launchbtn [disabled]="!readyToLaunch">Launch</button>
<button *ngFor="let action of app.appactions" mat-flat-button (click)="runaction(action)" color="primary" >{{ action.name }}</button>
</div>
</div>
</div>
</div>
......@@ -7,9 +7,10 @@ import { Observable, merge, pipe, timer, Subscription} from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { take, skip } from 'rxjs/operators';
import { Identity } from '../identity';
import { Strudelapp } from '../strudelapp';
import { Strudelapp, AppAction } from '../strudelapp';
import { BatchInterface} from '../batchinterface';
import { fromEvent } from 'rxjs';
import { Job } from '../job';
@Component({
......@@ -131,6 +132,7 @@ export class LaunchDialogComponent implements OnInit {
}
receiveMessage(event) {
console.log(event);
console.log('received a message');
if (event.data['batchcmd'] !== undefined) {
this.submitcmd.next(event.data['batchcmd']);
}
......@@ -140,6 +142,32 @@ export class LaunchDialogComponent implements OnInit {
}
}
runaction(action: AppAction) {
console.log('attempting to run action',action.name);
console.log(action.paramscmd);
if (action.paramscmd.indexOf('{submitcmd}') != -1) {
this.batchbuilderiframe.nativeElement.contentWindow.postMessage('launch selected',"*");
this.submitcmd.pipe(skip(1),take(1)).subscribe( (submitcmd) => { console.log('submitcmd changed',submitcmd); this.reallyRunAction(submitcmd,action)})
} else {
console.log('submitcmd not present');
this.reallyRunAction('',action);
}
}
reallyRunAction(submitcmd: string, action: AppAction) {
var job: Job;
var newaction: AppAction;
job = new Job();
job.identity = this.identity;
job.batch_host = 'localhost';
job.jobid='1';
newaction = new AppAction();
newaction.paramscmd = action.paramscmd.replace(/\{submitcmd\}/,submitcmd);
console.log('really runAction');
console.log(newaction.paramscmd);
this.tesService.connect(job,newaction);
}
launch() {
// tell the batchbuilder iframe that lanch was selected
// This is the cue to save the values as defaults for next launch
......
......@@ -71,7 +71,7 @@ export class LauncherComponent implements OnInit {
) {
this.subscriptions = [];
this.subscriptions.push(this.authService.sshAuthzServers.subscribe(o => {this.updateSshAuthZServers(o)}));
this.subscriptions.push(this.authService.loggedInAuthZ.subscribe(o => this.navLogin(o)));
//this.subscriptions.push(this.authService.loggedInAuthZ.subscribe(o => this.navLogin(o)));
this.subscriptions.push(this.computeSitesService.appidentities.subscribe(o => this.getHealth(o)));
this.app$ = new BehaviorSubject<Strudelapp>(null);
this.identity$ = new BehaviorSubject<Identity>(null);
......@@ -175,19 +175,43 @@ export class LauncherComponent implements OnInit {
}
id = this.getId(ids);
this.identity$.next(id);
if (id === null) {
if (this.computeSitesService.appidentities.value === null || this.computeSitesService.appidentities.value.length == 0) {
this.identity$.next(null);
this.router.navigate(['/login']);
return;
} else {
this.router.navigate(['/launch',this.computeSitesService.appidentities.value[0].displayName(),'accountinfo']);
return
}
}
}
updateIdApp(params: ParamMap) {
var ids: string = params.get('site');
var apps: string = params.get('app');
if (ids === null) {
if (this.computeSitesService.appidentities.value === null || this.computeSitesService.appidentities.value.length == 0) {
this.identity$.next(null);
this.router.navigate(['/login']);
return;
} else {
this.router.navigate(['/launch',this.computeSitesService.appidentities.value[0].displayName(),'accountinfo']);
return
}
}
var id: Identity = this.getId(ids);
if (id === null) {
console.log('id is null, callback updateIdApp');
this.computeSitesService.appidentities.pipe(skip(1),filter((v) => v !== null && v.length > 0),take(1)).subscribe(() => this.updateIdApp(params));
if (this.computeSitesService.appidentities.value === null || this.computeSitesService.appidentities.value.length == 0) {
this.identity$.next(null);
this.router.navigate(['/login']);
return;
} else {
this.router.navigate(['/launch',this.computeSitesService.appidentities.value[0].displayName(),'accountinfo']);
return
}
//this.computeSitesService.appidentities.pipe(skip(1),filter((v) => v !== null && v.length > 0),take(1)).subscribe(() => this.updateIdApp(params));
return
}
if (id !== this.identity$.value) {
......
......@@ -88,7 +88,7 @@ export class LoginComponent implements OnInit {
}
navLaunch(o) {
if (this.computeSitesService.appidentities.value.length > 0) {
if (this.computeSitesService.appidentities.value !== null && this.computeSitesService.appidentities.value.length > 0) {
this.router.navigate(['/launch']);
}
}
......
......@@ -12,7 +12,7 @@ export class SettingsService {
constructor() {
this.menuToggle$ = new BehaviorSubject<boolean>(true);
this.theme$ = new BehaviorSubject<string>('strudel-theme-light');
this.useMenu$ = new BehaviorSubject<boolean>(false);
this.useMenu$ = new BehaviorSubject<boolean>(true);
this.getTheme();
}
......
......@@ -9,7 +9,8 @@ export class Strudelapp {
name: string;
startscript: string; // batch script ... should NOT include resource directives
// resource directives like #SBATCH belong in the batchinterface
actions: AppAction[];
appactions: AppAction[]; // appactions don't require an instance. i.e. they take place on the login submit node
instactions: AppAction[]; // instactions apply to a particular instance of an application, eg connecting to a running desktop
localbind: boolean; // does the application bind to a port on the localhost
// interface or on all interfaces. This behaviour determins
/// how we create tunnels
......
......@@ -416,7 +416,7 @@ addUserHealth(identity,resp) {
job.connectionState = 1;
this.http.get<string>(this.Base+'/appinstance/'+username+'/'+loginhost+'/'+batchhost+'/'+jobid+'?'+paramstr, options)
// .pipe(catchError(this.handleError))
.subscribe(resp => { job.appinst = resp; if (action.client != null) { this.createTunnel(job, action) } else { job.connectionState = 0} },
.subscribe(resp => { console.log('ran',action.paramscmd,'got',resp); job.appinst = resp; if (action.client != null) { this.createTunnel(job, action) } else { job.connectionState = 0} },
error => { this.handleAppInstanceError(job,error) })
// let paramstr = this.buildParams(job.app,job.identity,this.batchinterface[job.identity.repr()]);
// let headers = new HttpHeaders();
......@@ -513,6 +513,9 @@ addUserHealth(identity,resp) {
public connect(job: Job, action: AppAction, appinst?: any) {
let headers = new HttpHeaders();
let options = { headers: headers, withCredentials: true};
console.log('called connect');
console.log(action);
console.log(job);
this.getInterface(job,action); // getInterface will subsequently called getAppInstance, which will call createTunnel, which will openAppWindow
}
......
......@@ -2,7 +2,16 @@
{ "url": null,
"name": "Desktop",
"startscript": "#!/bin/bash\n/usr/local/sv2/dev/desktop/desktop.slurm\n ",
"actions": [
"appactions": [
{
"name": "Clear Logs",
"paramscmd": "/home/chines/rmlogs Desktop",
"client": {"cmd": null, "redir": null},
"states": null
}
],
"instactions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/desktop/params.py {jobid}",
......@@ -35,7 +44,7 @@
"url": null,
"name": "Jupyter Lab",
"startscript": "#!/bin/bash\n/usr/local/sv2/dev/jupyter/jupyter.slurm\n",
"actions": [
"instactions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/jupyter/jupyter_params.py {jobid}",
......@@ -69,7 +78,7 @@
"url": null,
"name": "Jupyter Lab - custom venv",
"startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter_custom.sh\n",
"actions": [
"instactions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/jupyter/jupyter_params.py {jobid}",
......@@ -103,7 +112,7 @@
"url": null,
"name": "CryoSPARC",
"startscript": null,
"actions": [ {
"instactions": [ {
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/cryosparc/cryosparc_params.py",
"client": {"cmd": null, "redir": ""}
......@@ -116,7 +125,7 @@
"url": null,
"name": "History",
"startscript": "#!/bin/bash\n/usr/local/sv2/dev/desktop/desktop.slurm\n ",
"actions": [
"instactions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/jupyter/jupyter_params.py {jobid}",
......@@ -151,7 +160,7 @@
{ "url": null,
"name": "File Explorer",
"startscript": "#!/bin/bash\n/usr/local/sv2/cloudcmd/start.sh\n ",
"actions": [
"instactions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/cloudcmd/params.py {jobid}",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment