Add login scripts support (#402)

* Support login scripts. Fix #344

* nowrap

* Follow the general Terminus style
This commit is contained in:
Domain 2018-08-29 17:15:00 +08:00 committed by Eugene
parent 4b1ba7863f
commit 5b76947d70
5 changed files with 183 additions and 41 deletions

View File

@ -1,5 +1,10 @@
import { BaseSession } from 'terminus-terminal'
export interface LoginScript {
expect?: string
send: string
}
export interface SSHConnection {
name?: string
host: string
@ -7,18 +12,43 @@ export interface SSHConnection {
user: string
password?: string
privateKey?: string
scripts?: LoginScript[]
}
export class SSHSession extends BaseSession {
constructor (private shell: any) {
scripts?: LoginScript[]
constructor (private shell: any, conn: SSHConnection) {
super()
this.scripts = conn.scripts.slice(0);
}
start () {
this.open = true
this.shell.on('data', data => {
this.emitOutput(data.toString())
let dataString = data.toString()
this.emitOutput(dataString)
if (this.scripts && this.scripts.length > 0) {
let found = false
for (let i = 0; i < this.scripts.length; i++) {
if (dataString.indexOf(this.scripts[i].expect) >= 0) {
console.log("Executing: " + this.scripts[i].send)
this.shell.write(this.scripts[i].send + "\n")
this.scripts.splice(i, 1)
i--
found = true
}
else {
break;
}
}
if (found) {
this.executeScripts()
}
}
})
this.shell.on('end', () => {
@ -26,6 +56,24 @@ export class SSHSession extends BaseSession {
this.destroy()
}
})
this.executeScripts()
}
executeScripts () {
if (this.scripts && this.scripts.length > 0) {
for (let i = 0; i < this.scripts.length; i++) {
if (!this.scripts[i].expect) {
console.log("Executing: " + this.scripts[i].send)
this.shell.write(this.scripts[i].send + "\n")
this.scripts.splice(i, 1)
i--
}
else {
break;
}
}
}
}
resize (columns, rows) {

View File

@ -1,45 +1,101 @@
.modal-body
.form-group
label Name
input.form-control(
type='text',
[(ngModel)]='connection.name',
)
ngb-tabset(type='pills', [activeId]='basic')
ngb-tab(id='basic')
ng-template(ngbTabTitle)
| Basic Setting
ng-template(ngbTabContent)
h4 Basic Setting
.form-group
label Name
input.form-control(
type='text',
[(ngModel)]='connection.name',
)
.form-group
label Host
input.form-control(
type='text',
[(ngModel)]='connection.host',
)
.form-group
label Host
input.form-control(
type='text',
[(ngModel)]='connection.host',
)
.form-group
label Port
input.form-control(
type='number',
placeholder='22',
[(ngModel)]='connection.port',
)
.form-group
label Port
input.form-control(
type='number',
placeholder='22',
[(ngModel)]='connection.port',
)
.form-group
label Username
input.form-control(
type='text',
[(ngModel)]='connection.user',
)
.form-group
label Username
input.form-control(
type='text',
[(ngModel)]='connection.user',
)
.form-group
label Private key
.input-group
input.form-control(
type='text',
placeholder='Key file path',
[(ngModel)]='connection.privateKey'
)
.input-group-btn
button.btn.btn-secondary((click)='selectPrivateKey()')
i.fa.fa-folder-open
.form-group
label Private key
.input-group
input.form-control(
type='text',
placeholder='Key file path',
[(ngModel)]='connection.privateKey'
)
.input-group-btn
button.btn.btn-secondary((click)='selectPrivateKey()')
i.fa.fa-folder-open
ngb-tab(id='scripts')
ng-template(ngbTabTitle)
| Login Scripts
ng-template(ngbTabContent)
h4 Login Scripts
.list-group
table
tr
th String to wait
th String to be sent
th Actions
tr(*ngFor='let script of connection.scripts')
td
input.form-control(
type='text',
value='{{script.expect}}',
)
td
input.form-control(
type='text',
value='{{script.send}}',
)
td
.input-group.flex-nowrap
button.btn.btn-outline-info.ml-0((click)='up(script)')
i.fa.fa-arrow-up
button.btn.btn-outline-info.ml-0((click)='down(script)')
i.fa.fa-arrow-down
button.btn.btn-outline-danger.ml-0((click)='delete(script)')
i.fa.fa-trash-o
tr
td
input.form-control(
type='text',
placeholder='Enter a string to wait',
[(ngModel)]='newScript.expect'
)
td
input.form-control(
type='text',
placeholder='Enter a string to be sent',
[(ngModel)]='newScript.send'
)
td
.input-group.flex-nowrap
button.btn.btn-outline-info.ml-0((click)='add()')
i.fa.fa-save
button.btn.btn-outline-danger.ml-0((click)='clear()')
i.fa.fa-trash-o
.modal-footer
button.btn.btn-outline-primary((click)='save()') Save
button.btn.btn-outline-danger((click)='cancel()') Cancel

View File

@ -1,19 +1,22 @@
import { Component } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { ElectronService, HostAppService } from 'terminus-core'
import { SSHConnection } from '../api'
import { SSHConnection, LoginScript } from '../api'
@Component({
template: require('./editConnectionModal.component.pug'),
})
export class EditConnectionModalComponent {
connection: SSHConnection
newScript: LoginScript
constructor (
private modalInstance: NgbActiveModal,
private electron: ElectronService,
private hostApp: HostAppService,
) { }
) {
this.newScript = { expect: "", send: ""}
}
selectPrivateKey () {
let path = this.electron.dialog.showOpenDialog(
@ -34,4 +37,38 @@ export class EditConnectionModalComponent {
cancel () {
this.modalInstance.dismiss()
}
up (script: LoginScript) {
let index = this.connection.scripts.indexOf(script)
if (index > 0) {
this.connection.scripts.splice(index, 1);
this.connection.scripts.splice(index - 1, 0, script);
}
}
down (script: LoginScript) {
let index = this.connection.scripts.indexOf(script)
if (index >= 0 && index < this.connection.scripts.length - 1) {
this.connection.scripts.splice(index, 1);
this.connection.scripts.splice(index + 1, 0, script);
}
}
delete (script: LoginScript) {
if (confirm(`Delete?`)) {
this.connection.scripts = this.connection.scripts.filter(x => x !== script)
}
}
add () {
if (!this.connection.scripts)
this.connection.scripts = []
this.connection.scripts.push(Object.assign({}, this.newScript))
this.clear();
}
clear () {
this.newScript.expect = ""
this.newScript.send = ""
}
}

View File

@ -24,6 +24,7 @@ export class SSHSettingsTabComponent {
port: 22,
user: 'root',
}
let modal = this.ngbModal.open(EditConnectionModalComponent)
modal.componentInstance.connection = connection
modal.result.then(result => {

View File

@ -148,7 +148,7 @@ export class SSHService {
})
})
let session = new SSHSession(shell)
let session = new SSHSession(shell, connection)
return this.zone.run(() => this.app.openNewTab(
TerminalTabComponent,