diff --git a/src/components/SelectMachine.react.js b/src/components/SelectMachine.react.js
new file mode 100644
index 00000000..08aee981
--- /dev/null
+++ b/src/components/SelectMachine.react.js
@@ -0,0 +1,85 @@
+import _ from 'underscore';
+import utils from '../utils/Util';
+import React from 'react/addons';
+import Router from 'react-router';
+import RetinaImage from 'react-retina-image';
+import metrics from '../utils/MetricsUtil';
+import {DropdownButton, MenuItem} from 'react-bootstrap';
+import machine from '../utils/DockerMachineUtil';
+import setupActions from '../actions/SetupActions';
+
+var Setup = React.createClass({
+ mixins: [Router.Navigation],
+
+ getInitialState: function () {
+ return {
+ currentEngine: localStorage.getItem('settings.vm.name') || 'VM Available',
+ machines: {}
+ };
+ },
+
+ componentDidMount: function () {
+ machine.list().then( machines => {
+ if (typeof machines.default === 'undefined') {
+ machines.default = {'driver': 'virtualbox', 'name': 'default', 'create': true};
+ }
+ this.setState({
+ machines: machines
+ });
+ });
+ },
+
+ handleChangeDockerEngine: function (machineIndex) {
+ localStorage.setItem('settings.vm', JSON.stringify(this.state.machines[machineIndex]));
+ if (this.state.currentEngine !== machineIndex) {
+ this.setState({
+ currentEngine: machineIndex
+ });
+ }
+ setupActions.retry(false);
+ },
+ render: function () {
+ let currentDriver = '';
+ let machineDropdown = (
);
+ if (!_.isEmpty(this.state.machines)) {
+ machineDropdown = React.addons.createFragment(_.mapObject(this.state.machines, (machineItem, index) => {
+ let menu = [];
+ let machineDriver = utils.camelCase(machineItem.driver);
+ let machineName = utils.camelCase(machineItem.name);
+ if (machineItem.create) {
+ machineName = 'Create ' + machineName;
+ }
+ if (currentDriver !== machineItem.driver) {
+ menu.push(
);
+ currentDriver = machine.driver;
+ }
+ menu.push(
);
+ return menu;
+ }));
+ }
+ return (
+
+
+
+
+
+
Select Docker VM
+
To run Docker containers on your computer, Kitematic needs Linux virtual machine.
+
+ {machineDropdown}
+
+
+
+
+
+ );
+ }
+});
+
+module.exports = Setup;
diff --git a/src/routes.js b/src/routes.js
index 824b5d70..a1001f10 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -1,5 +1,6 @@
import React from 'react/addons';
import Setup from './components/Setup.react';
+import SelectMachine from './components/SelectMachine.react';
import Account from './components/Account.react';
import AccountSignup from './components/AccountSignup.react';
import AccountLogin from './components/AccountLogin.react';
@@ -53,6 +54,7 @@ var routes = (
+
);
diff --git a/src/utils/DockerMachineUtil.js b/src/utils/DockerMachineUtil.js
index e342e7fc..bc173697 100644
--- a/src/utils/DockerMachineUtil.js
+++ b/src/utils/DockerMachineUtil.js
@@ -13,7 +13,10 @@ var DockerMachine = {
}
},
name: function () {
- return 'default';
+ return util.vmsettings().name || 'default';
+ },
+ driver: function () {
+ return util.vmsettings().driver || 'virtualbox';
},
installed: function () {
if (util.isWindows() && !process.env.DOCKER_TOOLBOX_INSTALL_PATH) {
@@ -34,6 +37,24 @@ var DockerMachine = {
return null;
}
},
+ list: function () {
+ return util.exec([this.command(), 'ls']).then(stdout => {
+ var lines = stdout.trim().split('\n').filter(line => line.indexOf('time=') === -1);
+ var machines = {};
+ lines.slice(1, lines.length).forEach(line => {
+ var tokens = line.trim().split(/[\s]+/).filter(token => token !== '*');
+ var machine = {
+ name: tokens[0],
+ active: tokens[1],
+ driver: tokens[2],
+ state: tokens[3],
+ url: tokens[4] || ''
+ };
+ machines[machine.name] = machine;
+ });
+ return Promise.resolve(machines);
+ });
+ },
exists: function (machineName = this.name()) {
return this.status(machineName).then(() => {
return true;
diff --git a/src/utils/SetupUtil.js b/src/utils/SetupUtil.js
index 25cdd8aa..a50366d0 100644
--- a/src/utils/SetupUtil.js
+++ b/src/utils/SetupUtil.js
@@ -26,6 +26,10 @@ export default {
});
},
+ resetProgress () {
+ setupServerActions.progress({progress: null});
+ },
+
clearTimers () {
_timers.forEach(t => clearTimeout(t));
_timers = [];
@@ -62,8 +66,20 @@ export default {
throw new Error('Docker Machine is not installed. Please install it via the Docker Toolbox.');
}
+ // Allow machine selection on initial launch
+ if (!localStorage.getItem('settings.vm')) {
+ router.get().transitionTo('selectmachine');
+ await this.pause();
+ }
+
setupServerActions.started({started: true});
- let exists = await virtualBox.vmExists(machine.name()) && fs.existsSync(path.join(util.home(), '.docker', 'machine', 'machines', machine.name()));
+
+ let exists = true;
+ // Check if we're dealing with a virtualbox machine
+ if (machine.driver() === 'virtualbox') {
+ exists = await virtualBox.vmExists(machine.name()) && fs.existsSync(path.join(util.home(), '.docker', 'machine', 'machines', machine.name()));
+ }
+
if (!exists) {
router.get().transitionTo('setup');
setupServerActions.started({started: true});
@@ -90,7 +106,6 @@ export default {
let tries = 80, ip = null;
while (!ip && tries > 0) {
try {
- console.log('Trying to fetch machine IP, tries left: ' + tries);
ip = await machine.ip();
tries -= 1;
await Promise.delay(1000);
diff --git a/src/utils/Util.js b/src/utils/Util.js
index 9950ca6e..0d86cedf 100644
--- a/src/utils/Util.js
+++ b/src/utils/Util.js
@@ -84,6 +84,9 @@ module.exports = {
} catch (err) {}
return settingsjson;
},
+ vmsettings: function () {
+ return JSON.parse(localStorage.getItem('settings.vm')) || null;
+ },
isOfficialRepo: function (name) {
if (!name || !name.length) {
return false;
@@ -143,6 +146,11 @@ module.exports = {
return 0;
},
+ camelCase: function (text) {
+ return text.toLowerCase().replace( /\b\w/g, function (m) {
+ return m.toUpperCase();
+ });
+ },
randomId: function () {
return crypto.randomBytes(32).toString('hex');
},