Skip to content
This repository was archived by the owner on Nov 23, 2022. It is now read-only.

Commit 4cab9ce

Browse files
committed
Merge branch 'develop', prepare 4.1.2
2 parents 275b74c + 2017bee commit 4cab9ce

File tree

15 files changed

+154
-10
lines changed

15 files changed

+154
-10
lines changed

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
FROM alpine
1+
FROM docker/compose:1.24.0
22

3-
# install required libs, docker-compose and yarn
4-
RUN apk update && apk add --no-cache libstdc++ libgcc py-pip yarn && pip install docker-compose
3+
# install required libs and yarn
4+
RUN apk update && apk add --no-cache libstdc++ libgcc yarn
55

66
# copy binary
77
COPY exoframe-server /

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "exoframe-server",
3-
"version": "4.1.1",
3+
"version": "4.1.2-dev",
44
"description": "Exoframe is a self-hosted tool that allows simple one-command deployments using Docker",
55
"main": "bin/server-core.js",
66
"bin": "bin/exoframe-server.js",

src/docker/templates/compose.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,10 @@ exports.executeTemplate = async ({
140140

141141
// generate host
142142
const host = getHost({serverConfig, name: baseName, config});
143-
const env = getEnv({username, config, name: baseName, host})
144-
.reduce((merged, [key, value]) => ({...merged, [key]: value}), {});
143+
const env = getEnv({username, config, name: baseName, host}).reduce(
144+
(merged, [key, value]) => ({...merged, [key]: value}),
145+
{}
146+
);
145147

146148
// re-build images if needed
147149
const {code: buildExitCode, log: buildLog} = await executeCompose({
@@ -154,6 +156,16 @@ exports.executeTemplate = async ({
154156
});
155157
util.logger.debug('Compose build executed, exit code:', buildExitCode);
156158

159+
if (buildExitCode !== '0') {
160+
util.writeStatus(resultStream, {
161+
message: `Deployment failed! Docker-compose build exited with code: ${buildExitCode}.`,
162+
log: buildLog,
163+
level: 'error',
164+
});
165+
resultStream.end('');
166+
return;
167+
}
168+
157169
// run compose via plugins if available
158170
const plugins = util.getPlugins();
159171
for (const plugin of plugins) {
@@ -184,7 +196,7 @@ exports.executeTemplate = async ({
184196
}
185197

186198
// execute compose 'up -d'
187-
const exitCode = await executeCompose({
199+
const {code: exitCode, log: execLog} = await executeCompose({
188200
cmd: ['--project-name', baseName, 'up', '-d'],
189201
env,
190202
resultStream,
@@ -194,6 +206,16 @@ exports.executeTemplate = async ({
194206
});
195207
util.logger.debug('Compose up executed, exit code:', exitCode);
196208

209+
if (exitCode !== '0') {
210+
util.writeStatus(resultStream, {
211+
message: `Deployment failed! Docker-compose up exited with code: ${exitCode}.`,
212+
log: execLog,
213+
level: 'error',
214+
});
215+
resultStream.end('');
216+
return;
217+
}
218+
197219
// get container infos
198220
const allContainers = await docker.daemon.listContainers({all: true});
199221
const deployments = await Promise.all(

src/routes/deploy.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,18 @@ const deploy = async ({username, folder, existing, resultStream}) => {
6969
}
7070
}
7171
}
72+
73+
// if template not found - throw an error
74+
if (!template) {
75+
logger.debug(`Build failed! Couldn't find template: ${config.template}`);
76+
util.writeStatus(resultStream, {
77+
message: `Build failed! Couldn't find template: ${config.template}!`,
78+
level: 'error',
79+
});
80+
resultStream.end('');
81+
return;
82+
}
83+
7284
logger.debug('Using template:', template);
7385
// execute fitting template
7486
await template.executeTemplate(templateProps);

src/routes/update.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ module.exports = fastify => {
5555
await traefikContainer.remove();
5656
}
5757
// re-init traefik
58-
initDocker({restart: true});
58+
initDocker();
5959
// reply
6060
reply.code(200).send({updated: true});
6161
return;

src/routes/version.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ module.exports = fastify => {
2727
const allImages = await docker.listImages();
2828
const traefik = allImages.find(img => img.RepoTags && img.RepoTags.find(t => t.includes('traefik')));
2929
if (traefik) {
30-
traefikVersion = traefik.Labels['org.label-schema.version'];
30+
traefikVersion =
31+
traefik.Labels['org.label-schema.version'] || traefik.Labels['org.opencontainers.image.version'];
3132
}
3233
// get latest versions
3334
const lastServerTag = await getLatestVersion(exoServerUrl);

test/deploy.test.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const authToken = require('./fixtures/authToken');
1515
const {startServer} = require('../src');
1616
const docker = require('../src/docker/docker');
1717
const {initNetwork} = require('../src/docker/network');
18-
const {getSecretsCollection, secretsInited} = require('../src/db/secrets')
18+
const {getSecretsCollection, secretsInited} = require('../src/db/secrets');
1919

2020
// create tar streams
2121
const streamDockerImage = tar.pack(path.join(__dirname, 'fixtures', 'docker-image-project'));
@@ -29,6 +29,9 @@ const streamCompose = tar.pack(path.join(__dirname, 'fixtures', 'compose-project
2929
const streamComposeUpdate = tar.pack(path.join(__dirname, 'fixtures', 'compose-project'));
3030
const streamBrokenDocker = tar.pack(path.join(__dirname, 'fixtures', 'broken-docker-project'));
3131
const streamBrokenNode = tar.pack(path.join(__dirname, 'fixtures', 'broken-node-project'));
32+
const streamBrokenTemplate = tar.pack(path.join(__dirname, 'fixtures', 'broken-template-project'));
33+
const streamBrokenCompose = tar.pack(path.join(__dirname, 'fixtures', 'broken-compose-project'));
34+
const streamBrokenComposeStart = tar.pack(path.join(__dirname, 'fixtures', 'broken-compose-project-start'));
3235
const streamAdditionalLabels = tar.pack(path.join(__dirname, 'fixtures', 'additional-labels'));
3336
const streamTemplate = tar.pack(path.join(__dirname, 'fixtures', 'template-project'));
3437

@@ -612,6 +615,78 @@ test('Should display error log for broken Node.js project', async done => {
612615
done();
613616
});
614617

618+
test('Should display error log for project with broken template', async done => {
619+
const options = Object.assign(optionsBase, {
620+
payload: streamBrokenTemplate,
621+
});
622+
623+
const response = await fastify.inject(options);
624+
// parse result into lines
625+
const result = response.payload
626+
.split('\n')
627+
.filter(l => l && l.length)
628+
.map(line => JSON.parse(line));
629+
630+
// get last error
631+
const error = result.pop();
632+
633+
// check response
634+
expect(response.statusCode).toEqual(200);
635+
expect(error.level).toEqual('error');
636+
expect(error.message).toEqual(`Build failed! Couldn't find template: do-not-exist!`);
637+
638+
// clean all exited containers
639+
const allContainers = await docker.listContainers({all: true});
640+
const exitedWithError = allContainers.filter(c => c.Status.includes('Exited (1)'));
641+
await Promise.all(exitedWithError.map(c => docker.getContainer(c.Id)).map(c => c.remove()));
642+
643+
done();
644+
});
645+
646+
test('Should display error log for broken compose project build', async done => {
647+
const options = Object.assign(optionsBase, {
648+
payload: streamBrokenCompose,
649+
});
650+
651+
const response = await fastify.inject(options);
652+
// parse result into lines
653+
const result = response.payload
654+
.split('\n')
655+
.filter(l => l && l.length)
656+
.map(line => JSON.parse(line));
657+
658+
// get last error
659+
const error = result.pop();
660+
661+
// check response
662+
expect(response.statusCode).toEqual(200);
663+
expect(error.message).toEqual(`Deployment failed! Docker-compose build exited with code: 1.`);
664+
665+
done();
666+
});
667+
668+
test('Should display error log for broken compose project start', async done => {
669+
const options = Object.assign(optionsBase, {
670+
payload: streamBrokenComposeStart,
671+
});
672+
673+
const response = await fastify.inject(options);
674+
// parse result into lines
675+
const result = response.payload
676+
.split('\n')
677+
.filter(l => l && l.length)
678+
.map(line => JSON.parse(line));
679+
680+
// get last error
681+
const error = result.pop();
682+
683+
// check response
684+
expect(response.statusCode).toEqual(200);
685+
expect(error.message).toEqual(`Deployment failed! Docker-compose up exited with code: 1.`);
686+
687+
done();
688+
});
689+
615690
test('Should have additional labels', async done => {
616691
const options = Object.assign(optionsBase, {
617692
payload: streamAdditionalLabels,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM busybox
2+
3+
CMD ["exit", "1"]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version: '2'
2+
services:
3+
web:
4+
build: .
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "test-broken-compose-deploy",
3+
"restart": "no"
4+
}

0 commit comments

Comments
 (0)