c9-core/server.js

238 wiersze
7.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
"use strict";
require("amd-loader");
try {
require("heapdump");
} catch(e) {}
var path = require("path");
var architect = require("architect");
var os = require("os");
var urls = require("c9/urls");
var hostname = require("c9/hostname");
var child_process = require("child_process");
require("c9/setup_paths.js");
if (process.version.match(/^v0/) && parseFloat(process.version.substr(3)) < 10) {
console.warn("You're using Node.js version " + process.version
+ ". Version 0.10 or higher is recommended. Some features will not work.");
}
var DEFAULT_CONFIG = "s";
var DEFAULT_SETTINGS = getDefaultSettings();
var shortcuts = {
"dev": ["ide", "preview", "user-content", "vfs", "api", "sapi", "proxy", "redis", "profile", "oldclient", "homepage", "apps-proxy", "-s", "devel"],
"onlinedev": ["ide", "preview", "user-content", "vfs", "api", "proxy", "oldclient", "homepage", "apps-proxy", "profile", "-s", "onlinedev"],
"beta": ["ide", "preview", "user-content", "vfs", "proxy", "-s", "beta"],
"s": ["standalone", "-s", "standalone"],
};
shortcuts.localdev = shortcuts.onlinedev.concat([
"-s", "beta",
"--ide.packed", "false",
"--ide.cdn", "false",
"--ide.forceDev", "true",
"--homepage.cdn", "false",
"--helpWithSudo",
"--api.port", "8281",
"--infra_port", "8282",
"--api_url", "http://api.c9.local:8281",
"--domains", "c9.local",
"--cdn.abbreviateVersion", "true",
]);
shortcuts.odev = shortcuts.onlinedev; // For backwards compatibility, if you see this in 2016 remove this line
var delayLoadConfigs = [
// Services that are usually not immediately needed
"preview", "user-content", "apps-proxy", "worker", "homepage",
// Services that are very slow to load, blocking others
"profile",
];
module.exports = main;
if (!module.parent)
main(process.argv.slice(2));
function getDefaultSettings() {
var suffix = hostname.parse(os.hostname()).env;
var modes = {
"workflowstaging": "workflow-staging",
"prod": "deploy",
"beta": "beta",
"dev": "devel",
"onlinedev": "onlinedev",
"test": "test"
};
return modes[suffix] || "devel";
}
module.exports.getDefaultSettings = getDefaultSettings;
function main(argv, config, onLoaded) {
var inContainer = os.hostname().match(/^\w+-\w+-\d+$/);
var optimist = require("optimist");
var async = require("async");
var options = optimist(argv)
.usage("Usage: $0 [CONFIG_NAME] [--help]")
.alias("s", "settings")
.default("settings", DEFAULT_SETTINGS)
.describe("settings", "Settings file to use")
.describe("dump", "dump config file as JSON")
.describe("domains", "Primary and any secondary top-level domains to use (e.g, c9.io,c9.dev)")
.describe("exclude", "Exclude specified service")
.describe("include", "Include only specified service")
.describe("helpWithSudo", "Ask for sudo password on startup")
.default("domains", inContainer && [process.env.C9_HOSTNAME || process.env.C9_DOMAINS, "c9.io"])
.boolean("help")
.describe("help", "Show command line options.");
var configs = options.argv._;
if (!configs.length)
configs = [config || DEFAULT_CONFIG];
var exclude = options.argv.exclude || [];
if (typeof exclude == "string")
exclude = exclude.split(",");
var expanded = expandShortCuts(configs);
if (expanded.length > configs.length)
return main(expanded.concat(argv.filter(function(arg) {
return !shortcuts[arg];
})), config, onLoaded);
if (options.argv.include)
expanded = [].concat(options.argv.include);
var delayed = expanded.filter(function(c) { return delayLoadConfigs.indexOf(c) !== -1 });
var notDelayed = expanded.filter(function(c) { return delayLoadConfigs.indexOf(c) === -1 });
if (options.argv.helpWithSudo)
return child_process.execFile("sudo", ["echo -n"], main.bind(null, argv.filter(function(a) {
return a !== "--helpWithSudo";
}), config, onLoaded));
startConfigs(notDelayed, function() {
startConfigs(delayed, function() {
console.log("Cloud9 is up and running");
});
});
function startConfigs(configs, done) {
async.each(configs, function(config, next) {
if (exclude && exclude.indexOf(config) > -1)
return next();
start(config, options, function(err, result, path) {
onLoaded && onLoaded(err, result, path);
next(err);
});
}, done);
}
}
function expandShortCuts(configs) {
var results = configs.slice();
for (var i = 0; i < results.length; i++) {
var expanded = shortcuts[results[i]];
if (expanded) {
results.splice.apply(results, [i, 1].concat(expanded));
i += expanded.length - 1;
}
}
return results;
}
function loadSettings(settingsName) {
var provider = hostname.parse(os.hostname()).provider;
var candidates = [
path.join(__dirname, "./settings", settingsName + "-" + provider),
path.join(__dirname, "./settings", settingsName)
];
var settings, settingsModule;
for (var i = 0; i < candidates.length; i++) {
var settingsPath = candidates[i];
try {
settingsModule = require(settingsPath);
} catch (e) {
continue;
}
settings = settingsModule();
break;
}
if (!settings)
throw new Error("No settings found");
return settings;
}
module.exports.loadSettings = loadSettings;
function start(configName, options, callback) {
console.log("Starting", configName);
var argv = options.argv;
var settingsName = argv.settings;
if (typeof settingsName != "string")
settingsName = settingsName.pop();
var configPath = configName;
if (configPath[0] !== "/")
configPath = path.join(__dirname, "/configs/", configName);
var settings = loadSettings(settingsName);
argv.domains = argv.domains || settings.domains;
if (settings.c9 && argv.domains)
urls.replaceDomains(settings, argv.domains);
var plugins = require(configPath)(settings, options);
if (argv.help) {
options.usage("Usage: $0 " + configName);
options.showHelp();
}
if (!plugins)
return;
if (module.exports.onResolvePlugins)
module.exports.onResolvePlugins(plugins, __dirname + "/plugins");
architect.resolveConfig(plugins, __dirname + "/plugins", function(err, config) {
if (err) {
console.error(err.stack || err);
process.exit(1);
}
if (argv.dump) {
console.log(JSON.stringify(config, null, 2));
return callback && callback(null, config);
}
if (argv._getConfig)
return callback && callback(null, config, configPath);
var app = architect.createApp(config, function (err, app) {
if (err) {
console.trace("Error while starting '%s':", configPath);
console.log(err, err.stack);
process.exit(1);
}
console.log("Started '%s' with config '%s'!", configPath, settingsName);
callback && callback(null, app);
});
app.on("service", function(name, plugin) {
if (typeof plugin !== "function")
plugin.name = name;
});
});
}