Skip to content

Commit 788517f

Browse files
committed
fix(job): fix job socket events
1 parent 5dd7698 commit 788517f

File tree

5 files changed

+94
-45
lines changed

5 files changed

+94
-45
lines changed

src/api/process.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ export function startBuildProcess(buildId: number, jobId: number,
3939
commands = commands.filter(cmd => !cmd.startsWith('export'));
4040

4141
startContainer(name, image, vars)
42-
.concat(ssh ? executeInContainer(name, 'sudo /etc/init.d/ssh start') : null)
43-
.concat(ssh ? getContainerExposedPort(name, 22) : null)
42+
.concat(ssh ? executeInContainer(name, 'sudo /etc/init.d/ssh start') : Observable.empty())
43+
.concat(ssh ? getContainerExposedPort(name, 22) : Observable.empty())
4444
.concat(...commands.map(command => executeInContainer(name, command)))
4545
.subscribe((event: ProcessOutput) => {
4646
observer.next(event);
@@ -57,9 +57,14 @@ export function startBuildProcess(buildId: number, jobId: number,
5757

5858
function executeInContainer(name: string, command: string): Observable<ProcessOutput> {
5959
return new Observable(observer => {
60-
const start = nodePty.spawn('docker', ['start', name]);
60+
const start = nodePty.spawn('docker', ['start', name], { name: 'xterm-color' });
61+
62+
start.on('exit', startCode => {
63+
if (startCode !== 0) {
64+
observer.error(bold(red('Container errored with exit code ' + startCode)));
65+
}
66+
6167

62-
start.on('exit', () => {
6368
let exitCode = 255;
6469
let executed = false;
6570
let attach = null;
@@ -81,6 +86,7 @@ function executeInContainer(name: string, command: string): Observable<ProcessOu
8186
exitCode = 0;
8287
attach.write(detachKey ? detachKey : 'exit $?\r');
8388
} else if (data.includes('EXECNOK')) {
89+
observer.error(red(`Last executed command returned error.`));
8490
attach.write(detachKey ? detachKey : 'exit $?\r');
8591
} else if (!data.includes(command) && !data.includes('exit $?') &&
8692
!data.includes('logout') && !data.includes('read escape sequence')) {
Lines changed: 7 additions & 0 deletions
Loading

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
<div class="build-top-container" [ngClass]="{ green: job?.status === 'success', yellow: job?.status === 'running', red: job?.status === 'failed' }">
1414
<div class="build-top-content">
1515
<div class="columns is-multiline">
16-
<div class="column is-2">
16+
<div class="column is-7">
1717
<h1 class="bold">
18-
<span><a [routerLink]="['/repo', job?.build.repository.id]">{{ job?.build.head_full_name }}</a></span>
18+
<span><a [routerLink]="['/repo', job?.build?.repository?.id]">{{ job?.build?.head_full_name }}</a></span>
1919
<span class="build-icon">
2020
<img src="images/icons/clock.svg" *ngIf="job?.status === 'queued'">
2121
<img src="images/icons/flickr.svg" *ngIf="job?.status === 'running'">
@@ -24,9 +24,6 @@ <h1 class="bold">
2424
</span>
2525
</h1>
2626
</div>
27-
<div class="column is-5">
28-
<code *ngIf="sshd" class="ssh">ssh {{ sshd.split(':')[0] }} -p {{ sshd.split(':')[1] }} -l abstruse</code>
29-
</div>
3027
<div class="column is-5 justify-end right-buttons-top">
3128
<button class="button is-fullwidth" name="btn-restart-ssh" type="button" (click)="restartJobWithSSH($event)" [disabled]="processing">
3229
<div class="centered">
@@ -57,23 +54,23 @@ <h1 class="bold">
5754
<hr/>
5855

5956
<div class="column is-3">
60-
<h2>{{ job?.build.message }}</h2>
57+
<h2>{{ job?.build?.message }}</h2>
6158
</div>
6259
<div class="column is-3">
6360
<p>
6461
<span class="icon">
6562
<img src="images/icons/git-commit.svg">
6663
</span>
67-
<span *ngIf="job?.build.head_sha">{{ job?.build.head_sha.slice(0, 7) }}</span>
68-
<span *ngIf="!job?.build.head_sha">{{ job?.build.sha.slice(0, 7) }}</span>
64+
<span *ngIf="job?.build?.head_sha">{{ job?.build?.head_sha.slice(0, 7) }}</span>
65+
<span *ngIf="!job?.build?.head_sha">{{ job?.build?.sha.slice(0, 7) }}</span>
6966
</p>
7067
</div>
7168
<div class="column is-4">
7269
<p>
7370
<span class="icon">
74-
<img [src]="job?.build.head_user_avatar_url" class="avatar-img">
71+
<img [src]="job?.build?.head_user_avatar_url" class="avatar-img">
7572
</span>
76-
<span>{{ job?.build.author }} commited {{ timeWords }} ago</span>
73+
<span>{{ job?.build?.author }} commited {{ timeWords }} ago</span>
7774
</p>
7875
</div>
7976
<div class="column is-2">
@@ -88,6 +85,16 @@ <h2>{{ job?.build.message }}</h2>
8885
</div>
8986
</div>
9087
</div>
88+
<div class="column is-12" *ngIf="sshd">
89+
<div class="ssh-container">
90+
<span class="icon">
91+
<img src="images/icons/ssh.svg">
92+
</span>
93+
<span>SSH Daemon is enabled in this container.</span>
94+
<code>ssh {{ sshd.split(':')[0] }} -p {{ sshd.split(':')[1] }} -l abstruse</code>
95+
<code>password: abstruse</code>
96+
</div>
97+
</div>
9198
<div class="column is-12">
9299
<app-terminal [data]="terminalInput" (outputData)="terminalOutput($event)" [options]="terminalOptions"></app-terminal>
93100
</div>

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

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,44 @@ export class AppJobComponent implements OnInit, OnDestroy {
3636
this.loading = true;
3737
this.status = 'queued';
3838
this.terminalOptions = { size: 'large' };
39+
this.id = null;
3940
}
4041

4142
ngOnInit() {
43+
this.termSub = this.socketService.outputEvents
44+
.subscribe(event => {
45+
if (event.type === 'data') {
46+
this.ngZone.run(() => this.terminalInput = event.data);
47+
} else if (event.type === 'jobStopped' && event.data === this.id) {
48+
this.processing = false;
49+
} else if (event.type === 'jobRestarted' && event.data === this.id) {
50+
this.processing = false;
51+
} else if (event.type === 'exposedPort') {
52+
this.sshd = `${document.location.hostname}:${event.data}`;
53+
}
54+
});
55+
56+
this.sub = this.socketService.outputEvents
57+
.filter(event => event.type === 'process')
58+
.filter(event => event.job_id === parseInt(<any>this.id, 10))
59+
.subscribe(event => {
60+
if (!this.job) {
61+
return;
62+
}
63+
64+
if (event.data === 'jobStarted') {
65+
this.job.status = 'running';
66+
this.job.end_time = null;
67+
this.job.start_time = new Date().getTime();
68+
} else if (event.data === 'jobSucceded') {
69+
this.job.status = 'success';
70+
this.job.end_time = new Date().getTime();
71+
} else if (event.data == 'jobFailed') {
72+
this.job.status = 'failed';
73+
this.job.end_time = new Date().getTime();
74+
}
75+
});
76+
4277
this.route.params.subscribe(params => {
4378
this.id = params.id;
4479

@@ -48,42 +83,12 @@ export class AppJobComponent implements OnInit, OnDestroy {
4883
this.timeWords = distanceInWordsToNow(job.build.start_time);
4984
this.loading = false;
5085

51-
this.termSub = this.socketService.outputEvents
52-
.subscribe(event => {
53-
if (event.type === 'data') {
54-
this.ngZone.run(() => this.terminalInput = event.data);
55-
} else if (event.type === 'jobStopped' && event.data === this.id) {
56-
this.processing = false;
57-
} else if (event.type === 'jobRestarted' && event.data === this.id) {
58-
this.processing = false;
59-
} else if (event.type === 'exposedPort') {
60-
this.sshd = `${document.location.hostname}:${event.data}`;
61-
}
62-
});
63-
6486
this.socketService.emit({ type: 'subscribeToJobOutput', data: { jobId: this.id } });
6587

6688
this.updateJobTime();
6789
setInterval(() => this.updateJobTime(), 1000);
68-
69-
this.sub = this.socketService.outputEvents
70-
.filter(event => event.type === 'process')
71-
.filter(event => event.job_id === parseInt(<any>this.id, 10))
72-
.subscribe(event => {
73-
if (event.data === 'jobStarted') {
74-
job.status = 'running';
75-
job.end_time = null;
76-
job.start_time = new Date().getTime();
77-
} else if (event.data === 'jobSucceded') {
78-
job.status = 'success';
79-
job.end_time = new Date().getTime();
80-
} else if (event.data == 'jobFailed') {
81-
job.status = 'failed';
82-
job.end_time = new Date().getTime();
83-
}
84-
});
85-
});
8690
});
91+
});
8792
}
8893

8994
ngOnDestroy() {
@@ -105,6 +110,7 @@ export class AppJobComponent implements OnInit, OnDestroy {
105110
e.stopPropagation();
106111
this.terminalInput = { clear: true };
107112
this.processing = true;
113+
this.sshd = null;
108114
this.socketService.emit({ type: 'restartJob', data: { jobId: this.id } });
109115
}
110116

@@ -113,13 +119,15 @@ export class AppJobComponent implements OnInit, OnDestroy {
113119
e.stopPropagation();
114120
this.terminalInput = { clear: true };
115121
this.processing = true;
122+
this.sshd = null;
116123
this.socketService.emit({ type: 'restartJobWithSSH', data: { jobId: this.id } });
117124
}
118125

119126
stopJob(e: MouseEvent): void {
120127
e.preventDefault();
121128
e.stopPropagation();
122129
this.processing = true;
130+
this.sshd = null;
123131
this.socketService.emit({ type: 'stopJob', data: { jobId: this.id } });
124132
}
125133

src/app/styles/build-details.sass

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,24 @@
102102

103103
.button
104104
margin-left: 10px
105+
106+
.ssh-container
107+
display: flex
108+
align-items: center
109+
padding: 15px 10px
110+
background: $background
111+
border: 1px solid $divider
112+
font-size: 13px
113+
114+
span
115+
margin: 0 10px 0 0
116+
117+
.icon
118+
margin-left: 10px
119+
120+
code
121+
background: $black
122+
color: $white
123+
padding: 5px 10px
124+
border-radius: 4px
125+
margin: 0 5px

0 commit comments

Comments
 (0)