Commit 79d45fa6 authored by Chris Hines's avatar Chris Hines
Browse files

add description for auth servers, fix...

add description for auth servers, fix #30, begin work on log file viewer
parent e1789f86
Pipeline #7652 passed with stages
in 3 minutes and 3 seconds
......@@ -10,6 +10,6 @@
<mat-sidenav-container style="height: 100%; width: 100%">
<mat-sidenav></mat-sidenav>
<mat-sidenav-content>
<router-outlet></router-outlet>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
......@@ -190,7 +190,7 @@ export class AuthorisationService {
let data = {'token': token.token, 'pubkey': sshpub, 'signing_url': token.sshauthzservice.sign};
this.http.post<any>(this.backendSelectionService.apiserver.value.tes+'/getcert',data, options)
.pipe(catchError(this.handleError([])))
//.pipe(catchError(this.handleError([])))
.subscribe(resp => this.makeKeyCert(newkeypair.private, resp, token.sshauthzservice),
error => this.signingError(error,token.sshauthzservice));
}
......@@ -226,12 +226,15 @@ public getKeys(id?: Identity) {
let path=sessionStorage.getItem('path');
//skip1 because loggedInAuthZ is a behaviour subject and we don't want the current value but the value
this.loggedInAuthZ.pipe(skip(1),take(1)).subscribe( () => {this.readyToNavigate.next([true,path])});
console.log('cert generated, adding keycert to agent');
this.sshAdd(keyCert);
// only navigate once the agent contents has been refreshed
}
public querySshAgentError(error: any) {
this.agentContents.next([]);
console.log('querySshAgentError');
console.log(error);
if (error.status == 0) {
this.statusMsg.next("A network error occured. Are you connected to the internet?")
}
......@@ -250,7 +253,7 @@ public getKeys(id?: Identity) {
var anyvar: any;
this.http.get<any>(this.backendURI+'/sshagent',options)
.pipe(catchError(this.handleError(anyvar)))
.subscribe(resp => { this.agentContents.next(resp); this.statusMsg.next("") },
.subscribe(resp => { this.agentContents.next(resp); console.log('agent response'); console.log(resp); this.statusMsg.next("") },
error => this.querySshAgentError(error));
// .subscribe(resp => this.computeSitesService.updateIdentities(resp),
// error => this.httperror(error))
......
......@@ -158,6 +158,8 @@ export class ComputesitesService {
// If the agent contents is set to null we are probably still updating it
console.log('updating app identities');
console.log(resp);
console.log(this.authorisationService.agentContents.value)
if (resp == null) {
return
}
......
......@@ -10,9 +10,13 @@
<div> {{ timeremaining }} </div>
</div>
<div fxFlex></div>
<div fxFlex="10%" fxLayout="row">
<div fxFlex="15%" fxLayout="row">
<div fxFlex *ngIf="!nocancel"> <button mat-button (click)="onCancel()" > Cancel </button> </div>
<div fxFlex *ngIf="jobdata.state == 'RUNNING' && jobdata.app !== null && jobdata.app.client !== null"> <button mat-button (click)="onConnect()"> Connect </button> </div>
<div *ngFor="let action of jobdata.app.actions">
<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>
</div>
</div>
</div>
......
......@@ -4,6 +4,7 @@ import {TesService} from '../tes.service';
import { StrudelappsService } from '../strudelapps.service';
import { timer, Subscription } from 'rxjs';
import { repeat } from 'rxjs/operators';
import { AppAction, Strudelapp} from '../strudelapp';
@Component({
selector: 'app-job',
......@@ -32,6 +33,15 @@ export class JobComponent implements OnInit, OnDestroy {
this.updatesub = timer(1000).pipe(repeat()).subscribe(() => this.updateFields());
}
parseDate(date) {
const parsed = Date.parse(date);
if (!isNaN(parsed)) {
return parsed;
}
return Date.parse(date.replace(/-/g, '/').replace(/[a-z]+/gi, ' '));
}
updateFields() {
if (this.jobdata.state == "RUNNING") {
this.available = true;
......@@ -55,10 +65,11 @@ export class JobComponent implements OnInit, OnDestroy {
this.resources = this.resources+" Mem: "+this.jobdata.mem;
}
if (this.jobdata.endtime != undefined) {
let end = Date.parse(this.jobdata.endtime);
let end = this.parseDate(this.jobdata.endtime);
let remaining = end.valueOf() - Date.now().valueOf();
this.timeremaining = "Time remaining: "+this.secondsToHms(remaining/1000);
} else {
console.log('jobdata endtime is undefined');
}
}
......@@ -76,10 +87,12 @@ export class JobComponent implements OnInit, OnDestroy {
this.tesService.cancel(this.jobdata);
}
onConnect() {
onConnect(action: AppAction) {
console.log('called on connect');
console.log(action)
// Before connecting we must resolve what type of app we are connecting to
// this.jobdata.app = this.strudelAppsService.getApp(this.jobdata.name);
this.tesService.connect(this.jobdata);
this.tesService.connect(this.jobdata,action);
}
}
......@@ -10,7 +10,7 @@
<span class="fill-horizontal-space"></span>
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container style="height: 100%; width: 100%">
<mat-sidenav-container style="height: 100%; width: 100%">
<mat-sidenav #idSideNav mode="side" opened>
<div fxLayout="column" style="height: 100%">
<div>
......
......@@ -132,12 +132,13 @@ export class LauncherComponent implements OnInit {
console.log('in navLogin');
if (o == null) {
console.log('not redireting null');
return
}
if (o.length == 0) {
console.log('redireting length == 0');
this.router.navigate(['/login']);
} else {
console.log('not redirecting, ids detected');
}
}
......
......@@ -30,8 +30,7 @@
<button mat-flat-button (click)="login()" color=primary style="width: 25%; text-align: center">Login</button>
<button *ngIf="(authService.loggedInAuthZ | async).length > 0" mat-flat-button routerLink="/launch" color=warn style="width: 25%; text-align: center">Cancel</button>
</div>
<div *ngIf="selected !== undefined">
{{ selected.desc }}
<div *ngIf="selected !== undefined" [innerHTML]="selected.desc">
</div>
</div>
<div fxFlex></div>
......
......@@ -31,7 +31,7 @@ export class ShareconnectComponent implements OnInit {
}
connect(jobdata: Job) {
this.tesService.connect(jobdata);
//this.tesService.connect(jobdata);
}
onSubmit() {
......
export class AppAction {
name: string;
paramscmd: string;
client: {cmd: string[], redir: string};
states: string[]; // list of stats such as 'RUNNING' in which the action is valid. null||undefined if its always valid
}
export class Strudelapp {
url: string; // A url used to retrieve extra config options. May be null
name: string; // Human readable name
startscript: string; // batch script ... should NOT include resource directives
// resource directives like #SBATCH belong in the batchinterface
paramscmd: string; // command to return extra data such as passwords and tokens
// values returned here can be used in the client strings
client: {cmd: string[], redir: string};
actions: AppAction[];
localbind: boolean; // does the application bind to a port on the localhost
// interface or on all interfaces. This behaviour determins
/// how we create tunnels
......
......@@ -4,7 +4,7 @@ import { Observable, Subject, BehaviorSubject, of, from } from 'rxjs';
import { fromEvent, throwError, Subscription } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { Job } from './job';
import { Strudelapp, StrudelappInstance } from './strudelapp';
import { AppAction, Strudelapp, StrudelappInstance } from './strudelapp';
import { Computesite, Health } from './computesite';
import { APIServer } from './apiserver';
import { Identity, AuthToken, KeyCert, SshAuthzServer } from './identity';
......@@ -382,7 +382,7 @@ addUserHealth(identity,resp) {
}
}
public getAppInstance(job: Job) {
public getAppInstance(job: Job, action: AppAction) {
let username = job.identity.username;
let loginhost = job.identity.site.host;
let batchhost = job.batch_host;
......@@ -390,13 +390,13 @@ addUserHealth(identity,resp) {
let params = new URLSearchParams;
let headers = new HttpHeaders();
let options = { headers: headers, withCredentials: true};
params.set('cmd',JSON.stringify(job.app.paramscmd));
params.set('cmd',JSON.stringify(action.paramscmd));
let paramstr = params.toString();
job.connectionState = 1;
console.log('in getAppInstance');
this.http.get<string>(this.Base+'/appinstance/'+username+'/'+loginhost+'/'+batchhost+'/'+jobid+'?'+paramstr, options)
// .pipe(catchError(this.handleError))
.subscribe(resp => { job.appinst = resp; this.createTunnel(job) },
.subscribe(resp => { job.appinst = resp; this.createTunnel(job, action) },
error => { this.handleAppInstanceError(job,error) })
// let paramstr = this.buildParams(job.app,job.identity,this.batchinterface[job.identity.repr()]);
// let headers = new HttpHeaders();
......@@ -406,7 +406,7 @@ addUserHealth(identity,resp) {
// .subscribe(resp => { job.appinst = <StrudelappInstance>resp; this.openAppWindow(job);});
}
public createTunnel(job: Job) {
public createTunnel(job: Job, action: AppAction) {
let username = job.identity.username;
let loginhost = job.identity.site.host;
let batchhost = job.batch_host;
......@@ -419,17 +419,18 @@ addUserHealth(identity,resp) {
//while(new Date().getTime() < now + sleepDuration){ /* do nothing */ }
let options = { headers: headers, withCredentials: true};
params.set('cmd',JSON.stringify(job.app.paramscmd));
//params.set('cmd',JSON.stringify(action.paramscmd));
let paramstr = params.toString();
this.http.post<string>(this.Base+'/createtunnel/'+username+'/'+loginhost+'/'+batchhost+'?'+paramstr, job.appinst, options)
.subscribe(() => { this.getAppUrl(job) } )
.subscribe(() => { this.getAppUrl(job, action) } )
}
public getAppUrl(job: Job) {
public getAppUrl(job: Job, action: AppAction) {
let params = new URLSearchParams;
let headers = new HttpHeaders();
let options = { headers: headers, withCredentials: true};
params.set('app',JSON.stringify(job.app));
let pseudoapp = {'client':{'redir':action.client.redir}};
params.set('app',JSON.stringify(pseudoapp));
params.set('appinst',JSON.stringify(job.appinst));
let paramstr = params.toString();
job.connectionState = 3;
......@@ -440,8 +441,8 @@ addUserHealth(identity,resp) {
}
public getInterface(job: Job) {
this.getAppInstance(job);
public getInterface(job: Job, action: AppAction) {
this.getAppInstance(job, action);
}
public openAppWindow(url: any) {
......@@ -457,10 +458,10 @@ addUserHealth(identity,resp) {
}
}
public connect(job: Job, appinst?: any) {
public connect(job: Job, action: AppAction, appinst?: any) {
let headers = new HttpHeaders();
let options = { headers: headers, withCredentials: true};
this.getInterface(job); // getInterface will subsequently called getAppInstance, which will call createTunnel, which will openAppWindow
this.getInterface(job,action); // getInterface will subsequently called getAppInstance, which will call createTunnel, which will openAppWindow
}
......
......@@ -13,6 +13,11 @@
"name": "Dev - Pawsey",
"tes": "https://strudel2-api-dev-pawsey.cloud.cvl.org.au/tes",
"tws": "https://strudel2-api-dev-pawsey.cloud.cvl.org.au"
},
{
"name": "localhost",
"tes": "http://localhost:8080",
"tws": "http://localhost:8090"
}
]
......
......@@ -10,6 +10,20 @@
"icon": null,
"scope": "user:email",
"cafp": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
"signup": "https://docs.massive.org.au/M3/requesting-an-account.html"
"signup": "https://docs.massive.org.au/M3/requesting-an-account.html",
"desc": "The Characterisaion Virtual Laboratory focuses on providing tools necessary for processing various experimental data such as MRI CT and EM imaging techniques.<p>By Authenticating to the CVL you will gain access to the M3 cluster at Monash University"
},
{
"authorise": "https://sshauthz.cloud.cvl.org.au/pysshauthz/oauth2/oauth/authorize/choose",
"base": "https://sshauthz.cloud.cvl.org.au/pysshauthz/oauth2/",
"client_id": "Q96kt2Vtw6S78dpORktM81DH",
"sign": "https://sshauthz.cloud.cvl.org.au/pysshauthz/sign/monash_hpcid/api/v1/sign_key",
"logout": "https://sshauthz.cloud.cvl.org.au/pysshauthz/oauth2/logout",
"name": "Don't select me",
"icon": null,
"scope": "user:email",
"cafp": "RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I",
"signup": "https://docs.massive.org.au/M3/requesting-an-account.html",
"desc": "This is a bogus authorisation server. It exists so that we can see the proposed position of various links in the test environment.<p> If you use this server it functions exactly the same as the CVL Option"
}
]
......@@ -2,8 +2,19 @@
{ "url": null,
"name": "Desktop",
"startscript": "#!/bin/bash\n/usr/local/sv2/dev/desktop/desktop.slurm\n ",
"actions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/desktop/params.py {jobid}",
"client": {"cmd": null, "redir": "vnc.html?password={password}" },
"states": ["RUNNING"]
},
{
"name": "View log",
"paramscmd": "blahblahblah",
"client": {"cmd": null, "redir": "/viewlog" }
}
],
"localbind": true,
"applist": null
},
......@@ -11,24 +22,13 @@
"url": null,
"name": "Jupyter Lab",
"startscript": "#!/bin/bash\n/usr/local/sv2/dev/jupyter/jupyter.slurm\n",
"actions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/jupyter/jupyter_params.py",
"client": {"cmd": null, "redir": "?token={token}"},
"localbind": true,
"applist": null
},
{ "url": "transfer",
"name": "Transfer files",
"startscript": "#!/bin/bash\n echo '{appparams}' | /usr/local/sv2/dev/copytool.py\n",
"paramscmd": null,
"client": {"cmd": null, "redir": null },
"localbind": true,
"applist": null
},
{ "url": null,
"name": "Transfer files v2",
"startscript": "#!/bin/bash\n echo '{keys}' > keys.json ; echo {ids} > ids.json\n",
"paramscmd": null,
"client": {"cmd": null, "redir": null },
"client": {"cmd": null, "redir": "?token={token}"}
}
],
"localbind": true,
"applist": null
},
......@@ -36,8 +36,12 @@
"url": null,
"name": "CryoSPARC",
"startscript": null,
"actions": [ {
"name": "Connect",
"paramscmd": "/usr/local/sv2/dev/cryosparc/cryosparc_params.py",
"client": {"cmd": null, "redir": ""},
"client": {"cmd": null, "redir": ""}
}],
"localbind": true,
"applist": null
}
......
[
{ "url": null,
"name": "Desktop",
"startscript": "#!/bin/bash\n#SBATCH -w m3a002\n/usr/local/sv2/dev/desktop/desktop.slurm\n ",
"paramscmd": "/usr/local/sv2/dev/desktop/params.py {jobid}",
"client": {"cmd": null, "redir": "vnc.html?password={password}" },
"startscript": "#!/bin/bash\n/usr/local/sv2/dev/desktop/desktop.slurm\n ",
"actions": [ {
"name": "Connect",
"paramscmd": "/usr/local/sv2/desktop/params.py {jobid}",
"client": {"cmd": null, "redir": "vnc.html?password={password}" }
}],
"localbind": true,
"applist": null
},
......@@ -11,24 +14,13 @@
"url": null,
"name": "Jupyter Lab",
"startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter.slurm\n",
"actions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/jupyter/jupyter_params.py",
"client": {"cmd": null, "redir": "?token={token}"},
"localbind": true,
"applist": null
},
{ "url": "transfer",
"name": "Transfer files",
"startscript": "#!/bin/bash\n echo '{appparams}' | /usr/local/sv2/dev/copytool.py\n",
"paramscmd": null,
"client": {"cmd": null, "redir": null },
"localbind": true,
"applist": null
},
{ "url": null,
"name": "Transfer files v2",
"startscript": "#!/bin/bash\n echo '{keys}' > sshkeys.json\n",
"paramscmd": null,
"client": {"cmd": null, "redir": null },
"client": {"cmd": null, "redir": "?token={token}"}
}
],
"localbind": true,
"applist": null
},
......@@ -36,8 +28,12 @@
"url": null,
"name": "CryoSPARC",
"startscript": null,
"actions": [ {
"name": "Connect",
"paramscmd": "/usr/local/sv2/cryosparc/cryosparc_params.py",
"client": {"cmd": null, "redir": ""},
"client": {"cmd": null, "redir": ""}
}],
"localbind": true,
"applist": null
}
......
......@@ -2,8 +2,11 @@
{ "url": null,
"name": "Desktop",
"startscript": "#!/bin/bash\n/usr/local/sv2/desktop/desktop.slurm\n ",
"actions": [ {
"name": "Connect",
"paramscmd": "/usr/local/sv2/desktop/params.py {jobid}",
"client": {"cmd": null, "redir": "vnc.html?password={password}" },
"client": {"cmd": null, "redir": "vnc.html?password={password}" }
}],
"localbind": true,
"applist": null
},
......@@ -11,8 +14,13 @@
"url": null,
"name": "Jupyter Lab",
"startscript": "#!/bin/bash\n/usr/local/sv2/jupyter/jupyter.slurm\n",
"actions": [
{
"name": "Connect",
"paramscmd": "/usr/local/sv2/jupyter/jupyter_params.py",
"client": {"cmd": null, "redir": "?token={token}"},
"client": {"cmd": null, "redir": "?token={token}"}
}
],
"localbind": true,
"applist": null
},
......@@ -20,8 +28,12 @@
"url": null,
"name": "CryoSPARC",
"startscript": null,
"actions": [ {
"name": "Connect",
"paramscmd": "/usr/local/sv2/cryosparc/cryosparc_params.py",
"client": {"cmd": null, "redir": ""},
"client": {"cmd": null, "redir": ""}
}],
"localbind": true,
"applist": null
}
......
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