Permalink
Browse files

feat(vnc): enables VNC for debugging

  • Loading branch information...
jkuri committed Aug 7, 2017
1 parent 9a4cd14 commit f9cd1bd6a4d01b5966d53b4aa474f9d215774031
@@ -221,7 +221,7 @@ export function stopJob(jobId: number): Promise<void> {
});
}

function queueJob(buildId: number, jobId: number, ssh = false): Promise<void> {
function queueJob(buildId: number, jobId: number, sshAndVnc = false): Promise<void> {
let commands: string[] = null;
let processes: JobProcess[] = null;

@@ -245,7 +245,7 @@ function queueJob(buildId: number, jobId: number, ssh = false): Promise<void> {
build_id: buildId,
job_id: jobId,
status: 'queued',
job: prepareJob(buildId, jobId, commands, ssh),
job: prepareJob(buildId, jobId, commands, sshAndVnc),
log: []
};

@@ -255,7 +255,7 @@ function queueJob(buildId: number, jobId: number, ssh = false): Promise<void> {
});
}

function prepareJob(buildId: number, jobId: number, cmds: any, ssh = false):
function prepareJob(buildId: number, jobId: number, cmds: any, sshAndVnc = false):
Observable<JobMessage> {
return new Observable(observer => {
getJobProcesses().then(processes => {
@@ -264,7 +264,7 @@ function prepareJob(buildId: number, jobId: number, cmds: any, ssh = false):
jobProcesses.next(processes);
const process = processes[index];

startBuildProcess(buildId, jobId, cmds, 'abstruse', ssh).subscribe(event => {
startBuildProcess(buildId, jobId, cmds, 'abstruse', sshAndVnc).subscribe(event => {
const msg: JobMessage = {
build_id: buildId,
job_id: jobId,
@@ -361,35 +361,19 @@ export function restartJob(jobId: number): Promise<void> {
});
}

export function restartJobWithSSH(jobId: number): Promise<void> {
return getJobProcesses()
.then(procs => {
const jobProcess = procs.find(job => job.job_id === jobId);
if (jobProcess) {
let jobData;
return dbJob.resetJob(jobId)
.then(job => {
jobData = job;
jobEvents.next({
type: 'process',
build_id: job.builds_id,
job_id: job.id,
data: 'jobRestarted'
});
})
.then(() => queueJob(jobData.builds_id, jobData.id, true));
} else {
return dbJob.getJob(jobId).then(job => {
jobEvents.next({
type: 'process',
build_id: job.builds_id,
job_id: job.id,
data: 'jobRestarted'
});

return queueJob(job.builds_id, job.id, true);
});
}
export function restartJobWithSshAndVnc(jobId: number): Promise<void> {
let jobData = null;
return stopJob(jobId)
.then(() => dbJob.resetJob(jobId))
.then(job => jobData = job)
.then(() => queueJob(jobData.builds_id, jobId, true))
.then(() => {
jobEvents.next({
type: 'process',
build_id: jobData.builds_id,
job_id: jobData.id,
data: 'jobRestarted'
});
});
}

@@ -28,7 +28,7 @@ export interface ProcessOutput {
}

export function startBuildProcess(buildId: number, jobId: number,
commands: string[], image: string, ssh = false): Observable<ProcessOutput> {
commands: string[], image: string, sshAndVnc = false): Observable<ProcessOutput> {
return new Observable(observer => {
const name = 'abstruse_' + buildId + '_' + jobId;
const vars = commands.filter(cmd => cmd.startsWith('export'))
@@ -38,9 +38,22 @@ export function startBuildProcess(buildId: number, jobId: number,
}, []);
commands = commands.filter(cmd => !cmd.startsWith('export'));

let debug: Observable<any> = Observable.empty();
if (sshAndVnc) {
debug = Observable.concat(...[
executeInContainer(name, 'sudo /etc/init.d/ssh start'),
getContainerExposedPort(name, 22),
executeInContainer(name, 'export DISPLAY=:99 && sudo /etc/init.d/xvfb start && ' +
'sleep 3 && sudo /etc/init.d/openbox start'),
executeInContainer(name, 'export DISPLAY=:99 && ' +
'x11vnc -xkb -noxrecord -noxfixes -noxdamage -display :99 ' +
'-forever -bg -rfbauth /etc/x11vnc.pass -rfbport 5900'),
getContainerExposedPort(name, 5900)
]);
}

const sub = startContainer(name, image, vars)
.concat(ssh ? executeInContainer(name, 'sudo /etc/init.d/ssh start') : Observable.empty())
.concat(ssh ? getContainerExposedPort(name, 22) : Observable.empty())
.concat(debug)
.concat(...commands.map(command => executeInContainer(name, command)))
.subscribe((event: ProcessOutput) => {
observer.next(event);
@@ -166,7 +179,9 @@ function getContainerExposedPort(name: string, port: number): Observable<Process
port
]);

process.on('data', data => observer.next({ type: 'exposedPort', data: data.split(':')[1] }));
process.on('data', data => {
return observer.next({ type: 'exposedPort', data: port + ':' + data.split(':')[1] });
});
process.on('exit', () => observer.complete());
});
}
@@ -10,7 +10,7 @@ import {
findDockerImageBuildJob,
jobEvents,
restartJob,
restartJobWithSSH,
restartJobWithSshAndVnc,
stopJob,
restartBuild,
stopBuild,
@@ -107,8 +107,8 @@ export class SocketServer {
conn.next({ type: 'jobRestarted', data: event.data.jobId });
});
break;
case 'restartJobWithSSH':
restartJobWithSSH(parseInt(event.data.jobId, 10))
case 'restartJobWithSshAndVnc':
restartJobWithSshAndVnc(parseInt(event.data.jobId, 10))
.then(() => {
conn.next({ type: 'jobRestarted', data: event.data.jobId });
});
@@ -90,13 +90,14 @@ <h2>{{ job?.build?.message }}</h2>
</div>
</div>
</div>
<div class="column is-12" *ngIf="sshd">
<div class="column is-12" *ngIf="sshd && vnc">
<div class="ssh-container">
<span class="icon">
<img src="images/icons/ssh.svg">
</span>
<span>SSH Daemon is enabled in this container.</span>
<code>ssh {{ sshd.split(':')[0] }} -p {{ sshd.split(':')[1] }} -l abstruse</code>
<code>VNC: {{ vnc.split(':')[0] }} VNC Port: {{ vnc.split(':')[1] }}</code>
<code>password: abstruse</code>
</div>
</div>
@@ -27,6 +27,7 @@ export class AppJobComponent implements OnInit, OnDestroy {
previousRuntime: number;
processing: boolean;
sshd: string;
vnc: string;
expectedProgress: number;

constructor(
@@ -52,7 +53,11 @@ export class AppJobComponent implements OnInit, OnDestroy {
} else if (event.type === 'jobRestarted' && event.data === this.id) {
this.processing = false;
} else if (event.type === 'exposedPort') {
this.sshd = `${document.location.hostname}:${event.data}`;
if (parseInt(event.data.split(':')[0], 10) === 22) {
this.sshd = `${document.location.hostname}:${event.data.split(':')[1]}`;
} else if (parseInt(event.data.split(':')[0], 10) === 5900) {
this.vnc = `${document.location.hostname}:${event.data.split(':')[1]}`;
}
}
});

@@ -120,6 +125,7 @@ export class AppJobComponent implements OnInit, OnDestroy {
this.terminalInput = { clear: true };
this.processing = true;
this.sshd = null;
this.vnc = null;
this.socketService.emit({ type: 'restartJob', data: { jobId: this.id } });
}

@@ -129,14 +135,16 @@ export class AppJobComponent implements OnInit, OnDestroy {
this.terminalInput = { clear: true };
this.processing = true;
this.sshd = null;
this.socketService.emit({ type: 'restartJobWithSSH', data: { jobId: this.id } });
this.vnc = null;
this.socketService.emit({ type: 'restartJobWithSshAndVnc', data: { jobId: this.id } });
}

stopJob(e: MouseEvent): void {
e.preventDefault();
e.stopPropagation();
this.processing = true;
this.sshd = null;
this.vnc = null;
this.socketService.emit({ type: 'stopJob', data: { jobId: this.id } });
}

0 comments on commit f9cd1bd

Please sign in to comment.