-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathserver.js
120 lines (96 loc) · 3.63 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
var fs = require('fs');
var path = require('path');
var child_process = require('child_process');
var express = require('express');
var basicAuth = require('basic-auth');
var currentPlatform = require('./env');
function hook(req, res, next) {
console.log('Deployment request received: ' + JSON.stringify(req.params));
var id = req.params[0];
if (!id) {
console.log('[400] Bad request. Without project id.');
return res.status(400).end();
}
// find project in config
var project = config.projects[id];
if (!project) {
console.log('[404] Not found. No project named as "' + id + '" found.');
return res.status(404).end();
}
// find branch options in config
var branch = req.params[1] || config.defaultBranch || 'orign/master';
var options = project[branch];
if (!options) {
console.log('[404] No options of branch "' + branch + '" found. Please check config.');
return res.status(404).end();
}
var branchParam = branch.split('/');
var remote = branchParam[0];
if (branchParam.length == 1) {
remote = config.defaultRemote || 'origin';
} else {
branch = branchParam[1];
}
// check auth
var auth = basicAuth(req);
if (!auth ||
!auth.pass ||
options.users.indexOf(auth.name) < 0 ||
config.users[auth.name] != auth.pass) {
console.log('[403] Forbidden.');
return res.status(403).end();
}
console.log('Authentication passed.');
if (!fs.existsSync(options.path)) {
console.log('[404] No path found for project: "' + id + '"');
return res.status(404).end();
}
var execFileOptions = Object.assign({}, currentPlatform.execFileOptions, { cwd: options.path });
if (currentPlatform.posix) {
var uid = parseInt(child_process.execSync('id -u ' + auth.name).toString().trim(), 10);
var gid = parseInt(child_process.execSync('id -g ' + auth.name).toString().trim(), 10);
var home = child_process.execSync('echo ~' + auth.name).toString().trim();
if (auth.name && (!uid || !home)) {
return res.status(404).send('[404] No user or home directory found');
}
execFileOptions.uid = uid;
execFileOptions.gid = gid;
// when running hookagent under root
if (process.env.USER === 'root') {
// get the target user's env
var envBuffer = child_process.execSync(`su - -c env ${auth.name}`);
envBuffer.toString().split('\n').forEach(line => {
var [key, ...value] = line.split('=');
execFileOptions.env[key] = value.join('');
});
} else {
Object.assign(execFileOptions.env, process.env);
}
}
res.status(200).send('ok');
child_process.execFile(path.join(__dirname, 'bin', `deploy.${currentPlatform.ext}`), [
id,
remote,
branch,
config.gitPath || ''
], execFileOptions, function (error, stdout, stderr) {
console.log(stdout);
if (error) {
console.error(error);
} else {
console.log('Deployment done.');
}
});
console.log('[200] Deployment started.');
}
var config = require(currentPlatform.configPath);
var agent = express();
agent.get('/', function (req, res, next) {
// indicate process is running
res.status(200).send('ok');
});
// [POST]:/project/project-name[@[remote/]branch-name]
agent.post(/\/project\/([\w\.\-]+)(?:@([\w\/\.\-]+))?/i, hook);
agent.listen(config.port, function() {
console.log("Hook agent started at %s. Listening on %d", new Date(), config.port);
});