diff --git a/Gruntfile.js b/Gruntfile.js index 0b66b1426b..eba8dbb4b7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -3,9 +3,6 @@ var execFile = require('child_process').execFile; var packagejson = require('./package.json'); var electron = require('electron-prebuilt'); -var WINDOWS_DOCKER_MACHINE_URL = 'https://github.com/docker/machine/releases/download/v' + packagejson['docker-machine-version'] + '/docker-machine_windows-amd64.exe'; -var DARWIN_DOCKER_MACHINE_URL = 'https://github.com/docker/machine/releases/download/v' + packagejson['docker-machine-version'] + '/docker-machine_darwin-amd64'; - module.exports = function (grunt) { require('load-grunt-tasks')(grunt); var target = grunt.option('target') || 'development'; @@ -22,21 +19,6 @@ module.exports = function (grunt) { return match ? match[1] : null; }; - grunt.registerMultiTask('download-binary', 'Downloads binary unless version up to date', function () { - var target = grunt.task.current.target; - var done = this.async(); - var config = grunt.config('download-binary')[target]; - execFile(config.binary, ['--version'], function (err, stdout) { - var currentVersion = version(stdout); - if (!currentVersion || currentVersion !== version(config.version)) { - grunt.task.run('curl:' + target); - grunt.task.run('chmod'); - } - done(); - - }); - }); - var BASENAME = 'Kitematic'; var APPNAME = BASENAME; @@ -128,15 +110,6 @@ module.exports = function (grunt) { } }, - // docker binaries - 'download-binary': { - 'docker-machine': { - version: packagejson['docker-machine-version'], - binary: path.join('resources', 'docker-machine'), - download: 'curl:docker-machine' - } - }, - // images copy: { dev: { @@ -166,7 +139,7 @@ module.exports = function (grunt) { files: [{ expand: true, cwd: 'resources', - src: ['docker*', 'ssh.exe', 'OPENSSH_LICENSE', 'msys-*'], + src: ['ssh.exe', 'OPENSSH_LICENSE', 'msys-*'], dest: 'dist/' + BASENAME + '-win32-x64/resources/resources' }], options: { @@ -177,7 +150,7 @@ module.exports = function (grunt) { files: [{ expand: true, cwd: 'resources', - src: ['docker*', 'macsudo', 'terminal'], + src: ['terminal'], dest: '<%= OSX_FILENAME %>/Contents/Resources/resources/' }, { src: 'util/kitematic.icns', @@ -196,23 +169,6 @@ module.exports = function (grunt) { } }, - // download binaries - curl: { - 'docker-machine': { - src: process.platform === 'win32' ? WINDOWS_DOCKER_MACHINE_URL : DARWIN_DOCKER_MACHINE_URL, - dest: process.platform === 'win32' ? path.join('resources', 'docker-machine.exe') : path.join('resources', 'docker-machine') - } - }, - - chmod: { - binaries: { - options: { - mode: '755' - }, - src: ['resources/docker*'] - } - }, - // styles less: { options: { @@ -312,12 +268,12 @@ module.exports = function (grunt) { } }); - grunt.registerTask('default', ['download-binary', 'newer:babel', 'less', 'newer:copy:dev', 'shell:electron', 'watchChokidar']); + grunt.registerTask('default', ['newer:babel', 'less', 'newer:copy:dev', 'shell:electron', 'watchChokidar']); if (process.platform === 'win32') { - grunt.registerTask('release', ['clean:release', 'download-binary', 'babel', 'less', 'copy:dev', 'electron:windows', 'copy:windows', 'rcedit:exes', 'compress']); + grunt.registerTask('release', ['clean:release', 'babel', 'less', 'copy:dev', 'electron:windows', 'copy:windows', 'rcedit:exes', 'compress']); } else { - grunt.registerTask('release', ['clean:release', 'download-binary', 'babel', 'less', 'copy:dev', 'electron:osx', 'copy:osx', 'shell:sign', 'shell:zip']); + grunt.registerTask('release', ['clean:release', 'babel', 'less', 'copy:dev', 'electron:osx', 'copy:osx', 'shell:sign', 'shell:zip']); } process.on('SIGINT', function () { diff --git a/package.json b/package.json index cee1225168..3820f1cdae 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "lint": "jsxhint src" }, "license": "Apache-2.0", - "docker-machine-version": "0.4.1", "electron-version": "0.33.6", "dependencies": { "alt": "^0.16.2", diff --git a/resources/macsudo b/resources/macsudo deleted file mode 100755 index a34962b716..0000000000 Binary files a/resources/macsudo and /dev/null differ diff --git a/src/actions/SetupServerActions.js b/src/actions/SetupServerActions.js index 651773eb91..27742c8a32 100644 --- a/src/actions/SetupServerActions.js +++ b/src/actions/SetupServerActions.js @@ -4,7 +4,8 @@ class SetupServerActions { constructor () { this.generateActions( 'progress', - 'error' + 'error', + 'started' ); } } diff --git a/src/components/Setup.react.js b/src/components/Setup.react.js index 707193aa9e..eb44736a5b 100644 --- a/src/components/Setup.react.js +++ b/src/components/Setup.react.js @@ -3,10 +3,10 @@ import Router from 'react-router'; import Radial from './Radial.react.js'; import RetinaImage from 'react-retina-image'; import Header from './Header.react'; -import Util from '../utils/Util'; import metrics from '../utils/MetricsUtil'; import setupStore from '../stores/SetupStore'; import setupActions from '../actions/SetupActions'; +import shell from 'shell'; var Setup = React.createClass({ mixins: [Router.Navigation], @@ -32,10 +32,17 @@ var Setup = React.createClass({ }, handleErrorRemoveRetry: function () { - console.log('Deleting VM and trying again.'); + console.log('Deleting VM and trying again.' ); setupActions.retry(true); }, + handleToolBox: function () { + metrics.track('Getting toolbox', { + from: 'setup' + }); + shell.openExternal('https://www.docker.com/docker-toolbox'); + }, + renderContents: function () { return (
@@ -65,6 +72,7 @@ var Setup = React.createClass({
); }, + renderError: function () { return (
@@ -85,7 +93,7 @@ var Setup = React.createClass({

{this.state.error.message || this.state.error}

- + {this.state.started ? : }

diff --git a/src/stores/SetupStore.js b/src/stores/SetupStore.js index 89c340ba65..3d1c248b9a 100644 --- a/src/stores/SetupStore.js +++ b/src/stores/SetupStore.js @@ -6,16 +6,21 @@ class SetupStore { constructor () { this.bindActions(setupActions); this.bindActions(setupServerActions); - this.percent = 0; + this.started = false; + this.progress = null; this.error = null; } + started ({started}) { + this.setState({error: null, started}); + } + error ({error}) { - this.setState({error}); + this.setState({error, progress: null}); } progress ({progress}) { - this.setState({error: null, progress}); + this.setState({progress}); } } diff --git a/src/utils/DockerMachineUtil.js b/src/utils/DockerMachineUtil.js index f3764e0fca..4f23cef4e4 100644 --- a/src/utils/DockerMachineUtil.js +++ b/src/utils/DockerMachineUtil.js @@ -3,15 +3,24 @@ import path from 'path'; import Promise from 'bluebird'; import fs from 'fs'; import util from './Util'; -import resources from './ResourcesUtil'; var DockerMachine = { command: function () { - return resources.dockerMachine(); + if (util.isWindows()) { + return path.join(process.env.DOCKER_TOOLBOX_INSTALL_PATH, 'docker-machine.exe'); + } else { + return '/usr/local/bin/docker-machine'; + } }, name: function () { return 'default'; }, + installed: function () { + if (util.isWindows() && !process.env.DOCKER_TOOLBOX_INSTALL_PATH) { + return false; + } + return fs.existsSync(this.command()); + }, isoversion: function (machineName = this.name()) { try { var data = fs.readFileSync(path.join(util.home(), '.docker', 'machine', 'machines', machineName, 'boot2docker.iso'), 'utf8'); @@ -161,7 +170,7 @@ var DockerMachine = { } else { cmd = cmd || process.env.SHELL; this.info(machineName).then(machine => { - util.exec([resources.terminal(), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 ${cmd}`]).then(() => {}); + util.exec([path.join(process.env.RESOURCES_PATH, 'terminal'), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 ${cmd}`]).then(() => {}); }); } }, diff --git a/src/utils/ResourcesUtil.js b/src/utils/ResourcesUtil.js deleted file mode 100644 index 5fd652ef93..0000000000 --- a/src/utils/ResourcesUtil.js +++ /dev/null @@ -1,23 +0,0 @@ -import util from './Util'; -import path from 'path'; - -module.exports = { - resourceDir: function () { - return process.env.RESOURCES_PATH; - }, - macsudo: function () { - return path.join(this.resourceDir(), 'macsudo'); - }, - terminal: function () { - return path.join(this.resourceDir(), 'terminal'); - }, - docker: function () { - return path.join(this.resourceDir(), 'docker' + util.binsEnding()); - }, - dockerMachine: function () { - return path.join(this.resourceDir(), 'docker-machine' + util.binsEnding()); - }, - dockerCompose: function () { - return path.join(this.resourceDir(), 'docker-compose' + util.binsEnding()); - } -}; diff --git a/src/utils/SetupUtil.js b/src/utils/SetupUtil.js index 4f26be95b4..bf7c35b5a8 100644 --- a/src/utils/SetupUtil.js +++ b/src/utils/SetupUtil.js @@ -16,6 +16,7 @@ let _timers = []; export default { simulateProgress (estimateSeconds) { + this.clearTimers(); var times = _.range(0, estimateSeconds * 1000, 200); _.each(times, time => { var timer = setTimeout(() => { @@ -50,13 +51,19 @@ export default { metrics.track('Started Setup'); while (true) { try { - if (!util.isWindows() && !virtualBox.active()) { - await util.exec(setupUtil.macSudoCmd(util.escapePath('/Library/Application Support/VirtualBox/LaunchDaemons/VirtualBoxStartup.sh') + ' restart')); + setupServerActions.started({started: false}); + router.get().transitionTo('setup'); + if (!virtualBox.installed()) { + throw new Error('VirtualBox is not installed. Please install it via the Docker Toolbox.'); } - let exists = await virtualBox.vmExists(machine.name()); + if (!machine.installed()) { + throw new Error('Docker Machine is not installed. Please install it via the Docker Toolbox.'); + } + + setupServerActions.started({started: true}); + let exists = await virtualBox.vmExists(machine.name()) && fs.existsSync(path.join(util.home(), '.docker', 'machine', 'machines', machine.name())); if (!exists) { - router.get().transitionTo('setup'); this.simulateProgress(60); try { await machine.rm(); @@ -70,7 +77,7 @@ export default { this.simulateProgress(10); } else if (state === 'Stopped') { router.get().transitionTo('setup'); - this.simulateProgress(25) + this.simulateProgress(25); } await machine.start(); } diff --git a/src/utils/VirtualBoxUtil.js b/src/utils/VirtualBoxUtil.js index d5cb1ed996..28ba6a5f4d 100644 --- a/src/utils/VirtualBoxUtil.js +++ b/src/utils/VirtualBoxUtil.js @@ -5,7 +5,7 @@ import Promise from 'bluebird'; var VirtualBox = { command: function () { - if(util.isWindows()) { + if (util.isWindows()) { if (process.env.VBOX_MSI_INSTALL_PATH) { return path.join(process.env.VBOX_MSI_INSTALL_PATH, 'VBoxManage.exe'); } else { @@ -16,7 +16,7 @@ var VirtualBox = { } }, installed: function () { - if(util.isWindows()) { + if (util.isWindows()) { return (process.env.VBOX_MSI_INSTALL_PATH && fs.existsSync(path.join(process.env.VBOX_MSI_INSTALL_PATH, 'VBoxManage.exe'))) || (process.env.VBOX_INSTALL_PATH && fs.existsSync(path.join(process.env.VBOX_INSTALL_PATH, 'VBoxManage.exe'))); } else { @@ -38,20 +38,13 @@ var VirtualBox = { }); }, poweroffall: function () { - if (!this.installed()) { - return Promise.reject('VirtualBox not installed.'); - } return util.exec(this.command() + ' list runningvms | sed -E \'s/.*\\{(.*)\\}/\\1/\' | xargs -L1 -I {} ' + this.command() + ' controlvm {} poweroff'); }, mountSharedDir: function (vmName, pathName, hostPath) { - if (!this.installed()) { - return Promise.reject('VirtualBox not installed.'); - } - return util.exec([this.command(), 'sharedfolder', 'add', vmName, '--name', pathName, '--hostpath', hostPath, '--automount']); }, killall: function () { - if(util.isWindows()) { + if (util.isWindows()) { return this.poweroffall().then(() => { return util.exec(['powershell.exe', '\"get-process VBox* | stop-process\"']); }).catch(() => {});