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

Commit f280b75

Browse files
committed
Merge branch 'develop', prepare 3.0
2 parents c79f80d + fd8f78a commit f280b75

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2853
-543
lines changed

.eslintrc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
"object-curly-spacing": ["warn", "never"],
1818
"max-len": ["error", 120, 4],
1919
"no-confusing-arrow": "warn",
20+
"global-require": "off",
21+
"no-underscore-dangle": "off",
22+
"no-await-in-loop": "off",
2023
"no-plusplus": "off",
24+
"prefer-promise-reject-errors": "off",
2125
"comma-dangle": [
2226
"error",
2327
{
@@ -28,7 +32,6 @@
2832
"functions": "ignore"
2933
}
3034
],
31-
"react/jsx-filename-extension": "off",
3235
"prettier/prettier": [
3336
"error",
3437
{

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ node_modules
22
.nyc_output
33
coverage
44
test/fixtures/auth.db
5-
test/fixtures/extensions/
5+
test/fixtures/deploying/
6+
test/fixtures/deploying-swarm/

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ cache: yarn
1212
before_install:
1313
- curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` > docker-compose
1414
- chmod +x docker-compose
15+
- docker swarm init
1516

1617
after_success:
1718
- docker rmi $(docker images -q)

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ Exoframe is a self-hosted tool that allows simple one-command deployments using
1212

1313
## Installation and Usage
1414

15-
1. Make sure you have Docker [installed and running](https://docs.docker.com/engine/installation/) on your host.
16-
2. Pull and run Exoframe server using docker:
15+
1. Make sure you have Docker [installed and running](https://docs.docker.com/engine/installation/) on your host.
16+
2. Pull and run Exoframe server using docker:
1717

1818
```sh
1919
docker run -d \
@@ -23,6 +23,7 @@ docker run -d \
2323
-e EXO_PRIVATE_KEY=your_private_key \
2424
--label traefik.backend=exoframe-server \
2525
--label traefik.frontend.rule=Host:exoframe.your-host.com \
26+
--restart always \
2627
--name exoframe-server \
2728
exoframe/server
2829

@@ -48,10 +49,35 @@ docker run -d \
4849
--label traefik.frontend.rule=Host:exoframe.your-host.com
4950
```
5051

51-
3. Edit config file to fit your needs (see section below)
52+
3. Edit config file to fit your needs (see section below)
5253

5354
Then install [Exoframe CLI](https://github.com/exoframejs/exoframe), point it to your new Exoframe server and use it.
5455

56+
## Installation and usage in Swarm mode
57+
58+
Exoframe also supports running in [Swarm mode](https://docs.docker.com/engine/swarm/).
59+
To run Exoframe server in swarm, you need to do the following:
60+
61+
1. Make sure you have Docker on your host.
62+
2. Make sure your Docker has [Swarm mode enabled](https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm/).
63+
3. Pull and run Exoframe server using Docker on your manager node:
64+
65+
```
66+
docker service create \
67+
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
68+
--mount type=bind,source=/path/to/exoframe-folder,target=/root/.exoframe \
69+
--mount type=bind,source=/home/user/.ssh/authorized_keys,target=/root/.ssh/authorized_keys,readonly \
70+
-e EXO_PRIVATE_KEY=your_private_key \
71+
--label traefik.backend=exoframe-server \
72+
--label traefik.frontend.rule=Host:exoframe.your-host.com \
73+
--label traefik.port=8080 \
74+
--constraint=node.role==manager \
75+
--name exoframe-server \
76+
exoframe/server
77+
```
78+
79+
Note that both Exoframe server and Traefik will be run on your manager node.
80+
5581
## Configuration
5682

5783
Exoframe stores its config in `~/.exoframe/server.config.yml`.

package.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"bin": "index.js",
77
"scripts": {
88
"start": "node index.js",
9-
"test": "NODE_ENV=testing jest --coverage --silent --maxWorkers=3 --ci",
9+
"test": "NODE_ENV=testing jest --coverage --silent --maxWorkers=2 --ci",
1010
"coveralls": "cat ./coverage/lcov.info | coveralls",
1111
"build": "pkg -t node8.9.0-alpine -o exoframe-server ."
1212
},
@@ -17,29 +17,29 @@
1717
"author": "Tim Ermilov <[email protected]>",
1818
"license": "MIT",
1919
"dependencies": {
20-
"chokidar": "^2.0.0",
20+
"chokidar": "^2.0.3",
2121
"cors": "^2.8.4",
22-
"dockerode": "^2.4.3",
23-
"fastify": "^0.40.0",
24-
"fastify-auth": "^0.1.0",
25-
"highland": "^2.11.1",
26-
"js-yaml": "^3.9.1",
27-
"jsonwebtoken": "^8.1.1",
28-
"lodash": "^4.17.4",
29-
"lokijs": "^1.5.0",
22+
"dockerode": "^2.5.5",
23+
"fastify": "^1.4.0",
24+
"fastify-auth": "^0.2.0",
25+
"highland": "^2.13.0",
26+
"js-yaml": "^3.11.0",
27+
"jsonwebtoken": "^8.2.1",
28+
"lodash": "^4.17.10",
29+
"lokijs": "^1.5.4",
3030
"mkdirp": "^0.5.1",
31-
"node-fetch": "^1.7.3",
31+
"node-fetch": "^2.1.2",
3232
"rimraf": "^2.6.1",
3333
"semver-compare": "^1.0.0",
34-
"sshpk": "^1.13.1",
35-
"tar-fs": "^1.15.2",
34+
"sshpk": "^1.14.1",
35+
"tar-fs": "^1.16.2",
3636
"uuid": "^3.2.1",
37-
"winston": "^2.3.1"
37+
"winston": "^2.4.2"
3838
},
3939
"devDependencies": {
40-
"coveralls": "^3.0.0",
40+
"coveralls": "^3.0.1",
4141
"get-port": "^3.2.0",
42-
"jest": "^22.1.4",
43-
"pkg": "^4.3.0"
42+
"jest": "^22.4.3",
43+
"pkg": "^4.3.1"
4444
}
4545
}

src/config/index.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@ const {spawn} = require('child_process');
1010
const logger = require('../logger');
1111

1212
// construct paths
13-
const baseFolder =
14-
process.env.NODE_ENV !== 'testing'
15-
? path.join(os.homedir(), '.exoframe')
16-
: path.join(__dirname, '..', '..', 'test', 'fixtures');
13+
const baseFolder = path.join(os.homedir(), '.exoframe');
1714
const configPath = path.join(baseFolder, 'server.config.yml');
18-
const publicKeysPath =
19-
process.env.NODE_ENV !== 'testing'
20-
? path.join(os.homedir(), '.ssh')
21-
: path.join(__dirname, '..', '..', 'test', 'fixtures');
15+
const publicKeysPath = path.join(os.homedir(), '.ssh');
2216
const extensionsFolder = path.join(baseFolder, 'extensions');
17+
const recipesFolder = path.join(baseFolder, 'recipes');
18+
// dir for temporary files used to build docker images
19+
const tempDir = path.join(baseFolder, 'deploying');
2320

2421
// export paths for others
2522
exports.baseFolder = baseFolder;
2623
exports.extensionsFolder = extensionsFolder;
24+
exports.recipesFolder = recipesFolder;
25+
exports.tempDockerDir = tempDir;
2726

2827
// create base folder if doesn't exist
2928
try {
@@ -45,6 +44,19 @@ try {
4544
spawn('yarn', ['init', '-y'], {cwd: extensionsFolder});
4645
}
4746

47+
// create recipes folder if doesn't exist
48+
try {
49+
fs.statSync(recipesFolder);
50+
} catch (e) {
51+
fs.mkdirSync(recipesFolder);
52+
}
53+
// init package.json if it doesn't exist
54+
try {
55+
fs.statSync(path.join(recipesFolder, 'package.json'));
56+
} catch (e) {
57+
spawn('yarn', ['init', '-y'], {cwd: recipesFolder});
58+
}
59+
4860
// default config
4961
const defaultConfig = {
5062
debug: false,
@@ -58,6 +70,8 @@ const defaultConfig = {
5870
traefikName: 'exoframe-traefik',
5971
traefikArgs: [],
6072
exoframeNetwork: 'exoframe',
73+
exoframeNetworkSwarm: 'exoframe-swarm',
74+
swarm: false,
6175
publicKeysPath,
6276
};
6377

src/docker/build.js

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,13 @@ const tar = require('tar-fs');
44
// our modules
55
const logger = require('../logger');
66
const docker = require('./docker');
7-
const {tempDockerDir, getProjectConfig, tagFromConfig, writeStatus} = require('../util');
7+
const {tempDockerDir} = require('../config');
8+
const {getProjectConfig, tagFromConfig, writeStatus} = require('../util');
89

9-
module.exports = ({username, resultStream}) =>
10-
new Promise(async (resolve, reject) => {
11-
// get packed stream
12-
const tarStream = tar.pack(tempDockerDir);
13-
14-
// get project info
15-
const config = getProjectConfig();
16-
17-
// construct image tag
18-
const tag = tagFromConfig({username, config});
19-
logger.debug('building with tag:', tag);
20-
writeStatus(resultStream, {message: `Building image with tag: ${tag}`, level: 'verbose'});
10+
const noop = () => {};
2111

12+
exports.buildFromParams = ({tarStream, tag, logLine = noop}) =>
13+
new Promise(async (resolve, reject) => {
2214
// deploy as docker
2315
const log = [];
2416
// track errors
@@ -34,21 +26,21 @@ module.exports = ({username, resultStream}) =>
3426
// process log data
3527
if (data.stream && data.stream.length) {
3628
log.push(data.stream);
37-
writeStatus(resultStream, {message: data.stream, level: 'verbose'});
29+
logLine({message: data.stream, level: 'verbose'});
3830
} else if (data.error && data.error.length) {
3931
// process error data
4032
log.push(data.error);
41-
writeStatus(resultStream, {message: data.error, level: 'error'});
33+
logLine({message: data.error, level: 'error'});
4234
hasErrors = true;
4335
} else {
4436
// push everything else as-is
4537
log.push(s);
46-
writeStatus(resultStream, {message: s, level: 'verbose'});
38+
logLine({message: s, level: 'verbose'});
4739
}
4840
} catch (e) {
4941
if (s && s.length) {
5042
log.push(s);
51-
writeStatus(resultStream, {message: s, level: 'verbose'});
43+
logLine({message: s, level: 'verbose'});
5244
}
5345
}
5446
});
@@ -61,3 +53,22 @@ module.exports = ({username, resultStream}) =>
6153
resolve({log, image: tag});
6254
});
6355
});
56+
57+
exports.build = async ({username, resultStream}) => {
58+
// get packed stream
59+
const tarStream = tar.pack(tempDockerDir);
60+
61+
// get project info
62+
const config = getProjectConfig();
63+
64+
// construct image tag
65+
const tag = tagFromConfig({username, config});
66+
logger.debug('building with tag:', tag);
67+
writeStatus(resultStream, {message: `Building image with tag: ${tag}`, level: 'verbose'});
68+
69+
// create logger function
70+
const logLine = data => writeStatus(resultStream, data);
71+
72+
// return build
73+
return exports.buildFromParams({tarStream, tag, logLine});
74+
};

0 commit comments

Comments
 (0)