Move to subfolder installer/
This commit is contained in:
213
installer/src/server.js
Executable file
213
installer/src/server.js
Executable file
@@ -0,0 +1,213 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/* jslint node: true */
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert'),
|
||||
async = require('async'),
|
||||
debug = require('debug')('installer:server'),
|
||||
express = require('express'),
|
||||
fs = require('fs'),
|
||||
http = require('http'),
|
||||
HttpError = require('connect-lastmile').HttpError,
|
||||
https = require('https'),
|
||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||
installer = require('./installer.js'),
|
||||
json = require('body-parser').json,
|
||||
lastMile = require('connect-lastmile'),
|
||||
morgan = require('morgan'),
|
||||
path = require('path'),
|
||||
superagent = require('superagent');
|
||||
|
||||
exports = module.exports = {
|
||||
start: start,
|
||||
stop: stop
|
||||
};
|
||||
|
||||
var PROVISION_CONFIG_FILE = '/root/provision.json';
|
||||
var CLOUDRON_CONFIG_FILE = '/home/yellowtent/configs/cloudron.conf';
|
||||
|
||||
var gHttpsServer = null, // provision server; used for install/restore
|
||||
gHttpServer = null; // update server; used for updates
|
||||
|
||||
function provisionDigitalOcean(callback) {
|
||||
if (fs.existsSync(CLOUDRON_CONFIG_FILE)) return callback(null); // already provisioned
|
||||
|
||||
superagent.get('http://169.254.169.254/metadata/v1.json').end(function (error, result) {
|
||||
if (error || result.statusCode !== 200) {
|
||||
console.error('Error getting metadata', error);
|
||||
return callback(new Error('Error getting metadata'));
|
||||
}
|
||||
|
||||
var userData = JSON.parse(result.body.user_data);
|
||||
|
||||
installer.provision(userData, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function provisionLocal(callback) {
|
||||
if (fs.existsSync(CLOUDRON_CONFIG_FILE)) return callback(null); // already provisioned
|
||||
|
||||
if (!fs.existsSync(PROVISION_CONFIG_FILE)) {
|
||||
console.error('No provisioning data found at %s', PROVISION_CONFIG_FILE);
|
||||
return callback(new Error('No provisioning data found'));
|
||||
}
|
||||
|
||||
var userData = require(PROVISION_CONFIG_FILE);
|
||||
|
||||
installer.provision(userData, callback);
|
||||
}
|
||||
|
||||
function update(req, res, next) {
|
||||
assert.strictEqual(typeof req.body, 'object');
|
||||
|
||||
if (!req.body.sourceTarballUrl || typeof req.body.sourceTarballUrl !== 'string') return next(new HttpError(400, 'No sourceTarballUrl provided'));
|
||||
if (!req.body.data || typeof req.body.data !== 'object') return next(new HttpError(400, 'No data provided'));
|
||||
|
||||
debug('provision: received from box %j', req.body);
|
||||
|
||||
installer.provision(req.body, function (error) {
|
||||
if (error) console.error(error);
|
||||
});
|
||||
|
||||
next(new HttpSuccess(202, { }));
|
||||
}
|
||||
|
||||
function retire(req, res, next) {
|
||||
assert.strictEqual(typeof req.body, 'object');
|
||||
|
||||
if (!req.body.data || typeof req.body.data !== 'object') return next(new HttpError(400, 'No data provided'));
|
||||
|
||||
if (typeof req.body.data.tlsCert !== 'string') console.error('No TLS cert provided');
|
||||
if (typeof req.body.data.tlsKey !== 'string') console.error('No TLS key provided');
|
||||
|
||||
debug('retire: received from appstore %j', req.body);
|
||||
|
||||
installer.retire(req.body, function (error) {
|
||||
if (error) console.error(error);
|
||||
});
|
||||
|
||||
next(new HttpSuccess(202, {}));
|
||||
}
|
||||
|
||||
function startUpdateServer(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
debug('Starting update server');
|
||||
|
||||
var app = express();
|
||||
|
||||
var router = new express.Router();
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') app.use(morgan('dev', { immediate: false }));
|
||||
|
||||
app.use(json({ strict: true }))
|
||||
.use(router)
|
||||
.use(lastMile());
|
||||
|
||||
router.post('/api/v1/installer/update', update);
|
||||
|
||||
gHttpServer = http.createServer(app);
|
||||
gHttpServer.on('error', console.error);
|
||||
|
||||
gHttpServer.listen(2020, '127.0.0.1', callback);
|
||||
}
|
||||
|
||||
function startProvisionServer(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
debug('Starting provision server');
|
||||
|
||||
var app = express();
|
||||
|
||||
var router = new express.Router();
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') app.use(morgan('dev', { immediate: false }));
|
||||
|
||||
app.use(json({ strict: true }))
|
||||
.use(router)
|
||||
.use(lastMile());
|
||||
|
||||
router.post('/api/v1/installer/retire', retire);
|
||||
|
||||
var caPath = path.join(__dirname, process.env.NODE_ENV === 'test' ? 'test/certs' : 'certs');
|
||||
var certPath = path.join(__dirname, process.env.NODE_ENV === 'test' ? 'test/certs' : 'certs');
|
||||
|
||||
var options = {
|
||||
key: fs.readFileSync(path.join(certPath, 'server.key')),
|
||||
cert: fs.readFileSync(path.join(certPath, 'server.crt')),
|
||||
ca: fs.readFileSync(path.join(caPath, 'ca.crt')),
|
||||
|
||||
// request cert from client and only allow from our CA
|
||||
requestCert: true,
|
||||
rejectUnauthorized: process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0' // this is set in the tests
|
||||
};
|
||||
|
||||
gHttpsServer = https.createServer(options, app);
|
||||
gHttpsServer.on('error', console.error);
|
||||
|
||||
gHttpsServer.listen(process.env.NODE_ENV === 'test' ? 4443 : 886, '0.0.0.0', callback);
|
||||
}
|
||||
|
||||
function stopProvisionServer(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
debug('Stopping provision server');
|
||||
|
||||
if (!gHttpsServer) return callback(null);
|
||||
|
||||
gHttpsServer.close(callback);
|
||||
gHttpsServer = null;
|
||||
}
|
||||
|
||||
function stopUpdateServer(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
debug('Stopping update server');
|
||||
|
||||
if (!gHttpServer) return callback(null);
|
||||
|
||||
gHttpServer.close(callback);
|
||||
gHttpServer = null;
|
||||
}
|
||||
|
||||
function start(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
var actions;
|
||||
|
||||
if (process.env.PROVISION === 'local') {
|
||||
debug('Starting Installer in selfhost mode');
|
||||
|
||||
actions = [
|
||||
startUpdateServer,
|
||||
provisionLocal
|
||||
];
|
||||
} else { // current fallback, should be 'digitalocean' eventually, see initializeBaseUbuntuImage.sh
|
||||
debug('Starting Installer in managed mode');
|
||||
|
||||
actions = [
|
||||
startUpdateServer,
|
||||
startProvisionServer,
|
||||
provisionDigitalOcean
|
||||
];
|
||||
}
|
||||
|
||||
async.series(actions, callback);
|
||||
}
|
||||
|
||||
function stop(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
async.series([
|
||||
stopUpdateServer,
|
||||
stopProvisionServer
|
||||
], callback);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
start(function (error) {
|
||||
if (error) console.error(error);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user