Merge pull request #672 from embark-framework/3_1_0_defaultHost

docker awareness for 3_1_0
This commit is contained in:
Michael Bradley 2018-08-02 16:02:33 -05:00 committed by GitHub
commit 76daae121f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 100 additions and 26 deletions

View File

@ -8,6 +8,8 @@ const constants = require('../../constants.json');
const GethCommands = require('./geth_commands.js');
const DevFunds = require('./dev_funds.js');
const {defaultHost, dockerHostSwap} = require('../../utils/host');
/*eslint complexity: ["error", 36]*/
var Blockchain = function(options) {
this.blockchainConfig = options.blockchainConfig;
@ -31,7 +33,7 @@ var Blockchain = function(options) {
genesisBlock: this.blockchainConfig.genesisBlock || false,
datadir: this.blockchainConfig.datadir || false,
mineWhenNeeded: this.blockchainConfig.mineWhenNeeded || false,
rpcHost: this.blockchainConfig.rpcHost || 'localhost',
rpcHost: dockerHostSwap(this.blockchainConfig.rpcHost) || defaultHost,
rpcPort: this.blockchainConfig.rpcPort || 8545,
rpcCorsDomain: this.blockchainConfig.rpcCorsDomain || false,
networkId: this.blockchainConfig.networkId || 1337,
@ -44,7 +46,7 @@ var Blockchain = function(options) {
bootnodes: this.blockchainConfig.bootnodes || "",
rpcApi: (this.blockchainConfig.rpcApi || ['eth', 'web3', 'net', 'debug']),
wsRPC: (this.blockchainConfig.wsRPC === undefined) || this.blockchainConfig.wsRPC,
wsHost: this.blockchainConfig.wsHost || 'localhost',
wsHost: dockerHostSwap(this.blockchainConfig.wsHost) || defaultHost,
wsPort: this.blockchainConfig.wsPort || 8546,
wsOrigins: this.blockchainConfig.wsOrigins || false,
wsApi: (this.blockchainConfig.wsApi || defaultWsApi),

View File

@ -2,6 +2,7 @@ let shelljs = require('shelljs');
let proxy = require('../core/proxy');
const Ipc = require('../core/ipc');
const constants = require('../constants.json');
const {defaultHost, dockerHostSwap} = require('../utils/host');
class Simulator {
constructor(options) {
@ -21,7 +22,7 @@ class Simulator {
}
let useProxy = this.blockchainConfig.proxy || false;
let host = (options.host || this.blockchainConfig.rpcHost || 'localhost');
let host = (dockerHostSwap(options.host || this.blockchainConfig.rpcHost) || defaultHost);
let port = (options.port || this.blockchainConfig.rpcPort || 8545);
cmds.push("-p " + (port + (useProxy ? constants.blockchain.servicePortOnProxy : 0)));

View File

@ -5,6 +5,7 @@ const utils = require('../utils/utils.js');
const path = require('path');
const deepEqual = require('deep-equal');
const constants = require('../constants');
const {canonicalHost, defaultHost} = require('../utils/host');
var Config = function(options) {
const self = this;
@ -106,6 +107,9 @@ Config.prototype._updateBlockchainCors = function(){
// remove /ipfs or /bzz: from getUrl if it's there
let getUrlParts = storageConfig.upload.getUrl.split('/');
getUrlParts = getUrlParts.slice(0, 3);
let host = canonicalHost(getUrlParts[2].split(':')[0]);
let port = getUrlParts[2].split(':')[1];
getUrlParts[2] = port ? [host, port].join(':') : host;
corsParts.push(getUrlParts.join('/'));
}
// use our modified getUrl or in case it wasn't specified, use a built url
@ -246,7 +250,7 @@ Config.prototype.loadStorageConfigFile = function() {
"upload": {
"provider": "ipfs",
"protocol": "http",
"host": "localhost",
"host" : defaultHost,
"port": 5001,
"getUrl": "http://localhost:8080/ipfs/"
},
@ -281,7 +285,9 @@ Config.prototype.loadCommunicationConfigFile = function() {
"provider": "whisper",
"available_providers": ["whisper"],
"connection": {
"host": "localhost", "port": 8546, "type": "ws"
"host": defaultHost,
"port": 8546,
"type": "ws"
}
}
};
@ -293,7 +299,9 @@ Config.prototype.loadCommunicationConfigFile = function() {
Config.prototype.loadWebServerConfigFile = function() {
var configObject = {
"enabled": true, "host": "localhost", "port": 8000
"enabled": true,
"host": defaultHost,
"port": 8000
};
let configFilePath = this._getFileOrOject(this.configDir, 'webserver', 'webserver');

View File

@ -3,9 +3,11 @@ const http = require('http');
const constants = require('../constants.json');
let commList = {};
let transactions = {};
let transactions = {};
let receipts = {};
const {canonicalHost, defaultHost} = require('../utils/host');
const parseRequest = function(reqBody){
let jsonO;
try {
@ -42,7 +44,7 @@ const parseResponse = function(ipc, resBody){
commList[receipts[jsonO.id]].blockNumber = jsonO.result.blockNumber;
commList[receipts[jsonO.id]].gasUsed = jsonO.result.gasUsed;
commList[receipts[jsonO.id]].status = jsonO.result.status;
if(ipc.connected && !ipc.connecting){
ipc.request('log', commList[receipts[jsonO.id]]);
} else {
@ -61,7 +63,7 @@ const parseResponse = function(ipc, resBody){
exports.serve = function(ipc, host, port, ws){
let proxy = httpProxy.createProxyServer({
target: {
host,
host: canonicalHost(host),
port: port + constants.blockchain.servicePortOnProxy
},
ws: ws
@ -80,7 +82,7 @@ exports.serve = function(ipc, host, port, ws){
if(resBody){
parseResponse(ipc, resBody);
}
});
});
});
let server = http.createServer((req, res) => {
@ -110,16 +112,16 @@ exports.serve = function(ipc, host, port, ws){
parseResponse(ipc, data.toString().substr(data.indexOf("{")));
});
});
proxy.on('proxyReqWs', (proxyReq, req, socket) => {
var parser = new WsParser(0, false);
socket.pipe(parser);
parser.on('frame', function (frame) {
parseRequest(frame.data);
});
});
}
server.listen(port);
server.listen(port, defaultHost);
};

View File

@ -1,3 +1,4 @@
var {canonicalHost} = require('../../utils/host.js');
var utils = require('../../utils/utils.js');
var Server = require('./server.js');
@ -26,7 +27,7 @@ class WebServer {
}
setServiceCheck() {
let url = 'http://' + this.host + ':' + this.port;
let url = 'http://' + canonicalHost(this.host) + ':' + this.port;
this.events.request("services:register", 'Webserver', function (cb) {
utils.checkIsAvailable(url, function (available) {

View File

@ -1,19 +1,23 @@
let finalhandler = require('finalhandler');
let http = require('http');
let serveStatic = require('serve-static');
const {canonicalHost, defaultHost, dockerHostSwap} = require('../../utils/host');
require('http-shutdown').extend();
class Server {
constructor(options) {
this.dist = options.dist || 'dist/';
this.port = options.port || 8000;
this.hostname = options.host || 'localhost';
this.hostname = dockerHostSwap(options.host) || defaultHost;
this.logger = options.logger;
}
start(callback) {
if (this.server && this.server.listening) {
this.logger.warn(__("a webserver is already running at") + " " + ("http://" + this.hostname + ":" + this.port).bold.underline.green);
this.logger.warn(__("a webserver is already running at") +
" " +
("http://" + canonicalHost(this.hostname) +
":" + this.port).bold.underline.green);
if (callback) {
callback();
}
@ -25,7 +29,10 @@ class Server {
serve(req, res, finalhandler(req, res));
}).withShutdown();
this.logger.info(__("webserver available at") + " " + ("http://" + this.hostname + ":" + this.port).bold.underline.green);
this.logger.info(__("webserver available at") +
" " +
("http://" + canonicalHost(this.hostname) +
":" + this.port).bold.underline.green);
this.server.listen(this.port, this.hostname);
if (callback) {
callback();

View File

@ -2,6 +2,8 @@ let utils = require('../../utils/utils.js');
let fs = require('../../core/fs.js');
let Web3 = require('web3');
const {canonicalHost, defaultHost} = require('../../utils/host');
class Whisper {
constructor(embark, _options) {
@ -69,7 +71,7 @@ class Whisper {
let connection = this.communicationConfig.connection || {};
// todo: make the add code a function as well
let config = JSON.stringify({
server: connection.host || 'localhost',
server: canonicalHost(connection.host || defaultHost),
port: connection.port || '8546',
type: connection.type || 'ws'
});

View File

@ -4,6 +4,7 @@ const utils = require('../../utils/utils');
const ProcessLauncher = require('../../process/processLauncher');
const constants = require('../../constants');
const StorageUtils = require('./storageUtils');
const {canonicalHost} = require('../../utils/host');
class StorageProcessesLauncher {
constructor(options) {
@ -46,6 +47,9 @@ class StorageProcessesLauncher {
// remove /ipfs or /bzz: from getUrl if it's there
let getUrlParts = dappConn.getUrl.split('/');
getUrlParts = getUrlParts.slice(0, 3);
let host = canonicalHost(getUrlParts[2].split(':')[0]);
let port = getUrlParts[2].split(':')[1];
getUrlParts[2] = port ? [host, port].join(':') : host;
corsParts.push(getUrlParts.join('/'));
}
// in case getUrl wasn't specified, use a built url
@ -59,12 +63,12 @@ class StorageProcessesLauncher {
if(this.blockchainConfig.enabled) {
// add our rpc endpoints to CORS
if(this.blockchainConfig.rpcHost && this.blockchainConfig.rpcPort){
corsParts.push(`http://${this.blockchainConfig.rpcHost}:${this.blockchainConfig.rpcPort}`);
corsParts.push(`http://${canonicalHost(this.blockchainConfig.rpcHost)}:${this.blockchainConfig.rpcPort}`);
}
// add our ws endpoints to CORS
if(this.blockchainConfig.wsRPC && this.blockchainConfig.wsHost && this.blockchainConfig.wsPort){
corsParts.push(`ws://${this.blockchainConfig.wsHost}:${this.blockchainConfig.wsPort}`);
corsParts.push(`ws://${canonicalHost(this.blockchainConfig.wsHost)}:${this.blockchainConfig.wsPort}`);
}
}
return corsParts;

45
lib/utils/host.js Normal file
View File

@ -0,0 +1,45 @@
const isDocker = (() => {
let isDocker;
const hostname = require('os').hostname();
const pattern = new RegExp(
'[0-9]+\:[a-z_-]+\:\/docker\/' + hostname + '[0-9a-z]+', 'i'
);
try {
isDocker = require('child_process')
.execSync(
'cat /proc/self/cgroup',
{stdio: ['ignore', 'pipe', 'ignore']}
)
.toString().match(pattern) !== null;
} catch (e) {
isDocker = false;
}
return isDocker;
})();
const defaultHost = isDocker ? '0.0.0.0' : 'localhost';
// when we're runing in Docker, we can expect (generally, in a development
// scenario) that the user would like to connect to the service in the
// container via the **host's** loopback address, so this helper can be used to
// swap 0.0.0.0 for localhost in code/messages that pertain to client-side
function canonicalHost(host) {
return isDocker && host === '0.0.0.0' ? 'localhost' : host;
}
function dockerHostSwap(host) {
return (isDocker && (host === 'localhost' || host === '127.0.0.1')) ? defaultHost : host;
}
const defaultCorsHost = canonicalHost(defaultHost);
module.exports = {
canonicalHost,
defaultCorsHost,
defaultHost,
dockerHostSwap,
isDocker
};

View File

@ -1,5 +1,6 @@
let http = require('follow-redirects').http;
let https = require('follow-redirects').https;
const {canonicalHost} = require('./host');
const balanceRegex = /([0-9]+) ?([a-zA-Z]*)/;
@ -296,7 +297,7 @@ function buildUrl (protocol, host, port){
function buildUrlFromConfig (configObj){
if(!configObj) throw new Error('[utils.buildUrlFromConfig]: config object must cannot be null');
if(!configObj.host) throw new Error('[utils.buildUrlFromConfig]: object must contain a \'host\' property');
return this.buildUrl(configObj.protocol, configObj.host, configObj.port);
return this.buildUrl(configObj.protocol, canonicalHost(configObj.host), configObj.port);
}
function getWeiBalanceFromString(balanceString, web3){

View File

@ -1,6 +1,7 @@
/*globals describe, it*/
const Blockchain = require('../lib/cmds/blockchain/blockchain');
const constants = require('../lib/constants.json');
const {defaultHost} = require('../lib/utils/host');
const assert = require('assert');
@ -19,7 +20,7 @@ describe('embark.Blockchain', function () {
geth_bin: 'geth',
datadir: false,
mineWhenNeeded: false,
rpcHost: 'localhost',
rpcHost: defaultHost,
rpcPort: 8545,
rpcApi: ['eth', 'web3', 'net', 'debug'],
rpcCorsDomain: false,
@ -33,7 +34,7 @@ describe('embark.Blockchain', function () {
account: {},
bootnodes: "",
wsApi: ["eth", "web3", "net", "shh", "debug"],
wsHost: "localhost",
wsHost: defaultHost,
wsOrigins: false,
wsPort: 8546,
wsRPC: true,
@ -62,7 +63,7 @@ describe('embark.Blockchain', function () {
geth_bin: 'geth',
datadir: '/foo/datadir/',
mineWhenNeeded: true,
rpcHost: 'someserver',
rpcHost: defaultHost,
rpcPort: 12345,
rpcApi: ['eth', 'web3', 'net', 'debug'],
rpcCorsDomain: true,
@ -76,9 +77,9 @@ describe('embark.Blockchain', function () {
account: {},
bootnodes: "",
wsApi: ["eth", "web3", "net", "shh", "debug"],
wsHost: "localhost",
wsHost: defaultHost,
wsOrigins: false,
wsPort: 8546,
wsPort: 12346,
wsRPC: true,
targetGasLimit: false,
syncMode: undefined,