mirror of https://github.com/docker/docs.git
Merge pull request #223 from kitematic/bug-fixes
Better Setup checking, add remove VM button to setup
This commit is contained in:
commit
7b8d6be11c
|
@ -1,6 +1,7 @@
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var dockerode = require('dockerode');
|
var dockerode = require('dockerode');
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
|
||||||
var Docker = {
|
var Docker = {
|
||||||
_host: null,
|
_host: null,
|
||||||
|
@ -25,7 +26,34 @@ var Docker = {
|
||||||
},
|
},
|
||||||
host: function () {
|
host: function () {
|
||||||
return this._host;
|
return this._host;
|
||||||
}
|
},
|
||||||
|
waitForConnection: Promise.coroutine(function * (tries, delay) {
|
||||||
|
tries = tries || 5;
|
||||||
|
delay = delay || 1000;
|
||||||
|
var tryCount = 1;
|
||||||
|
while (true) {
|
||||||
|
console.log('Connecting: ' + tryCount + ' tries...');
|
||||||
|
try {
|
||||||
|
yield new Promise((resolve, reject) => {
|
||||||
|
this._client.listContainers((err) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
} catch (err) {
|
||||||
|
tryCount += 1;
|
||||||
|
yield Promise.delay(delay);
|
||||||
|
if (tryCount > tries) {
|
||||||
|
throw new Error(err);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Docker;
|
module.exports = Docker;
|
||||||
|
|
12
src/Main.js
12
src/Main.js
|
@ -83,20 +83,12 @@ setInterval(function () {
|
||||||
}, 14400000);
|
}, 14400000);
|
||||||
|
|
||||||
router.run(Handler => React.render(<Handler/>, document.body));
|
router.run(Handler => React.render(<Handler/>, document.body));
|
||||||
SetupStore.setup().then(ip => {
|
SetupStore.setup().then(() => {
|
||||||
docker.setup(ip, machine.name());
|
|
||||||
Menu.setApplicationMenu(Menu.buildFromTemplate(template()));
|
Menu.setApplicationMenu(Menu.buildFromTemplate(template()));
|
||||||
ContainerStore.on(ContainerStore.SERVER_ERROR_EVENT, (err) => {
|
ContainerStore.on(ContainerStore.SERVER_ERROR_EVENT, (err) => {
|
||||||
bugsnag.notify(err);
|
bugsnag.notify(err);
|
||||||
});
|
});
|
||||||
ContainerStore.init(function (err) {
|
ContainerStore.init(function () {
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
bugsnag.notify('ContainerStoreError', 'Could not init containerstore', {
|
|
||||||
error: err,
|
|
||||||
machine: machine
|
|
||||||
});
|
|
||||||
}
|
|
||||||
router.transitionTo('containers');
|
router.transitionTo('containers');
|
||||||
});
|
});
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
|
|
@ -6,7 +6,6 @@ var RetinaImage = require('react-retina-image');
|
||||||
var Header = require('./Header.react');
|
var Header = require('./Header.react');
|
||||||
var Util = require('./Util');
|
var Util = require('./Util');
|
||||||
var metrics = require('./Metrics');
|
var metrics = require('./Metrics');
|
||||||
var machine = require('./DockerMachine');
|
|
||||||
|
|
||||||
var Setup = React.createClass({
|
var Setup = React.createClass({
|
||||||
mixins: [ Router.Navigation ],
|
mixins: [ Router.Navigation ],
|
||||||
|
@ -14,7 +13,6 @@ var Setup = React.createClass({
|
||||||
return {
|
return {
|
||||||
progress: 0,
|
progress: 0,
|
||||||
name: '',
|
name: '',
|
||||||
retrying: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentWillMount: function () {
|
componentWillMount: function () {
|
||||||
|
@ -37,18 +35,18 @@ var Setup = React.createClass({
|
||||||
SetupStore.retry();
|
SetupStore.retry();
|
||||||
},
|
},
|
||||||
handleErrorRetry: function () {
|
handleErrorRetry: function () {
|
||||||
this.setState({
|
|
||||||
retrying: true
|
|
||||||
});
|
|
||||||
metrics.track('Setup Retried', {
|
metrics.track('Setup Retried', {
|
||||||
from: 'error'
|
from: 'error',
|
||||||
|
removeVM: false
|
||||||
});
|
});
|
||||||
machine.stop().finally(() => {
|
SetupStore.retry(false);
|
||||||
this.setState({
|
},
|
||||||
retrying: false
|
handleErrorRemoveRetry: function () {
|
||||||
});
|
metrics.track('Setup Retried', {
|
||||||
SetupStore.retry();
|
from: 'error',
|
||||||
|
removeVM: true
|
||||||
});
|
});
|
||||||
|
SetupStore.retry(true);
|
||||||
},
|
},
|
||||||
handleOpenWebsite: function () {
|
handleOpenWebsite: function () {
|
||||||
Util.exec(['open', 'https://www.virtualbox.org/wiki/Downloads']);
|
Util.exec(['open', 'https://www.virtualbox.org/wiki/Downloads']);
|
||||||
|
@ -128,7 +126,7 @@ var Setup = React.createClass({
|
||||||
<h1>We're Sorry!</h1>
|
<h1>We're Sorry!</h1>
|
||||||
<p>There seems to have been an unexpected error with Kitematic:</p>
|
<p>There seems to have been an unexpected error with Kitematic:</p>
|
||||||
<p className="error">{this.state.error.message || this.state.error}</p>
|
<p className="error">{this.state.error.message || this.state.error}</p>
|
||||||
<p><button className="btn btn-action" disabled={this.state.retrying} onClick={this.handleErrorRetry}>Retry Setup</button></p>
|
<p><button className="btn btn-action" onClick={this.handleErrorRetry}>Retry Setup</button> <button className="btn btn-action" onClick={this.handleErrorRemoveRetry}>Delete VM and Retry Setup</button></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,6 +11,7 @@ var assign = require('object-assign');
|
||||||
var metrics = require('./Metrics');
|
var metrics = require('./Metrics');
|
||||||
var bugsnag = require('bugsnag-js');
|
var bugsnag = require('bugsnag-js');
|
||||||
var rimraf = require('rimraf');
|
var rimraf = require('rimraf');
|
||||||
|
var docker = require('./Docker');
|
||||||
|
|
||||||
var _currentStep = null;
|
var _currentStep = null;
|
||||||
var _error = null;
|
var _error = null;
|
||||||
|
@ -118,12 +119,26 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
cancelled: function () {
|
cancelled: function () {
|
||||||
return _cancelled;
|
return _cancelled;
|
||||||
},
|
},
|
||||||
retry: function () {
|
retry: function (remove) {
|
||||||
_error = null;
|
_error = null;
|
||||||
_cancelled = false;
|
_cancelled = false;
|
||||||
if (_retryPromise) {
|
if (!_retryPromise) {
|
||||||
_retryPromise.resolve();
|
return;
|
||||||
}
|
}
|
||||||
|
this.emit(this.ERROR_EVENT);
|
||||||
|
if (remove) {
|
||||||
|
machine.rm().finally(() => {
|
||||||
|
_retryPromise.resolve();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
machine.stop().finally(() => {
|
||||||
|
_retryPromise.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setError: function (error) {
|
||||||
|
_error = error;
|
||||||
|
this.emit(this.ERROR_EVENT);
|
||||||
},
|
},
|
||||||
pause: function () {
|
pause: function () {
|
||||||
_retryPromise = Promise.defer();
|
_retryPromise = Promise.defer();
|
||||||
|
@ -207,6 +222,7 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
setup: Promise.coroutine(function * () {
|
setup: Promise.coroutine(function * () {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
|
console.log('Starting Steps');
|
||||||
var ip = yield this.run();
|
var ip = yield this.run();
|
||||||
if (!ip || !ip.length) {
|
if (!ip || !ip.length) {
|
||||||
throw {
|
throw {
|
||||||
|
@ -214,10 +230,13 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
machine: yield machine.info(),
|
machine: yield machine.info(),
|
||||||
ip: ip,
|
ip: ip,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
metrics.track('Setup Finished');
|
|
||||||
return ip;
|
|
||||||
}
|
}
|
||||||
|
console.log('Finished Steps');
|
||||||
|
console.log(ip);
|
||||||
|
docker.setup(ip, machine.name());
|
||||||
|
yield docker.waitForConnection();
|
||||||
|
metrics.track('Setup Finished');
|
||||||
|
break;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
metrics.track('Setup Failed', {
|
metrics.track('Setup Failed', {
|
||||||
step: _currentStep
|
step: _currentStep
|
||||||
|
@ -227,7 +246,7 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
error: err,
|
error: err,
|
||||||
step: _currentStep,
|
step: _currentStep,
|
||||||
virtualbox: virtualboxVersion
|
virtualbox: virtualboxVersion
|
||||||
});
|
}, 'info');
|
||||||
_error = err;
|
_error = err;
|
||||||
this.emit(this.ERROR_EVENT);
|
this.emit(this.ERROR_EVENT);
|
||||||
yield this.pause();
|
yield this.pause();
|
||||||
|
|
|
@ -17,11 +17,11 @@ var SetupUtil = {
|
||||||
return fs.statSync('/usr/local/bin').gid !== 80 || fs.statSync('/usr/local/bin').uid !== process.getuid();
|
return fs.statSync('/usr/local/bin').gid !== 80 || fs.statSync('/usr/local/bin').uid !== process.getuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.existsSync('/usr/local/bin/docker') && (fs.statSync('/usr/local/bin/docker').gid !== 80 || fs.statSync('/usr/local/bin/docker').uid !== process.getuid())) {
|
if (fs.statSync('/usr/local/bin/docker').gid !== 80 || fs.statSync('/usr/local/bin/docker').uid !== process.getuid()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.existsSync('/usr/local/bin/docker-machine') && (fs.statSync('/usr/local/bin/docker-machine').gid !== 80 || fs.statSync('/usr/local/bin/docker-machine').uid !== process.getuid())) {
|
if (fs.statSync('/usr/local/bin/docker-machine').gid !== 80 || fs.statSync('/usr/local/bin/docker-machine').uid !== process.getuid()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -11,7 +11,7 @@ module.exports = {
|
||||||
if (code) {
|
if (code) {
|
||||||
var cmd = Array.isArray(args) ? args.join(' ') : args;
|
var cmd = Array.isArray(args) ? args.join(' ') : args;
|
||||||
reject({
|
reject({
|
||||||
message: cmd.replace(this.home(), '') + ' returned non zero exit code',
|
message: cmd + ' returned non zero exit code',
|
||||||
stderr: stderr,
|
stderr: stderr,
|
||||||
stdout: stdout
|
stdout: stdout
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue