Skip to content

Commit f9cd1bd

Browse files
committed
feat(vnc): enables VNC for debugging
1 parent 9a4cd14 commit f9cd1bd

File tree

5 files changed

+51
-43
lines changed

5 files changed

+51
-43
lines changed

src/api/process-manager.ts

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export function stopJob(jobId: number): Promise<void> {
221221
});
222222
}
223223

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

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

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

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

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

364-
export function restartJobWithSSH(jobId: number): Promise<void> {
365-
return getJobProcesses()
366-
.then(procs => {
367-
const jobProcess = procs.find(job => job.job_id === jobId);
368-
if (jobProcess) {
369-
let jobData;
370-
return dbJob.resetJob(jobId)
371-
.then(job => {
372-
jobData = job;
373-
jobEvents.next({
374-
type: 'process',
375-
build_id: job.builds_id,
376-
job_id: job.id,
377-
data: 'jobRestarted'
378-
});
379-
})
380-
.then(() => queueJob(jobData.builds_id, jobData.id, true));
381-
} else {
382-
return dbJob.getJob(jobId).then(job => {
383-
jobEvents.next({
384-
type: 'process',
385-
build_id: job.builds_id,
386-
job_id: job.id,
387-
data: 'jobRestarted'
388-
});
389-
390-
return queueJob(job.builds_id, job.id, true);
391-
});
392-
}
364+
export function restartJobWithSshAndVnc(jobId: number): Promise<void> {
365+
let jobData = null;
366+
return stopJob(jobId)
367+
.then(() => dbJob.resetJob(jobId))
368+
.then(job => jobData = job)
369+
.then(() => queueJob(jobData.builds_id, jobId, true))
370+
.then(() => {
371+
jobEvents.next({
372+
type: 'process',
373+
build_id: jobData.builds_id,
374+
job_id: jobData.id,
375+
data: 'jobRestarted'
376+
});
393377
});
394378
}
395379

src/api/process.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface ProcessOutput {
2828
}
2929

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

41+
let debug: Observable<any> = Observable.empty();
42+
if (sshAndVnc) {
43+
debug = Observable.concat(...[
44+
executeInContainer(name, 'sudo /etc/init.d/ssh start'),
45+
getContainerExposedPort(name, 22),
46+
executeInContainer(name, 'export DISPLAY=:99 && sudo /etc/init.d/xvfb start && ' +
47+
'sleep 3 && sudo /etc/init.d/openbox start'),
48+
executeInContainer(name, 'export DISPLAY=:99 && ' +
49+
'x11vnc -xkb -noxrecord -noxfixes -noxdamage -display :99 ' +
50+
'-forever -bg -rfbauth /etc/x11vnc.pass -rfbport 5900'),
51+
getContainerExposedPort(name, 5900)
52+
]);
53+
}
54+
4155
const sub = startContainer(name, image, vars)
42-
.concat(ssh ? executeInContainer(name, 'sudo /etc/init.d/ssh start') : Observable.empty())
43-
.concat(ssh ? getContainerExposedPort(name, 22) : Observable.empty())
56+
.concat(debug)
4457
.concat(...commands.map(command => executeInContainer(name, command)))
4558
.subscribe((event: ProcessOutput) => {
4659
observer.next(event);
@@ -166,7 +179,9 @@ function getContainerExposedPort(name: string, port: number): Observable<Process
166179
port
167180
]);
168181

169-
process.on('data', data => observer.next({ type: 'exposedPort', data: data.split(':')[1] }));
182+
process.on('data', data => {
183+
return observer.next({ type: 'exposedPort', data: port + ':' + data.split(':')[1] });
184+
});
170185
process.on('exit', () => observer.complete());
171186
});
172187
}

src/api/socket.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
findDockerImageBuildJob,
1111
jobEvents,
1212
restartJob,
13-
restartJobWithSSH,
13+
restartJobWithSshAndVnc,
1414
stopJob,
1515
restartBuild,
1616
stopBuild,
@@ -107,8 +107,8 @@ export class SocketServer {
107107
conn.next({ type: 'jobRestarted', data: event.data.jobId });
108108
});
109109
break;
110-
case 'restartJobWithSSH':
111-
restartJobWithSSH(parseInt(event.data.jobId, 10))
110+
case 'restartJobWithSshAndVnc':
111+
restartJobWithSshAndVnc(parseInt(event.data.jobId, 10))
112112
.then(() => {
113113
conn.next({ type: 'jobRestarted', data: event.data.jobId });
114114
});

src/app/components/app-job/app-job.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,14 @@ <h2>{{ job?.build?.message }}</h2>
9090
</div>
9191
</div>
9292
</div>
93-
<div class="column is-12" *ngIf="sshd">
93+
<div class="column is-12" *ngIf="sshd && vnc">
9494
<div class="ssh-container">
9595
<span class="icon">
9696
<img src="images/icons/ssh.svg">
9797
</span>
9898
<span>SSH Daemon is enabled in this container.</span>
9999
<code>ssh {{ sshd.split(':')[0] }} -p {{ sshd.split(':')[1] }} -l abstruse</code>
100+
<code>VNC: {{ vnc.split(':')[0] }} VNC Port: {{ vnc.split(':')[1] }}</code>
100101
<code>password: abstruse</code>
101102
</div>
102103
</div>

src/app/components/app-job/app-job.component.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class AppJobComponent implements OnInit, OnDestroy {
2727
previousRuntime: number;
2828
processing: boolean;
2929
sshd: string;
30+
vnc: string;
3031
expectedProgress: number;
3132

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

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

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

135142
stopJob(e: MouseEvent): void {
136143
e.preventDefault();
137144
e.stopPropagation();
138145
this.processing = true;
139146
this.sshd = null;
147+
this.vnc = null;
140148
this.socketService.emit({ type: 'stopJob', data: { jobId: this.id } });
141149
}
142150

0 commit comments

Comments
 (0)