зеркало из https://github.com/docker/kitematic.git
Merge pull request #1155 from FrenchBen/1061-VM-name
Added selector for VM fixes #1061
This commit is contained in:
Коммит
6325b07b5c
|
@ -26,7 +26,8 @@ var Header = React.createClass({
|
||||||
document.addEventListener('keyup', this.handleDocumentKeyUp, false);
|
document.addEventListener('keyup', this.handleDocumentKeyUp, false);
|
||||||
|
|
||||||
accountStore.listen(this.update);
|
accountStore.listen(this.update);
|
||||||
|
// remove listener if exists
|
||||||
|
ipc.removeAllListeners('application:update-available');
|
||||||
ipc.on('application:update-available', () => {
|
ipc.on('application:update-available', () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
updateAvailable: true
|
updateAvailable: true
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import React from 'react/addons';
|
import React from 'react/addons';
|
||||||
import metrics from '../utils/MetricsUtil';
|
import metrics from '../utils/MetricsUtil';
|
||||||
import Router from 'react-router';
|
import Router from 'react-router';
|
||||||
|
import setupUtil from '../utils/SetupUtil';
|
||||||
|
import docker from '../utils/DockerUtil';
|
||||||
|
|
||||||
var Preferences = React.createClass({
|
var Preferences = React.createClass({
|
||||||
mixins: [Router.Navigation],
|
mixins: [Router.Navigation],
|
||||||
|
@ -14,6 +16,21 @@ var Preferences = React.createClass({
|
||||||
this.goBack();
|
this.goBack();
|
||||||
metrics.track('Went Back From Preferences');
|
metrics.track('Went Back From Preferences');
|
||||||
},
|
},
|
||||||
|
handleClearVMClick: function () {
|
||||||
|
localStorage.removeItem('settings.vm');
|
||||||
|
localStorage.removeItem('placeholders');
|
||||||
|
setupUtil.resetProgress();
|
||||||
|
setupUtil.setup().then(() => {
|
||||||
|
docker.init();
|
||||||
|
this.transitionTo('search');
|
||||||
|
}).catch(err => {
|
||||||
|
metrics.track('Setup Failed', {
|
||||||
|
step: 'catch',
|
||||||
|
message: err.message
|
||||||
|
});
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
},
|
||||||
handleChangeCloseVMOnQuit: function (e) {
|
handleChangeCloseVMOnQuit: function (e) {
|
||||||
var checked = e.target.checked;
|
var checked = e.target.checked;
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -48,6 +65,14 @@ var Preferences = React.createClass({
|
||||||
<input type="checkbox" checked={this.state.closeVMOnQuit} onChange={this.handleChangeCloseVMOnQuit}/>
|
<input type="checkbox" checked={this.state.closeVMOnQuit} onChange={this.handleChangeCloseVMOnQuit}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="option">
|
||||||
|
<div className="option-name">
|
||||||
|
Reset VM preferences
|
||||||
|
</div>
|
||||||
|
<div className="option-value">
|
||||||
|
<button className="btn btn-primary" onClick={this.handleClearVMClick}>Reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="title">App Settings</div>
|
<div className="title">App Settings</div>
|
||||||
<div className="option">
|
<div className="option">
|
||||||
<div className="option-name">
|
<div className="option-name">
|
||||||
|
|
|
@ -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 = (<div className="spinner la-ball-clip-rotate la-dark la-lg" style={{marginLeft: 30 + '%'}}><div></div></div>);
|
||||||
|
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(<MenuItem header>{machineDriver}</MenuItem>);
|
||||||
|
currentDriver = machine.driver;
|
||||||
|
}
|
||||||
|
menu.push(<MenuItem onSelect={this.handleChangeDockerEngine.bind(this, index)} key={index}>{machineName}</MenuItem>);
|
||||||
|
return menu;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="setup">
|
||||||
|
<div className="setup-content">
|
||||||
|
<div className="image">
|
||||||
|
<div className="contents">
|
||||||
|
<RetinaImage src="boot2docker.png" checkIfRetinaImgExists={false}/>
|
||||||
|
<div className="detail">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="desc">
|
||||||
|
<div className="content">
|
||||||
|
<h1>Select Docker VM</h1>
|
||||||
|
<p>To run Docker containers on your computer, Kitematic needs Linux virtual machine.</p>
|
||||||
|
<DropdownButton bsStyle="primary" title={this.state.currentEngine}>
|
||||||
|
{machineDropdown}
|
||||||
|
</DropdownButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = Setup;
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react/addons';
|
import React from 'react/addons';
|
||||||
import Setup from './components/Setup.react';
|
import Setup from './components/Setup.react';
|
||||||
|
import SelectMachine from './components/SelectMachine.react';
|
||||||
import Account from './components/Account.react';
|
import Account from './components/Account.react';
|
||||||
import AccountSignup from './components/AccountSignup.react';
|
import AccountSignup from './components/AccountSignup.react';
|
||||||
import AccountLogin from './components/AccountLogin.react';
|
import AccountLogin from './components/AccountLogin.react';
|
||||||
|
@ -53,6 +54,7 @@ var routes = (
|
||||||
</Route>
|
</Route>
|
||||||
<DefaultRoute name="loading" handler={Loading}/>
|
<DefaultRoute name="loading" handler={Loading}/>
|
||||||
<Route name="setup" handler={Setup}/>
|
<Route name="setup" handler={Setup}/>
|
||||||
|
<Route name="selectmachine" handler={SelectMachine}/>
|
||||||
</Route>
|
</Route>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,10 @@ var DockerMachine = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: function () {
|
name: function () {
|
||||||
return 'default';
|
return util.vmsettings().name || 'default';
|
||||||
|
},
|
||||||
|
driver: function () {
|
||||||
|
return util.vmsettings().driver || 'virtualbox';
|
||||||
},
|
},
|
||||||
installed: function () {
|
installed: function () {
|
||||||
if (util.isWindows() && !process.env.DOCKER_TOOLBOX_INSTALL_PATH) {
|
if (util.isWindows() && !process.env.DOCKER_TOOLBOX_INSTALL_PATH) {
|
||||||
|
@ -34,6 +37,24 @@ var DockerMachine = {
|
||||||
return null;
|
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()) {
|
exists: function (machineName = this.name()) {
|
||||||
return this.status(machineName).then(() => {
|
return this.status(machineName).then(() => {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -26,6 +26,10 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resetProgress () {
|
||||||
|
setupServerActions.progress({progress: null});
|
||||||
|
},
|
||||||
|
|
||||||
clearTimers () {
|
clearTimers () {
|
||||||
_timers.forEach(t => clearTimeout(t));
|
_timers.forEach(t => clearTimeout(t));
|
||||||
_timers = [];
|
_timers = [];
|
||||||
|
@ -62,8 +66,20 @@ export default {
|
||||||
throw new Error('Docker Machine is not installed. Please install it via the Docker Toolbox.');
|
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});
|
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) {
|
if (!exists) {
|
||||||
router.get().transitionTo('setup');
|
router.get().transitionTo('setup');
|
||||||
setupServerActions.started({started: true});
|
setupServerActions.started({started: true});
|
||||||
|
@ -90,7 +106,6 @@ export default {
|
||||||
let tries = 80, ip = null;
|
let tries = 80, ip = null;
|
||||||
while (!ip && tries > 0) {
|
while (!ip && tries > 0) {
|
||||||
try {
|
try {
|
||||||
console.log('Trying to fetch machine IP, tries left: ' + tries);
|
|
||||||
ip = await machine.ip();
|
ip = await machine.ip();
|
||||||
tries -= 1;
|
tries -= 1;
|
||||||
await Promise.delay(1000);
|
await Promise.delay(1000);
|
||||||
|
|
|
@ -84,6 +84,9 @@ module.exports = {
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
return settingsjson;
|
return settingsjson;
|
||||||
},
|
},
|
||||||
|
vmsettings: function () {
|
||||||
|
return JSON.parse(localStorage.getItem('settings.vm')) || null;
|
||||||
|
},
|
||||||
isOfficialRepo: function (name) {
|
isOfficialRepo: function (name) {
|
||||||
if (!name || !name.length) {
|
if (!name || !name.length) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -143,6 +146,11 @@ module.exports = {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
camelCase: function (text) {
|
||||||
|
return text.toLowerCase().replace( /\b\w/g, function (m) {
|
||||||
|
return m.toUpperCase();
|
||||||
|
});
|
||||||
|
},
|
||||||
randomId: function () {
|
randomId: function () {
|
||||||
return crypto.randomBytes(32).toString('hex');
|
return crypto.randomBytes(32).toString('hex');
|
||||||
},
|
},
|
||||||
|
|
Загрузка…
Ссылка в новой задаче