Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
hpc-team
strudelv2_spa
Commits
d1d506ef
Commit
d1d506ef
authored
Jul 23, 2018
by
Chris Hines
Browse files
lots of development to sv2
parent
2a260a4f
Changes
24
Hide whitespace changes
Inline
Side-by-side
src/app/app.component.html
View file @
d1d506ef
...
...
@@ -4,8 +4,8 @@
<span
class=
"fill-remaining-space"
></span>
<span
class=
"fill-remaining-space"
></span>
<!-- <app-siteselection></app-siteselection> -->
<button
mat-button
*ngIf=
"authorised"
(click)=
"logout()"
>
Logout
</button>
<button
mat-button
*ngIf=
"!authorised"
(click)=
"login()"
>
Login
</button>
<!--
<button mat-button *ngIf="authorised" (click)="logout()">Logout</button>
<button mat-button *ngIf="!authorised" (click)="login()">Login</button>
-->
</mat-toolbar-row>
</mat-toolbar>
...
...
src/app/app.component.ts
View file @
d1d506ef
...
...
@@ -17,7 +17,6 @@ export class AppComponent {
};
ngOnInit
()
{
setTimeout
(()
=>
{
this
.
tesService
.
authorised
.
subscribe
(
authorised
=>
{
this
.
authorised
=
authorised
});
});
// this.tesService.testingAuth.subscribe(testingAuth => { this.testingAuth = testingAuth; console.log('testingAuth updated'+this.testingAuth) });
// this.testingAuth = false;
}
...
...
src/app/app.module.ts
View file @
d1d506ef
...
...
@@ -3,7 +3,7 @@ import { NgModule } from '@angular/core';
import
{
AppComponent
}
from
'
./app.component
'
;
import
{
LauncherComponent
,
DialogPlaceholder
}
from
'
./launcher/launcher.component
'
;
import
{
LauncherComponent
}
from
'
./launcher/launcher.component
'
;
import
{
JoblistComponent
}
from
'
./joblist/joblist.component
'
;
import
{
MatButtonModule
}
from
'
@angular/material
'
;
import
{
MatFormFieldModule
}
from
'
@angular/material
'
;
...
...
@@ -27,6 +27,8 @@ import { SiteselectionComponent } from './siteselection/siteselection.component'
import
{
TeserrorsComponent
}
from
'
./teserrors/teserrors.component
'
;
import
{
AppRoutingModule
}
from
'
.//app-routing.module
'
;
import
{
TokenextractorComponent
}
from
'
./tokenextractor/tokenextractor.component
'
;
import
{
LogindialogComponent
}
from
'
./logindialog/logindialog.component
'
;
import
{
LogoutdialogComponent
}
from
'
./logoutdialog/logoutdialog.component
'
;
...
...
@@ -38,8 +40,9 @@ import { TokenextractorComponent } from './tokenextractor/tokenextractor.compone
JobComponent
,
SiteselectionComponent
,
TeserrorsComponent
,
DialogPlaceholder
,
TokenextractorComponent
TokenextractorComponent
,
LogindialogComponent
,
LogoutdialogComponent
],
imports
:
[
BrowserModule
,
...
...
@@ -60,7 +63,7 @@ import { TokenextractorComponent } from './tokenextractor/tokenextractor.compone
AppRoutingModule
,
],
entryComponents
:
[
DialogPlaceholder
],
entryComponents
:
[
LogindialogComponent
,
LogoutdialogComponent
],
providers
:
[
StrudelappsService
,
ComputesitesService
,
TesService
,
MatDialog
],
bootstrap
:
[
AppComponent
]
})
...
...
src/app/computesite.ts
View file @
d1d506ef
...
...
@@ -7,4 +7,18 @@ export class Computesite {
cafingerprint
:
string
;
// Certificates contain a CA fingerprint. We use this
// to figure out which compute site a certificate is valid
// for
appCatalog
:
Strudelapp
[];
}
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
};
localbind
:
boolean
;
// does the application bind to a port on the localhost
// interface or on all interfaces. This behaviour determins
/// how we create tunnels
}
src/app/computesites.service.ts
View file @
d1d506ef
...
...
@@ -2,7 +2,9 @@ import { Injectable } from '@angular/core';
import
{
Computesite
}
from
'
./computesite
'
;
import
{
COMPUTESITES
}
from
'
./mock-compute-site
'
;
@
Injectable
()
@
Injectable
({
providedIn
:
'
root
'
,
})
export
class
ComputesitesService
{
constructor
()
{
}
...
...
src/app/identity.ts
View file @
d1d506ef
import
{
Computesite
}
from
'
./computesite
'
;
// Identities are defined by a username on a computer, but rather than just
// Identities are defined by a username on a computer, but rather than just
// DNS entry, there is extra info in the Computesite
export
class
Identity
{
username
:
string
;
site
:
Computesite
;
authservice
:
AuthService
;
constructor
(
username
:
string
,
site
:
Computesite
)
{
this
.
username
=
username
;
this
.
site
=
site
;
}
displayName
():
string
{
return
this
.
username
+
'
@
'
+
this
.
site
.
name
;
}
repr
():
string
{
return
JSON
.
stringify
([
this
.
username
,
this
.
site
.
cafingerprint
,
this
.
site
.
host
]);
}
}
export
class
AuthToken
{
token
:
string
;
authservice
:
AuthService
;
constructor
(
token
:
string
,
authservice
:
AuthService
)
{
this
.
token
=
token
;
this
.
authservice
=
authservice
;
}
}
export
class
KeyCert
{
key
:
string
;
cert
:
string
;
authservice
:
AuthService
;
}
export
class
AuthService
{
base
:
string
;
authorise
:
string
;
sign
:
string
;
client_id
:
string
;
}
src/app/job/job.component.ts
View file @
d1d506ef
...
...
@@ -19,15 +19,20 @@ export class JobComponent implements OnInit {
}
ngOnInit
()
{
console
.
log
(
'
creating job component
'
);
if
(
this
.
jobdata
.
state
==
"
RUNNING
"
)
{
this
.
available
=
true
;
}
else
{
this
.
available
=
false
;
}
this
.
tesService
.
busy
.
subscribe
(
busy
=>
this
.
busy
=
busy
);
console
.
log
(
'
creating job component complete
'
);
}
onCancel
()
{
this
.
jobdata
.
app
=
this
.
strudelAppsService
.
getApp
(
this
.
jobdata
.
name
);
console
.
log
(
this
.
jobdata
);
this
.
tesService
.
cancel
(
this
.
jobdata
);
}
...
...
src/app/joblist/joblist.component.html
View file @
d1d506ef
<div
*ngIf=
"
job
s.length == 0"
>
<div
*ngIf=
"
identitie
s.length == 0"
>
<mat-card>
You don't appear to have any jobs
</mat-card>
Click identity and login to a service to start an application.
</mat-card>
</div>
<div
*ngFor=
"let job of jobs"
>
<app-job
[jobdata]=
job
></app-job>
<div
*ngFor=
"let id of identities"
>
<mat-card>
<mat-card-title>
{{ id.displayName() }}
</mat-card-title>
<div
*ngIf=
"jobs[id.repr()] == undefined || jobs[id.repr()].length == 0 "
>
No jobs running yet
</div>
<div
*ngFor=
"let job of jobs[id.repr()]"
>
<app-job
[jobdata]=
job
></app-job>
</div>
</mat-card>
</div>
src/app/joblist/joblist.component.ts
View file @
d1d506ef
...
...
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import
{
TesService
}
from
'
../tes.service
'
;
import
{
Job
}
from
'
../job
'
;
import
{
Observable
}
from
'
rxjs/Observable
'
;
import
{
Identity
}
from
'
../identity
'
;
...
...
@@ -11,16 +12,20 @@ import { Observable } from 'rxjs/Observable';
styleUrls
:
[
'
./joblist.component.css
'
]
})
export
class
JoblistComponent
implements
OnInit
{
public
jobs
:
any
[]
=
[];
public
jobs
:
{[
id
:
string
]:
Job
[]
}
=
{};
public
identities
:
Identity
[];
private
displayedColumns
=
[
'
id
'
];
private
jobsSubscription
:
any
;
private
idSubscription
:
any
;
constructor
(
private
tesService
:
TesService
,)
{
}
constructor
(
private
tesService
:
TesService
,)
{
}
ngOnInit
()
{
this
.
jobsSubscription
=
this
.
tesService
.
joblist
.
subscribe
(
jobs
=>
this
.
jobs
=
jobs
);
console
.
log
(
"
jobs subscribed by joblist component
"
);
console
.
log
(
'
creating joblist component
'
);
this
.
jobsSubscription
=
this
.
tesService
.
joblist
.
subscribe
(
jobs
=>
this
.
updateJobs
(
jobs
));
this
.
idSubscription
=
this
.
tesService
.
identities
.
subscribe
(
ids
=>
this
.
updateIds
(
ids
));
console
.
log
(
"
joblist component complete
"
);
}
public
ngOnDestroy
():
void
{
...
...
@@ -29,21 +34,18 @@ export class JoblistComponent implements OnInit {
}
}
updateIds
(
identities
:
Identity
[])
{
console
.
log
(
'
update identities
'
);
this
.
identities
=
identities
;
console
.
log
(
'
update identities complete
'
);
updateJobs
(
jobs
)
{
this
.
jobs
=
jobs
;
console
.
log
(
"
job data received by the joblist component
"
);
console
.
log
(
this
.
jobs
);
}
login
()
{
//Wire this up to the tes login component to get an ssh cert on the tes backend
//This will also tell the TES which site we are using
return
;
updateJobs
(
jobs
)
{
console
.
log
(
'
updating jobs
'
)
this
.
jobs
=
jobs
;
console
.
log
(
'
update jobs complete
'
)
}
logout
()
{
return
;
}
}
src/app/launcher/launcher.component.html
View file @
d1d506ef
<div
*ngIf=
"authorised"
>
<mat-form-field>
<mat-select
placeholder=
"Identity"
(selectionChange)=
"selectId($event)"
>
<mat-option
*ngFor=
"let id of identities"
[value]=
id
>
{{id.displayName()}}
</mat-option>
<mat-option>
<button
mat-button
(click)=
login()
>
Login ...
</button>
</mat-option>
<mat-option>
<button
mat-button
(click)=
logout()
>
Logout
</button>
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select
placeholder=
"Application"
[(value)]=
app
>
<mat-option
*ngFor=
"let a of strudelapps"
[value]=
a
>
...
...
@@ -7,12 +20,8 @@
</mat-option>
</mat-select>
</mat-form-field>
<button
mat-button
(click)=
configureResources()
>
Configure Resources
</button>
<button
mat-button
(click)=
configureApp()
[disabled]=
"!app"
>
Configure App
</button>
<button
mat-button
(click)=
submitApp()
[disabled]=
"!app"
>
Start
</button>
<button
mat-button
(click)=
configureResources()
[disabled]=
"!app || !identity"
>
Configure Resources
</button>
<!--
<button mat-button (click)=configureApp() [disabled]="!app
|| !identity
">Configure App</button>
-->
<button
mat-button
(click)=
submitApp()
[disabled]=
"!app
|| !identity
"
>
Start
</button>
<app-joblist></app-joblist>
</div>
src/app/launcher/launcher.component.ts
View file @
d1d506ef
...
...
@@ -3,7 +3,10 @@ import {Strudelapp} from '../strudelapp';
import
{
StrudelappsService
}
from
'
../strudelapps.service
'
;
import
{
MatDialog
,
MatDialogRef
,
MAT_DIALOG_DATA
,
MatDialogModule
}
from
'
@angular/material
'
;
import
{
TesService
}
from
'
../tes.service
'
;
import
{
Identity
}
from
'
../identity
'
;
import
{
Identity
}
from
'
../identity
'
;
import
{
Computesite
}
from
'
../computesite
'
;
import
{
LogoutdialogComponent
}
from
'
../logoutdialog/logoutdialog.component
'
;
import
{
LogindialogComponent
}
from
'
../logindialog/logindialog.component
'
...
...
@@ -18,68 +21,93 @@ export class LauncherComponent implements OnInit {
private
app
:
Strudelapp
;
public
authorised
:
boolean
;
private
identity
:
Identity
;
private
identities
:
Identity
[];
constructor
(
private
strudelappsService
:
StrudelappsService
,
public
dialog
:
MatDialog
,
private
tesService
:
TesService
)
{
}
ngOnInit
()
{
this
.
loadStrudelapps
();
setTimeout
(
()
=>
{
this
.
tesService
.
authorised
.
subscribe
(
auth
=>
this
.
authorised
=
auth
);
});
constructor
(
public
dialog
:
MatDialog
,
private
tesService
:
TesService
)
{
}
ngOnInit
()
{
console
.
log
(
'
initialising launcher compoenent
'
);
this
.
strudelapps
=
[];
setTimeout
(
()
=>
{
this
.
tesService
.
identities
.
subscribe
(
identities
=>
this
.
updateIdentities
(
identities
));
});
console
.
log
(
'
initialising launcher compoenent complete
'
);
configureApp
()
{
console
.
log
(
'
configuring app for
'
,
this
.
app
.
name
);
this
.
openDialog
(
'
If the application takes any parameters, this will open a new window where you can configure them
'
)
}
configureResources
()
{
this
.
openDialog
(
'
This will open a new window to configure resource reqests
'
)
}
updateIdentities
(
identities
)
{
console
.
log
(
'
updateIdentities in launcher
'
);
this
.
identities
=
identities
;
console
.
log
(
'
updateIdentities in launcher complete
'
);
submitApp
()
{
console
.
log
(
'
submitting app for
'
,
this
.
app
.
name
);
this
.
identity
=
this
.
tesService
.
identities
[
0
];
this
.
tesService
.
submit
(
this
.
app
,
this
.
identity
);
// this.openDialog('This is where we should start the app');
}
appselect
(
a
:
any
)
{
console
.
log
(
'
appselect
'
)
this
.
app
=
a
;
}
login
()
{
let
dialogRef
=
this
.
dialog
.
open
(
LogindialogComponent
,
{
width
:
'
250px
'
,
height
:
'
400px
'
,
});
return
;
}
logout
()
{
let
dialogRef
=
this
.
dialog
.
open
(
LogoutdialogComponent
,
{
width
:
'
250px
'
,
height
:
'
400px
'
,
});
// this.tesService.logout();
// return;
}
loadStrudelapps
()
{
this
.
strudelapps
=
this
.
strudelappsService
.
getStrudelapps
()
}
openDialog
(
msg
:
string
):
void
{
let
dialogRef
=
this
.
dialog
.
open
(
DialogPlaceholder
,
{
width
:
'
250px
'
,
height
:
'
400px
'
,
data
:
{
'
msg
'
:
msg
}
});
dialogRef
.
afterClosed
().
subscribe
(
result
=>
{
console
.
log
(
'
The dialog was closed
'
);
});
selectId
(
event
:
any
)
{
console
.
log
(
'
in selectID
'
);
if
(
!
(
event
.
value
===
undefined
)
&&
event
.
value
instanceof
(
Identity
))
{
this
.
identity
=
event
.
value
;
this
.
strudelapps
=
this
.
identity
.
site
.
appCatalog
;
}
console
.
log
(
'
selectID complete
'
);
}
configureResources
()
{
let
configwindow
=
window
.
open
(
this
.
identity
.
site
.
url
+
'
configure/
'
+
this
.
app
.
name
);
}
}
submitApp
()
{
this
.
tesService
.
getconfig
(
this
.
app
,
this
.
identity
)
.
subscribe
(
resp
=>
{
console
.
log
(
resp
);
this
.
tesService
.
submit
(
this
.
app
,
this
.
identity
,
resp
)});
}
@
Component
({
selector
:
'
dialog-placeholder
'
,
templateUrl
:
'
dialog-placeholder.html
'
,
})
export
class
DialogPlaceholder
{
constructor
(
public
dialogRef
:
MatDialogRef
<
DialogPlaceholder
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
)
{
}
onNoClick
():
void
{
this
.
dialogRef
.
close
();
}
// openDialog(msg: string ): void {
// let dialogRef = this.dialog.open(LoginDialog, {
// width: '250px',
// height: '400px',
// data: { 'msg': msg }
// });
//
// dialogRef.afterClosed().subscribe(result => {
// console.log('The dialog was closed');
// });
// }
}
// @Component({
// selector: 'dialog-placeholder',
// templateUrl: 'dialog-placeholder.html',
// })
// export class LoginDialog {
//
// constructor(
// public dialogRef: MatDialogRef<LoginDialog>,
// @Inject(MAT_DIALOG_DATA) public data: any) { }
//
// onNoClick(): void {
// this.dialogRef.close();
// }
//
// }
src/app/logindialog/logindialog.component.css
0 → 100644
View file @
d1d506ef
src/app/logindialog/logindialog.component.html
0 → 100644
View file @
d1d506ef
<button
mat-button
(click)=
"onLogin()"
>
Login to M3
</button>
<button
mat-button
(click)=
"onCancel()"
>
Cancel
</button>
src/app/logindialog/logindialog.component.spec.ts
0 → 100644
View file @
d1d506ef
import
{
async
,
ComponentFixture
,
TestBed
}
from
'
@angular/core/testing
'
;
import
{
LogindialogComponent
}
from
'
./logindialog.component
'
;
describe
(
'
LogindialogComponent
'
,
()
=>
{
let
component
:
LogindialogComponent
;
let
fixture
:
ComponentFixture
<
LogindialogComponent
>
;
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
declarations
:
[
LogindialogComponent
]
})
.
compileComponents
();
}));
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
LogindialogComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'
should create
'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/logindialog/logindialog.component.ts
0 → 100644
View file @
d1d506ef
import
{
Component
,
OnInit
,
Inject
}
from
'
@angular/core
'
;
import
{
MatDialog
,
MatDialogRef
,
MAT_DIALOG_DATA
,
MatDialogModule
}
from
'
@angular/material
'
;
import
{
TesService
}
from
'
../tes.service
'
;
@
Component
({
selector
:
'
app-logindialog
'
,
templateUrl
:
'
./logindialog.component.html
'
,
styleUrls
:
[
'
./logindialog.component.css
'
]
})
export
class
LogindialogComponent
implements
OnInit
{
constructor
(
public
dialogRef
:
MatDialogRef
<
LogindialogComponent
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
,
private
tesService
:
TesService
)
{
}
ngOnInit
()
{
}
onLogin
()
{
this
.
tesService
.
login
();
}
onCancel
()
{
this
.
dialogRef
.
close
();
}
}
src/app/logoutdialog/logoutdialog.component.css
0 → 100644
View file @
d1d506ef
src/app/logoutdialog/logoutdialog.component.html
0 → 100644
View file @
d1d506ef
<button
mat-button
(click)=
"onLogout()"
>
Logout of everything
</button>
<button
mat-button
(click)=
"onCancel()"
>
Cancel
</button>
src/app/logoutdialog/logoutdialog.component.spec.ts
0 → 100644
View file @
d1d506ef
import
{
async
,
ComponentFixture
,
TestBed
}
from
'
@angular/core/testing
'
;
import
{
LogoutdialogComponent
}
from
'
./logoutdialog.component
'
;
describe
(
'
LogoutdialogComponent
'
,
()
=>
{
let
component
:
LogoutdialogComponent
;
let
fixture
:
ComponentFixture
<
LogoutdialogComponent
>
;
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
declarations
:
[
LogoutdialogComponent
]
})
.
compileComponents
();
}));
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
LogoutdialogComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'
should create
'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/logoutdialog/logoutdialog.component.ts
0 → 100644
View file @
d1d506ef
import
{
Component
,
OnInit
,
Inject
}
from
'
@angular/core
'
;
import
{
TesService
}
from
'
../tes.service
'
;
import
{
MatDialog
,
MatDialogRef
,
MAT_DIALOG_DATA
,
MatDialogModule
}
from
'
@angular/material
'
;
@
Component
({
selector
:
'
app-logoutdialog
'
,
templateUrl
:
'
./logoutdialog.component.html
'
,
styleUrls
:
[
'
./logoutdialog.component.css
'
]
})
export
class
LogoutdialogComponent
implements
OnInit
{
constructor
(
public
dialogRef
:
MatDialogRef
<
LogoutdialogComponent
>
,
@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
any
,
private
tesService
:
TesService
)
{
}
ngOnInit
()
{
}
onLogout
()
{
this
.
tesService
.
logout
();
this
.
dialogRef
.
close
();
}
onCancel
()
{
this
.
dialogRef
.
close
();
}
}
src/app/mock-compute-site.ts
View file @
d1d506ef
import
{
Computesite
}
from
'
./computesite
'
;
import
{
STRUDELAPPS
}
from
'
./mock-strudel-app
'
;
export
const
COMPUTESITES
:
Computesite
[]
=
[
{
url
:
'
http://
localhost:8080/
config
'
,
name
:
'
M3
'
,
{
url
:
'
http
s
://
vm-118-138-240-255.erc.monash.edu.au/m3site
config
/
'
,
name
:
'
M3
'
,
host
:
'
m3.massive.org.au
'
,
cafingerprint
:
'
RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I
'
},
cafingerprint
:
'
RSA SHA256:cmDxHrZQSPlBMUUcI/BWmruXho1XOzfXPDHSqVTwV2I
'
,
appCatalog
:
STRUDELAPPS
}
];
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment