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

Commit 084b14a

Browse files
committed
Add way to deploy projects from image and image tar file
1 parent 3583f61 commit 084b14a

File tree

6 files changed

+106
-1
lines changed

6 files changed

+106
-1
lines changed

src/docker/templates/image.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// npm packages
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
// template name
6+
exports.name = 'image';
7+
8+
// function to check if the template fits this recipe
9+
exports.checkTemplate = async ({config}) => {
10+
// if project has image field defined in config
11+
try {
12+
return config.image && config.image.length;
13+
} catch (e) {
14+
return false;
15+
}
16+
};
17+
18+
// function to execute current template
19+
exports.executeTemplate = async ({config, username, tempDockerDir, folder, resultStream, util, docker}) => {
20+
// build docker image
21+
try {
22+
const {image, imageFile} = config;
23+
util.writeStatus(resultStream, {message: `Deploying project from image: ${image}..`, level: 'info'});
24+
25+
// import from tar if needed
26+
if (imageFile && imageFile.length) {
27+
util.writeStatus(resultStream, {message: `Importing image from file: ${imageFile}..`, level: 'info'});
28+
// get packed stream
29+
const tarStream = fs.createReadStream(path.join(tempDockerDir, folder, imageFile));
30+
const importRes = await docker.daemon.loadImage(tarStream, {tag: image});
31+
util.logger.debug('Import result:', importRes);
32+
}
33+
34+
// start image
35+
const container = await docker.start({image, username, folder, resultStream});
36+
util.logger.debug(container);
37+
38+
// return new deployments
39+
util.writeStatus(resultStream, {message: 'Deployment success!', deployments: [container], level: 'info'});
40+
resultStream.end('');
41+
} catch (e) {
42+
util.logger.debug('build failed!', e);
43+
util.writeStatus(resultStream, {message: e.error, error: e.error, log: e.log, level: 'error'});
44+
resultStream.end('');
45+
}
46+
};

src/docker/templates/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const path = require('path');
77
const {extensionsFolder} = require('../../config');
88

99
// hard-coded templates
10+
const imageTemplate = require('./image');
1011
const composeTemplate = require('./compose');
1112
const dockerfileTemplate = require('./dockerfile');
1213
const nodeTemplate = require('./node');
@@ -23,5 +24,5 @@ module.exports = () => {
2324
return require(templatePath);
2425
});
2526

26-
return [composeTemplate, dockerfileTemplate, nodeTemplate, nginxTemplate].concat(userTemplates);
27+
return [imageTemplate, composeTemplate, dockerfileTemplate, nodeTemplate, nginxTemplate].concat(userTemplates);
2728
};

test/deploy.test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const docker = require('../src/docker/docker');
1717
const {initNetwork} = require('../src/docker/network');
1818

1919
// create tar streams
20+
const streamDockerImage = tar.pack(path.join(__dirname, 'fixtures', 'docker-image-project'));
2021
const streamDocker = tar.pack(path.join(__dirname, 'fixtures', 'docker-project'));
2122
const streamNode = tar.pack(path.join(__dirname, 'fixtures', 'node-project'));
2223
const streamNodeLock = tar.pack(path.join(__dirname, 'fixtures', 'node-lock-project'));
@@ -111,6 +112,52 @@ test('Should deploy simple docker project', async done => {
111112
done();
112113
});
113114

115+
test('Should deploy simple project from image and image tar', async done => {
116+
const options = Object.assign(optionsBase, {
117+
payload: streamDockerImage,
118+
});
119+
120+
const response = await fastify.inject(options);
121+
// parse result into lines
122+
const result = response.payload
123+
.split('\n')
124+
.filter(l => l && l.length)
125+
.map(line => JSON.parse(line));
126+
127+
// find deployments
128+
const completeDeployments = result.find(it => it.deployments && it.deployments.length).deployments;
129+
130+
// check response
131+
expect(response.statusCode).toEqual(200);
132+
expect(completeDeployments.length).toEqual(1);
133+
expect(completeDeployments[0].Name.startsWith('/exo-test-image-')).toBeTruthy();
134+
135+
// check docker services
136+
const allContainers = await docker.listContainers();
137+
const containerInfo = allContainers.find(c => c.Names.includes(completeDeployments[0].Name));
138+
const name = completeDeployments[0].Name.slice(1);
139+
140+
expect(containerInfo).toBeDefined();
141+
expect(containerInfo.Labels['exoframe.deployment']).toEqual(name);
142+
expect(containerInfo.Labels['exoframe.user']).toEqual('admin');
143+
expect(containerInfo.Labels['exoframe.project']).toEqual('test-image-project');
144+
expect(containerInfo.Labels['traefik.backend']).toEqual(`${name}.test`);
145+
expect(containerInfo.Labels['traefik.docker.network']).toEqual('exoframe');
146+
expect(containerInfo.Labels['traefik.enable']).toEqual('true');
147+
expect(containerInfo.NetworkSettings.Networks.exoframe).toBeDefined();
148+
149+
const containerData = docker.getContainer(containerInfo.Id);
150+
const container = await containerData.inspect();
151+
expect(container.NetworkSettings.Networks.exoframe.Aliases.includes('testimage')).toBeTruthy();
152+
expect(container.HostConfig.RestartPolicy).toMatchObject({Name: 'no', MaximumRetryCount: 0});
153+
154+
// cleanup
155+
const instance = docker.getContainer(containerInfo.Id);
156+
await instance.remove({force: true});
157+
158+
done();
159+
});
160+
114161
test('Should deploy simple node project', async done => {
115162
const options = Object.assign(optionsBase, {
116163
payload: streamNode,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM busybox
2+
3+
CMD ["sleep", "300"]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "test-docker-image-deploy",
3+
"hostname": "testimage",
4+
"project": "test-image-project",
5+
"restart": "no",
6+
"image": "exo-test-image",
7+
"imageFile": "image.tar"
8+
}
1.36 MB
Binary file not shown.

0 commit comments

Comments
 (0)