Basic OS Console executor

This commit is contained in:
ziajka 2019-03-05 14:26:09 +01:00
parent 2b0bb19f88
commit 0c2fff6ac1
9 changed files with 124 additions and 2 deletions

33
console-executor.js Normal file
View File

@ -0,0 +1,33 @@
const { spawn } = require('child_process');
exports.openConsole = async (consoleRequest) => {
const genericConsoleCommand = 'xfce4-terminal --tab -T "%d" -e "telnet %h %p"';
const command = prepareCommand(genericConsoleCommand, consoleRequest);
console.log(`Starting console with command: '${command}'`);
let consoleProcess = spawn(command, [], {
shell :true
});
consoleProcess.stdout.on('data', (data) => {
console.log(`Console is producing: ${data.toString()}`);
});
}
function prepareCommand(consoleCommand, consoleRequest) {
const mapping = {
h: consoleRequest.host,
p: consoleRequest.port,
d: consoleRequest.name,
i: consoleRequest.project_id,
n: consoleRequest.node_id,
c: consoleRequest.server_url
};
for(var key in mapping) {
const regExp = new RegExp(`%${key}`, 'g');
consoleCommand = consoleCommand.replace(regExp, mapping[key]);
}
return consoleCommand;
}

View File

@ -15,6 +15,7 @@ files:
- sentry.js
- installed-software.js
- local-server.js
- console-executor.js
- package.json
extraFiles:

View File

@ -168,6 +168,7 @@ import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapsho
import { DateFilter } from './filters/dateFilter.pipe';
import { NameFilter } from './filters/nameFilter.pipe';
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component';
import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component';
if (environment.production) {
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
@ -273,7 +274,8 @@ if (environment.production) {
DateFilter,
NameFilter,
ListOfSnapshotsComponent,
CustomAdaptersComponent
CustomAdaptersComponent,
ConsoleDeviceActionComponent
],
imports: [
BrowserModule,

View File

@ -0,0 +1,4 @@
<button mat-menu-item (click)="console()">
<mat-icon>web_asset</mat-icon>
<span>Console</span>
</button>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ConsoleDeviceActionComponent } from './console-device-action.component';
describe('ConsoleDeviceActionComponent', () => {
let component: ConsoleDeviceActionComponent;
let fixture: ComponentFixture<ConsoleDeviceActionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ConsoleDeviceActionComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ConsoleDeviceActionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,43 @@
import { Component, OnInit, Input } from '@angular/core';
import { Node } from '../../../../../cartography/models/node';
import { Server } from '../../../../../models/server';
import { ElectronService } from 'ngx-electron';
import { Project } from '../../../../../models/project';
import { ServerService } from '../../../../../services/server.service';
@Component({
selector: 'app-console-device-action',
templateUrl: './console-device-action.component.html'
})
export class ConsoleDeviceActionComponent implements OnInit {
@Input() server: Server;
@Input() project: Project;
@Input() nodes: Node[];
constructor(
private electronService: ElectronService,
private serverService: ServerService
) { }
ngOnInit() {
}
async console() {
for(var node of this.nodes) {
const consoleRequest = {
type: node.console_type,
host: node.console_host,
port: node.console,
name: node.name,
project_id: this.project.project_id,
node_id: node.node_id,
server_url: this.serverService.getServerUrl(this.server)
};
await this.openConsole(consoleRequest);
}
}
async openConsole(request) {
return await this.electronService.remote.require('./console-executor.js').openConsole(request);
}
}

View File

@ -3,6 +3,12 @@
<mat-menu #contextMenu="matMenu" class="context-menu-items">
<app-start-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-start-node-action>
<app-stop-node-action *ngIf="nodes.length" [server]="server" [nodes]="nodes"></app-stop-node-action>
<app-console-device-action
*ngIf="!projectService.isReadOnly(project) && nodes.length && isElectronApp"
[project]="project"
[server]="server"
[nodes]="nodes"
></app-console-device-action>
<app-edit-style-action *ngIf="drawings.length===1 && !hasTextCapabilities"
[server]="server"
[project]="project"

View File

@ -9,6 +9,7 @@ import { Drawing } from '../../../cartography/models/drawing';
import { TextElement } from '../../../cartography/models/drawings/text-element';
import { Label } from '../../../cartography/models/label';
import { Link } from '../../../models/link';
import { ElectronService } from 'ngx-electron';
@Component({
@ -30,16 +31,19 @@ export class ContextMenuComponent implements OnInit {
labels: Label[] = [];
links: Link[] = [];
hasTextCapabilities: boolean = false;
hasTextCapabilities = false;
isElectronApp = false;
constructor(
private sanitizer: DomSanitizer,
private changeDetector: ChangeDetectorRef,
private electronService: ElectronService,
public projectService: ProjectService
) {}
ngOnInit() {
this.setPosition(0, 0);
this.isElectronApp = this.electronService.isElectronApp;
}
public setPosition(top: number, left: number) {

View File

@ -55,6 +55,10 @@ export class ServerService {
return this.onReady(() => this.indexedDbService.get().delete(this.tablename, server.id));
}
public getServerUrl(server: Server) {
return `http://${server.host}:${server.port}/`;
}
public getLocalServer(host: string, port: number) {
const promise = new Promise((resolve, reject) => {
this.findAll().then((servers: Server[]) => {