mirror of https://github.com/docker/docs.git
Fixing common installer bugs
This commit is contained in:
parent
392288042c
commit
adff625795
|
@ -1,14 +1,54 @@
|
||||||
var exec = require('exec');
|
var exec = require('exec');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
boot2dockerexec = function (command, callback) {
|
Boot2Docker = {};
|
||||||
exec(path.join(getBinDir(), 'boot2docker') + ' ' + command, function(err, stdout) {
|
|
||||||
callback(err, stdout);
|
Boot2Docker.REQUIRED_IP = '192.168.60.103';
|
||||||
|
|
||||||
|
Boot2Docker.exec = function (command, callback) {
|
||||||
|
exec(path.join(getBinDir(), 'boot2docker') + ' ' + command, function(err, stdout, stderr) {
|
||||||
|
callback(err, stdout, stderr);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoot2DockerIp = function (callback) {
|
Boot2Docker.exists = function (callback) {
|
||||||
boot2dockerexec('ip', function (err, stdout) {
|
this.exec('info', function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(null, false);
|
||||||
|
} else {
|
||||||
|
callback(null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.stop = function (callback) {
|
||||||
|
this.exec('stop', function (err, stdout) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.erase = function (callback) {
|
||||||
|
var VMFileLocation = path.join(getHomePath(), 'VirtualBox\\ VMs/boot2docker-vm');
|
||||||
|
exec('rm -rf ' + VMFileLocation, function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.upgrade = function (callback) {
|
||||||
|
var self = this;
|
||||||
|
self.stop(function (err) {
|
||||||
|
self.exec('upgrade', function (err, stdout) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.ip = function (callback) {
|
||||||
|
this.exec('ip', function (err, stdout) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, null);
|
callback(err, null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,8 +57,51 @@ getBoot2DockerIp = function (callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoot2DockerState = function (callback) {
|
Boot2Docker.setIp = function (ifname, ip, callback) {
|
||||||
boot2dockerexec(' info', function (err, stdout) {
|
this.exec('ssh "sudo ifconfig ' + ifname + ' ' + ip + ' netmask 255.255.255.0"', function (err, stdout) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.init = function (callback) {
|
||||||
|
this.exec('init', function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.start = function (callback) {
|
||||||
|
var self = this;
|
||||||
|
self.exists(function (err, exists) {
|
||||||
|
if (!exists) {
|
||||||
|
callback('Cannot start if the boot2docker VM doesn\'t exist');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.exec('up -v', function (err, stdout) {
|
||||||
|
console.log('here0');
|
||||||
|
console.log('here1');
|
||||||
|
// Sometimes boot2docker returns an error code even though it's working / waiting, so treat that as
|
||||||
|
// Success as well
|
||||||
|
if (!err || (err.indexOf('Waiting for VM to be started') !== -1 || err.indexOf('..........') !== -1)) {
|
||||||
|
Boot2Docker.setIp('eth2', Boot2Docker.REQUIRED_IP, function(err) {
|
||||||
|
console.log('here1');
|
||||||
|
if (err) { callback(err); return; }
|
||||||
|
VirtualBox.removeDHCP(function (err) {
|
||||||
|
console.log('here2');
|
||||||
|
self.injectUtilities(function (err) {
|
||||||
|
console.log('here3');
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Boot2Docker.state = function (callback) {
|
||||||
|
this.exec('info', function (err, stdout) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, null);
|
callback(err, null);
|
||||||
return;
|
return;
|
||||||
|
@ -32,8 +115,8 @@ getBoot2DockerState = function (callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoot2DockerDiskUsage = function (callback) {
|
Boot2Docker.diskUsage = function (callback) {
|
||||||
boot2dockerexec('ssh "df"', function (err, stdout) {
|
this.exec('ssh "df"', function (err, stdout) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, null);
|
callback(err, null);
|
||||||
return;
|
return;
|
||||||
|
@ -61,8 +144,8 @@ getBoot2DockerDiskUsage = function (callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoot2DockerMemoryUsage = function (callback) {
|
Boot2Docker.memoryUsage = function (callback) {
|
||||||
boot2dockerexec('ssh "free -m"', function (err, stdout) {
|
this.exec('ssh "free -m"', function (err, stdout) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, null);
|
callback(err, null);
|
||||||
return;
|
return;
|
||||||
|
@ -92,152 +175,80 @@ getBoot2DockerMemoryUsage = function (callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoot2DockerInfo = function (callback) {
|
Boot2Docker.stats = function (callback) {
|
||||||
boot2dockerexec('ssh "sudo ifconfig eth1 192.168.59.103 netmask 255.255.255.0"', function (err, stdout) {
|
this.state(function (err, state) {
|
||||||
exec('VBoxManage dhcpserver remove --netname HostInterfaceNetworking-vboxnet0', function (err, stdout) {
|
if (err) {
|
||||||
getBoot2DockerState(function (err, state) {
|
callback(err, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state === 'poweroff') {
|
||||||
|
callback(null, {state: state});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.memoryUsage(function (err, mem) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, null);
|
callback(null, {state: state});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state === 'poweroff') {
|
this.diskUsage(function (err, disk) {
|
||||||
callback(null, {state: state});
|
|
||||||
} else {
|
|
||||||
getBoot2DockerMemoryUsage(function (err, mem) {
|
|
||||||
if (err) { callback(null, {state: state}); }
|
|
||||||
getBoot2DockerDiskUsage(function (err, disk) {
|
|
||||||
if (err) { callback(null, {state: state}); }
|
|
||||||
callback(null, {
|
|
||||||
state: state,
|
|
||||||
memory: mem,
|
|
||||||
disk: disk
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
boot2DockerVMExists = function (callback) {
|
|
||||||
boot2dockerexec('info', function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(null, false);
|
|
||||||
} else {
|
|
||||||
callback(null, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
eraseBoot2DockerVMFiles = function (callback) {
|
|
||||||
var VMFileLocation = path.join(getHomePath(), 'VirtualBox\\ VMs/boot2docker-vm');
|
|
||||||
exec('rm -rf ' + VMFileLocation, function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
initBoot2Docker = function (callback) {
|
|
||||||
isVirtualBoxInstalled(function (err, installed) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (installed) {
|
|
||||||
boot2dockerexec('init', function (err) {
|
|
||||||
console.log(err);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.indexOf('exit status 1') !== -1) {
|
callback(null, {state: state});
|
||||||
eraseBoot2DockerVMFiles(function () {
|
return;
|
||||||
boot2dockerexec('init', function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
|
callback(null, {
|
||||||
|
state: state,
|
||||||
|
memory: mem,
|
||||||
|
disk: disk
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the VM's version.
|
||||||
|
* Node that this only works if the VM is up and running.
|
||||||
|
*/
|
||||||
|
Boot2Docker.vmVersion = function (callback) {
|
||||||
|
this.exec('ssh "cat /etc/version', function (err, stdout, stderr) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('initBoot2Docker called but VirtualBox isn\'t installed.'));
|
callback(null, stdout);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
upgradeBoot2Docker = function (callback) {
|
Boot2Docker.version = function (callback) {
|
||||||
boot2dockerexec('upgrade', function (err, stdout) {
|
this.exec('version', function (err, stdout, stderr) {
|
||||||
console.log(stdout);
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var match = stdout.match(/Client version: v(\d\.\d\.\d)/);
|
||||||
|
if (!match || match.length < 2) {
|
||||||
|
callback('Could not parse the boot2docker cli version.')
|
||||||
|
} else {
|
||||||
|
callback(null, match[1]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
installBoot2DockerAddons = function (callback) {
|
Boot2Docker.injectUtilities = function (callback) {
|
||||||
exec('/bin/cat ' + path.join(getBinDir(), 'kite-binaries.tar.gz') + ' | ' + path.join(getBinDir(), 'boot2docker') + ' ssh "tar zx -C /usr/local/bin"', function (err, stdout) {
|
exec('/bin/cat ' + path.join(getBinDir(), 'kite-binaries.tar.gz') + ' | ' + path.join(getBinDir(), 'boot2docker') + ' ssh "tar zx -C /usr/local/bin"', function (err, stdout) {
|
||||||
console.log(stdout);
|
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
exec('VBoxManage modifyvm boot2docker-vm --nic2 hostonly --nictype2 virtio --cableconnected2 on --hostonlyadapter2 vboxnet0', function (err, stdout) {});
|
|
||||||
boot2dockerexec('ssh "sudo ifconfig eth1 192.168.59.103 netmask 255.255.255.0"', function (err, stdout) {});
|
|
||||||
exec('VBoxManage dhcpserver remove --netname HostInterfaceNetworking-vboxnet0', function (err, stdout) {});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
startBoot2Docker = function (callback) {
|
Boot2Docker.check = function (callback) {
|
||||||
isVirtualBoxInstalled(function (err, installed) {
|
var self = this;
|
||||||
if (err) {
|
self.exists(function (err) {
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (installed) {
|
|
||||||
boot2DockerVMExists(function (err, exists) {
|
|
||||||
if (exists) {
|
|
||||||
boot2dockerexec('up -v', function (err, stdout) {
|
|
||||||
console.log(err);
|
|
||||||
console.log(stdout);
|
|
||||||
if (err) {
|
|
||||||
if (err.indexOf('Waiting for VM to be started') !== -1 || err.indexOf('..........') !== -1) {
|
|
||||||
installBoot2DockerAddons(function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
installBoot2DockerAddons(function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback(new Error('startBoot2Docker called but boot2docker-vm doesn\'t exist.'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback(new Error('startBoot2Docker called but VirtualBox isn\'t installed.'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
stopBoot2Docker = function (callback) {
|
|
||||||
boot2dockerexec('stop', function (err, stdout) {
|
|
||||||
console.log(stdout);
|
|
||||||
console.log(err);
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
checkBoot2DockerVM = function (callback) {
|
|
||||||
boot2DockerVMExists(function (err) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
getBoot2DockerState(function (err, state) {
|
self.state(function (err, state) {
|
||||||
if (state !== 'running') {
|
if (state !== 'running') {
|
||||||
callback('boot2docker not running');
|
callback('boot2docker not running');
|
||||||
} else {
|
} else {
|
||||||
|
@ -248,10 +259,9 @@ checkBoot2DockerVM = function (callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure the VM exists, is up and is running.
|
Boot2Docker.resolve = function (callback) {
|
||||||
resolveBoot2DockerVM = function (callback) {
|
var self = this;
|
||||||
boot2DockerVMExists(function (err, exists) {
|
self.exists(function (err, exists) {
|
||||||
|
|
||||||
// If somehow the boot2docker VM doesn't exist anymor then re-create it.
|
// If somehow the boot2docker VM doesn't exist anymor then re-create it.
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
initBoot2Docker(function () {
|
initBoot2Docker(function () {
|
||||||
|
@ -260,9 +270,8 @@ resolveBoot2DockerVM = function (callback) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// If it exists but it's not running.. restart it.
|
// If it exists but it's not running.. restart it.
|
||||||
getBoot2DockerState(function (err, state) {
|
self.state(function (err, state) {
|
||||||
if (state !== 'running') {
|
if (state !== 'running') {
|
||||||
startBoot2Docker(function (err) {
|
startBoot2Docker(function (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
Installer = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install steps. A step is a function that accepts a function (err) callback and returns once that step is complete.keys:
|
||||||
|
* - run: Function that runs the installation step and calls the callback with an error if failed.
|
||||||
|
* - pastMessage: Message to show after step completion
|
||||||
|
* - message: Message to show while step is running
|
||||||
|
* - imperativeMessage: Message to show before running
|
||||||
|
*/
|
||||||
|
Installer.steps = [
|
||||||
|
{
|
||||||
|
run: function (callback) {
|
||||||
|
var installed = VirtualBox.installed();
|
||||||
|
if (!installed) {
|
||||||
|
VirtualBox.install(function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Version 4.3.12 is required.
|
||||||
|
VirtualBox.version(function (err, installedVersion) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var needsUpdate = Utilities.compareVersions(installedVersion, VirtualBox.REQUIRED_VERSION) < 0;
|
||||||
|
if (needsUpdate) {
|
||||||
|
VirtualBox.install(function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pastMessage: 'VirtualBox installed',
|
||||||
|
message: 'Installing VirtualBox',
|
||||||
|
futureMessage: 'Install VirtualBox if necessary'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Initialize Boot2Docker if necessary.
|
||||||
|
{
|
||||||
|
run: function (callback) {
|
||||||
|
Boot2Docker.exists(function (err, exists) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!exists) {
|
||||||
|
Boot2Docker.init(function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Boot2Docker.stop(function (err) {
|
||||||
|
Boot2Docker.upgrade(function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pastMessage: 'Setup the Boot2Docker VM (if required)',
|
||||||
|
message: 'Setting up the Boot2Docker VM',
|
||||||
|
futureMessage: 'Set up the Boot2Docker VM(if required)'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set up the routing.
|
||||||
|
{
|
||||||
|
run: function (callback) {
|
||||||
|
VirtualBox.setupRouting('boot2docker-vm', function (err, ifname) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pastMessage: 'Container routing set up.',
|
||||||
|
message: 'Setting up container routing (root required).',
|
||||||
|
subMessage: '(This may take a few minutes)',
|
||||||
|
futureMessage: 'Set up container routing to VM (root required).'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Start the Kitematic VM
|
||||||
|
{
|
||||||
|
run: function (callback) {
|
||||||
|
Boot2Docker.state(function (err, state) {
|
||||||
|
if (state !== 'running') {
|
||||||
|
Boot2Docker.start(function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Boot2Docker.setIp('eth2', Boot2Docker.REQUIRED_IP, function(err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pastMessage: 'Started the Boot2Docker VM',
|
||||||
|
message: 'Starting the Boot2Docker VM',
|
||||||
|
subMessage: '(This may take a few minutes)',
|
||||||
|
futureMessage: 'Start the Kitematic VM',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set up the default Kitematic images
|
||||||
|
{
|
||||||
|
run: function (callback) {
|
||||||
|
Meteor.call('reloadDefaultContainers', function (err) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pastMessage: 'Started the Boot2Docker VM',
|
||||||
|
message: 'Setting up the default Kitematic images...',
|
||||||
|
subMessage: '(This may take a few minutes)',
|
||||||
|
futureMessage: 'Set up the default Kitematic images',
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
Installer.run = function (callback) {
|
||||||
|
var currentStep = 0;
|
||||||
|
Session.set('currentInstallStep', currentStep);
|
||||||
|
Session.set('numberOfInstallSteps', this.steps.length);
|
||||||
|
async.eachSeries(this.steps, function (step, callback) {
|
||||||
|
console.log('Performing step ' + currentStep);
|
||||||
|
step.run(function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
currentStep += 1;
|
||||||
|
Session.set('currentInstallStep', currentStep);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
if (err) {
|
||||||
|
// if any of the steps fail
|
||||||
|
console.log('Kitematic setup failed at step ' + currentStep);
|
||||||
|
console.log(err);
|
||||||
|
Session.set('failedStep', currentStep);
|
||||||
|
Session.set('failedError', err);
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
// Setup Finished
|
||||||
|
console.log('Setup finished.');
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,5 +1,80 @@
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
|
Utilities = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two software version numbers (e.g. "1.7.1" or "1.2b").
|
||||||
|
*
|
||||||
|
* @param {string} v1 The first version to be compared.
|
||||||
|
* @param {string} v2 The second version to be compared.
|
||||||
|
* @param {object} [options] Optional flags that affect comparison behavior:
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* <tt>lexicographical: true</tt> compares each part of the version strings lexicographically instead of
|
||||||
|
* naturally; this allows suffixes such as "b" or "dev" but will cause "1.10" to be considered smaller than
|
||||||
|
* "1.2".
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* <tt>zeroExtend: true</tt> changes the result if one version string has less parts than the other. In
|
||||||
|
* this case the shorter string will be padded with "zero" parts instead of being considered smaller.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* @returns {number|NaN}
|
||||||
|
* <ul>
|
||||||
|
* <li>0 if the versions are equal</li>
|
||||||
|
* <li>a negative integer iff v1 < v2</li>
|
||||||
|
* <li>a positive integer iff v1 > v2</li>
|
||||||
|
* <li>NaN if either version string is in the wrong format</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Utilities.compareVersions = function (v1, v2, options) {
|
||||||
|
var lexicographical = options && options.lexicographical,
|
||||||
|
zeroExtend = options && options.zeroExtend,
|
||||||
|
v1parts = v1.split('.'),
|
||||||
|
v2parts = v2.split('.');
|
||||||
|
|
||||||
|
function isValidPart(x) {
|
||||||
|
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
|
||||||
|
return NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zeroExtend) {
|
||||||
|
while (v1parts.length < v2parts.length) v1parts.push('0');
|
||||||
|
while (v2parts.length < v1parts.length) v2parts.push('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lexicographical) {
|
||||||
|
v1parts = v1parts.map(Number);
|
||||||
|
v2parts = v2parts.map(Number);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < v1parts.length; ++i) {
|
||||||
|
if (v2parts.length == i) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v1parts[i] == v2parts[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (v1parts[i] > v2parts[i]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v1parts.length != v2parts.length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
getBinDir = function () {
|
getBinDir = function () {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
return path.join(path.join(process.env.PWD, '..'), 'resources');
|
return path.join(path.join(process.env.PWD, '..'), 'resources');
|
||||||
|
|
|
@ -1,55 +1,168 @@
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var child_process = require('child_process');
|
var exec = require('exec');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
isVirtualBoxInstalled = function (callback) {
|
VirtualBox = {};
|
||||||
fs.exists('/usr/bin/VBoxManage', function (exists) {
|
|
||||||
callback(null, exists);
|
VirtualBox.REQUIRED_VERSION = '4.3.12';
|
||||||
|
VirtualBox.INCLUDED_VERSION = '4.3.12';
|
||||||
|
VirtualBox.INSTALLER_FILENAME = 'virtualbox-4.3.12.pkg';
|
||||||
|
|
||||||
|
// Info for the hostonly interface we add to the VM.
|
||||||
|
VirtualBox.HOSTONLY_HOSTIP = '192.168.60.3';
|
||||||
|
VirtualBox.HOSTONLY_NETWORKMASK = '255.255.255.0';
|
||||||
|
|
||||||
|
VirtualBox.installed = function () {
|
||||||
|
return fs.existsSync('/usr/bin/VBoxManage');
|
||||||
|
};
|
||||||
|
|
||||||
|
VirtualBox.exec = function (command, callback) {
|
||||||
|
exec('/usr/bin/VBoxManage ' + command, function (error, stdout, stderr) {
|
||||||
|
callback(error, stdout, stderr);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
isResolverSetup = function (callback) {
|
VirtualBox.install = function (callback) {
|
||||||
fs.readFile('/etc/resolver/dev', {
|
// -W waits for the process to close before finishing.
|
||||||
encoding: 'utf8'
|
exec('open -W ' + path.join(getBinDir(), this.INSTALLER_FILENAME), function (error, stdout, stderr) {
|
||||||
}, function (err, data) {
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualBox.version = function (callback) {
|
||||||
|
if (!this.installed()) {
|
||||||
|
callback('VirtualBox not installed.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.exec('-v', function (err, stdout, stderr) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, false);
|
callback(err);
|
||||||
} else {
|
return;
|
||||||
if (data.indexOf('nameserver 172.17.42.1') !== -1) {
|
}
|
||||||
callback(null, true);
|
// Output is x.x.xryyyyyy
|
||||||
} else {
|
var match = stdout.match(/(\d+\.\d+\.\d+).*/);
|
||||||
callback(null, false);
|
if (!match || match.length < 2) {
|
||||||
|
callback('VBoxManage -v output format not recognized.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(null, match[1]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
VirtualBox.hostOnlyIfs = function (callback) {
|
||||||
|
this.exec('list hostonlyifs', function (err, stdout, stderr) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var lines = stdout.split('\n');
|
||||||
|
var hostOnlyIfs = {};
|
||||||
|
var currentIf = null;
|
||||||
|
_.each(lines, function (line) {
|
||||||
|
if (!line.length) return;
|
||||||
|
var pieces = line.split(':');
|
||||||
|
var key = pieces[0].trim();
|
||||||
|
var value = pieces[1] ? pieces[1].trim() : null;
|
||||||
|
if (key === 'Name') {
|
||||||
|
currentIf = value;
|
||||||
|
hostOnlyIfs[value] = {};
|
||||||
}
|
}
|
||||||
}
|
hostOnlyIfs[currentIf][key] = value;
|
||||||
|
});
|
||||||
|
callback(null, hostOnlyIfs);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
setupResolver = function (callback) {
|
VirtualBox.hostOnlyAdapters = function (vm, callback) {
|
||||||
var installFile = path.join(getBinDir(), 'install');
|
this.exec('showvminfo ' + vm + ' --machinereadable', function (err, stdout, stderr) {
|
||||||
var cocoaSudo = path.join(getBinDir(), 'cocoasudo');
|
if (err) {
|
||||||
var execCommand = cocoaSudo + ' --prompt="Kitematic Setup wants to make changes. Type your password to allow this." ' + installFile;
|
callback(err);
|
||||||
child_process.exec(execCommand, function (error, stdout, stderr) {
|
|
||||||
console.log(stdout);
|
|
||||||
if (error) {
|
|
||||||
console.log(error);
|
|
||||||
callback(error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('Virtualbox Installation & Resolver config complete.');
|
var matches = stdout.match(/(hostonlyadapter\d+)="(vboxnet\d+)"/g);
|
||||||
callback();
|
if (!matches.length) {
|
||||||
|
callback(null, {});
|
||||||
|
} else {
|
||||||
|
var objs = {};
|
||||||
|
_.each(matches, function (match) {
|
||||||
|
var pieces = match.split('=');
|
||||||
|
objs[pieces[0]] = pieces[1].replace(/"/g, '');
|
||||||
|
});
|
||||||
|
callback(null, objs);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
setupVirtualBox = function (callback) {
|
VirtualBox.hostOnlyAdapter = function (callback) {
|
||||||
child_process.exec('open -W ' + path.join(getBinDir(), 'virtualbox-4.3.12.pkg'), function (error, stdout, stderr) {
|
var self = this;
|
||||||
console.log(stdout);
|
self.hostOnlyIfs(function (err, ifs) {
|
||||||
if (error) {
|
var iface = _.findWhere(_.toArray(ifs), {IPAddress: VirtualBox.HOSTONLY_HOSTIP});
|
||||||
console.log(error);
|
if (!iface) {
|
||||||
callback(error);
|
self.exec('hostonlyif create', function (err, stdout, stderr) {
|
||||||
|
var match = stdout.match(/Interface '(vboxnet\d+)' was successfully created/);
|
||||||
|
console.log(match);
|
||||||
|
if (!match) {
|
||||||
|
callback('Could not parse output of hostonlyif create');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.exec('hostonlyif ipconfig ' + match[1] + ' --ip ' + VirtualBox.HOSTONLY_HOSTIP + ' --netmask ' + VirtualBox.HOSTONLY_NETWORKMASK, function(err, stdout, stderr) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(null, match[1]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(null, iface.Name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
VirtualBox.addCustomHostAdapter = function (vm, callback) {
|
||||||
|
var self = this;
|
||||||
|
self.hostOnlyAdapter(function (err, ifname) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('Virtualbox Installation running.');
|
self.exec('modifyvm ' + vm + ' --nic3 hostonly --nictype3 virtio --cableconnected3 on --hostonlyadapter3 ' + ifname, function (err, stdout, stderr) {
|
||||||
callback();
|
callback(err, ifname);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VirtualBox.setupRouting = function (vm, callback) {
|
||||||
|
// Get the host only adapter or create it if it doesn't exist
|
||||||
|
this.addCustomHostAdapter(vm, function (err, ifname) {
|
||||||
|
var installFile = path.join(getBinDir(), 'install');
|
||||||
|
var cocoaSudo = path.join(getBinDir(), 'cocoasudo');
|
||||||
|
var execCommand = cocoaSudo + ' --prompt="Kitematic needs your password to allow routing *.dev requests to containers." ' + installFile;
|
||||||
|
exec(execCommand, {env: {IFNAME: ifname, GATEWAY: Boot2Docker.REQUIRED_IP}}, function (error, stdout, stderr) {
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
VirtualBox.removeDHCP = function (callback) {
|
||||||
|
var self = this;
|
||||||
|
self.hostOnlyAdapter(function (err, ifname) {
|
||||||
|
if (err) { callback(err); return; }
|
||||||
|
console.log(ifname);
|
||||||
|
self.exec('dhcpserver remove --ifname ' + ifname, function (err, stdout, stderr) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,19 +68,6 @@ Meteor.call('getDockerHost', function (err, host) {
|
||||||
Session.set('dockerHost', host);
|
Session.set('dockerHost', host);
|
||||||
});
|
});
|
||||||
|
|
||||||
updateBoot2DockerInfo = function () {
|
|
||||||
getBoot2DockerInfo(function (err, info) {
|
|
||||||
if (err) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Session.set('boot2dockerState', info.state);
|
|
||||||
if (info.state !== 'poweroff' && info.memory && info.disk) {
|
|
||||||
Session.set('boot2dockerMemoryUsage', info.memory);
|
|
||||||
Session.set('boot2dockerDiskUsage', info.disk);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
fixBoot2DockerVM = function (callback) {
|
fixBoot2DockerVM = function (callback) {
|
||||||
checkBoot2DockerVM(function (err) {
|
checkBoot2DockerVM(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -138,7 +125,24 @@ fixDefaultContainers = function (callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Meteor.setInterval(function () {
|
Meteor.setInterval(function () {
|
||||||
updateBoot2DockerInfo();
|
Boot2Docker.exists(function (err, exists) {
|
||||||
|
if (err) { return; }
|
||||||
|
if (exists) {
|
||||||
|
Boot2Docker.state(function (err, state) {
|
||||||
|
if (err) { return; }
|
||||||
|
if (state === 'running') {
|
||||||
|
Boot2Docker.info(function (err, info) {
|
||||||
|
if (err) { return; }
|
||||||
|
Session.set('boot2dockerState', info.state);
|
||||||
|
if (info.state !== 'poweroff' && info.memory && info.disk) {
|
||||||
|
Session.set('boot2dockerMemoryUsage', info.memory);
|
||||||
|
Session.set('boot2dockerDiskUsage', info.disk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
fixInterval = null;
|
fixInterval = null;
|
||||||
|
@ -148,7 +152,6 @@ startFixInterval = function () {
|
||||||
resolveWatchers(function () {});
|
resolveWatchers(function () {});
|
||||||
fixBoot2DockerVM(function (err) {
|
fixBoot2DockerVM(function (err) {
|
||||||
if (err) { console.log(err); return; }
|
if (err) { console.log(err); return; }
|
||||||
// Meteor.call('recoverApps');
|
|
||||||
fixDefaultImages(function (err) {
|
fixDefaultImages(function (err) {
|
||||||
if (err) { console.log(err); return; }
|
if (err) { console.log(err); return; }
|
||||||
fixDefaultContainers(function (err) {
|
fixDefaultContainers(function (err) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ Template.dashboard_settings.events({
|
||||||
var $btn = $(e.currentTarget);
|
var $btn = $(e.currentTarget);
|
||||||
$btn.html('Starting Boot2Docker...');
|
$btn.html('Starting Boot2Docker...');
|
||||||
$btn.attr("disabled", "disabled");
|
$btn.attr("disabled", "disabled");
|
||||||
startFixInterval();
|
//startFixInterval();
|
||||||
startBoot2Docker(function (err) {
|
startBoot2Docker(function (err) {
|
||||||
if (err) { console.error(err); }
|
if (err) { console.error(err); }
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,136 +1,8 @@
|
||||||
var async = require('async');
|
|
||||||
|
|
||||||
// Install steps. A step is a function that accepts a function (err) callback and returns once that step is complete.
|
|
||||||
// keys:
|
|
||||||
// - install: Function that runs the installation step and calls the callback with an error if failed.
|
|
||||||
// - pastMessage: Message to show after step completion
|
|
||||||
// - message: Message to show while step is running
|
|
||||||
// - imperativeMessage: Message to show before running
|
|
||||||
var steps = [
|
|
||||||
|
|
||||||
// Set up VirtualBox
|
|
||||||
{
|
|
||||||
install: function (callback) {
|
|
||||||
isVirtualBoxInstalled(function (err, virtualBoxInstalled) {
|
|
||||||
var installedYet = false;
|
|
||||||
if (!virtualBoxInstalled) {
|
|
||||||
setupVirtualBox(function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
pastMessage: 'VirtualBox installed',
|
|
||||||
message: 'Installing VirtualBox',
|
|
||||||
futureMessage: 'Install VirtualBox if necessary'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Set up the routing.
|
|
||||||
{
|
|
||||||
install: function (callback) {
|
|
||||||
setupResolver(function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
pastMessage: 'Container routing set up (root required).',
|
|
||||||
message: 'Setting up container routing (root required).',
|
|
||||||
subMessage: '(This may take a few minutes)',
|
|
||||||
futureMessage: 'Set up container routing to VM (root required).'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Set up the VM for running Kitematic apps
|
|
||||||
{
|
|
||||||
install: function (callback) {
|
|
||||||
console.log('Checking if vm exists...');
|
|
||||||
boot2DockerVMExists(function (err, exists) {
|
|
||||||
console.log('VM exists: ' + exists);
|
|
||||||
if (exists) {
|
|
||||||
console.log('Stopping vm');
|
|
||||||
stopBoot2Docker(function () {
|
|
||||||
console.log('Upgrading vm');
|
|
||||||
upgradeBoot2Docker(function () {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('init VM');
|
|
||||||
initBoot2Docker(function () {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
pastMessage: 'Set up the Kitematic VM',
|
|
||||||
message: 'Setting up the Kitematic VM...',
|
|
||||||
futureMessage: 'Set up the Kitematic VM'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Start the Kitematic VM
|
|
||||||
{
|
|
||||||
install: function (callback) {
|
|
||||||
startBoot2Docker(function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
pastMessage: 'Started the Kitematic VM',
|
|
||||||
message: 'Starting the Kitematic VM',
|
|
||||||
subMessage: '(This may take a few minutes)',
|
|
||||||
futureMessage: 'Start the Kitematic VM',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Set up the default Kitematic images
|
|
||||||
{
|
|
||||||
install: function (callback) {
|
|
||||||
Meteor.call('reloadDefaultContainers', function (err) {
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
pastMessage: 'Started the Kitematic VM',
|
|
||||||
message: 'Setting up the default Kitematic images...',
|
|
||||||
subMessage: '(This may take a few minutes)',
|
|
||||||
futureMessage: 'Set up the default Kitematic images',
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
runSetup = function (callback) {
|
|
||||||
// Run through the Kitematic installation, skipping steps if required.
|
|
||||||
var currentStep = 0;
|
|
||||||
Session.set('currentInstallStep', currentStep);
|
|
||||||
Session.set('numberOfInstallSteps', steps.length);
|
|
||||||
async.eachSeries(steps, function (step, callback) {
|
|
||||||
console.log('Performing step ' + currentStep);
|
|
||||||
step.install(function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
} else {
|
|
||||||
currentStep += 1;
|
|
||||||
Session.set('currentInstallStep', currentStep);
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
if (err) {
|
|
||||||
// if any of the steps fail
|
|
||||||
console.log('Kitematic setup failed at step ' + currentStep);
|
|
||||||
console.log(err);
|
|
||||||
Session.set('failedStep', currentStep);
|
|
||||||
Session.set('failedError', err);
|
|
||||||
callback(err);
|
|
||||||
} else {
|
|
||||||
// Setup Finished
|
|
||||||
console.log('Setup finished.');
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var installStarted = false;
|
var installStarted = false;
|
||||||
Template.setup_install.rendered = function() {
|
Template.setup_install.rendered = function() {
|
||||||
if(!installStarted) {
|
if(!installStarted) {
|
||||||
installStarted = true;
|
installStarted = true;
|
||||||
runSetup(function (err) {
|
Installer.run(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('Setup failed.');
|
console.log('Setup failed.');
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
@ -144,7 +16,7 @@ Template.setup_install.rendered = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Template.setup_install.steps = function () {
|
Template.setup_install.steps = function () {
|
||||||
return steps.map(function (step, index) {
|
return Installer.steps.map(function (step, index) {
|
||||||
step.index = index;
|
step.index = index;
|
||||||
return step;
|
return step;
|
||||||
});
|
});
|
||||||
|
@ -155,7 +27,7 @@ Template.setup_install.helpers({
|
||||||
return Session.get('currentInstallStep');
|
return Session.get('currentInstallStep');
|
||||||
},
|
},
|
||||||
installComplete: function () {
|
installComplete: function () {
|
||||||
return Session.get('currentInstallStep') === steps.length;
|
return Session.get('currentInstallStep') === Installer.steps.length;
|
||||||
},
|
},
|
||||||
failedStep: function () {
|
failedStep: function () {
|
||||||
return Session.get('failedStep');
|
return Session.get('failedStep');
|
||||||
|
|
|
@ -3,8 +3,8 @@ Docker = Meteor.require('dockerode');
|
||||||
var Convert = Meteor.require('ansi-to-html');
|
var Convert = Meteor.require('ansi-to-html');
|
||||||
var convert = new Convert();
|
var convert = new Convert();
|
||||||
|
|
||||||
var DOCKER_HOST='192.168.59.103';
|
var DOCKER_HOST='192.168.60.103';
|
||||||
docker = new Docker({host: '192.168.59.103', port: '2375'});
|
docker = new Docker({host: DOCKER_HOST, port: '2375'});
|
||||||
|
|
||||||
hasDockerfile = function (directory) {
|
hasDockerfile = function (directory) {
|
||||||
return fs.existsSync(path.join(directory, 'Dockerfile'));
|
return fs.existsSync(path.join(directory, 'Dockerfile'));
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Lookup the Kitematic VM resolver for .dev domains
|
# This script must be run as root and sets up Mac OS X to route all .dev domains to the virtual box VM with the name
|
||||||
|
# 'boot2docker-vm'. It does the following:
|
||||||
|
# 1) Adds a file under /etc/resolver/dev
|
||||||
|
# 2) Sets up a LaunchAgent for adding entries to the route table to route all requests to the Docker subnet (172.17.0.0/16)
|
||||||
|
# And expects the $IFNAME variable to contain the interface on which to send traffic to the boot2docker VM.
|
||||||
|
|
||||||
mkdir -p /etc/resolver
|
mkdir -p /etc/resolver
|
||||||
echo "nameserver 172.17.42.1" > /etc/resolver/dev
|
echo "nameserver 172.17.42.1" > /etc/resolver/dev
|
||||||
|
|
||||||
|
@ -8,10 +13,9 @@ DIR=$(dirname "$0")
|
||||||
USER=`w -h | sort -u -t' ' -k1,1 | awk '{print $1}'`
|
USER=`w -h | sort -u -t' ' -k1,1 | awk '{print $1}'`
|
||||||
|
|
||||||
/bin/rm -rf /Library/LaunchAgents/com.kitematic.route.plist
|
/bin/rm -rf /Library/LaunchAgents/com.kitematic.route.plist
|
||||||
|
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||||
echo '<?xml version="1.0" encoding="UTF-8"?>
|
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<plist version=\"1.0\">
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
<dict>
|
||||||
<key>Label</key>
|
<key>Label</key>
|
||||||
<string>com.kitematic.route</string>
|
<string>com.kitematic.route</string>
|
||||||
|
@ -20,26 +24,25 @@ echo '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<string>/sbin/route</string>
|
<string>/sbin/route</string>
|
||||||
<string>-n</string>
|
<string>-n</string>
|
||||||
<string>add</string>
|
<string>add</string>
|
||||||
<string>172.17.0.0/16</string>
|
<string>-net</string>
|
||||||
<string>192.168.59.103</string>
|
<string>172.17.0.0</string>
|
||||||
|
<string>-netmask</string>
|
||||||
|
<string>255.255.0.0</string>
|
||||||
|
<string>-iface</string>
|
||||||
|
<string>$IFNAME</string>
|
||||||
|
<string>255.255.0.0</string>
|
||||||
|
<string>-gateway</string>
|
||||||
|
<string>$GATEWAY</string>
|
||||||
</array>
|
</array>
|
||||||
<key>KeepAlive</key>
|
<key>KeepAlive</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>ServiceIPC</key>
|
|
||||||
<false/>
|
|
||||||
<key>UserName</key>
|
|
||||||
<string>root</string>
|
|
||||||
<key>LaunchOnlyOnce</key>
|
<key>LaunchOnlyOnce</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>' > /Library/LaunchAgents/com.kitematic.route.plist
|
</plist>" > /Library/LaunchAgents/com.kitematic.route.plist
|
||||||
|
|
||||||
sudo -u $USER $DIR/boot2docker init
|
|
||||||
VBoxManage modifyvm boot2docker-vm --nic2 hostonly --nictype2 virtio --cableconnected2 on --hostonlyadapter2 vboxnet0
|
|
||||||
VBoxManage dhcpserver add --netname=vboxnet0 --ip=192.168.59.99 --netmask=255.255.255.0 --lowerip=192.168.59.103 --upperip=192.168.59.103
|
|
||||||
|
|
||||||
# Add entries to routing table for Kitematic VM
|
# Add entries to routing table for Kitematic VM
|
||||||
/sbin/route delete 172.17.0.0/16 192.168.59.103
|
/sbin/route delete -net 172.17.0.0 -netmask 255.255.0.0 -gateway $GATEWAY
|
||||||
/sbin/route -n add 172.17.0.0/16 192.168.59.103
|
/sbin/route -n add -net 172.17.0.0 -netmask 255.255.0.0 -iface $IFNAME -gateway $GATEWAY
|
Loading…
Reference in New Issue