diff --git a/deps b/deps index 9f44db32c3..f9c354caf3 100755 --- a/deps +++ b/deps @@ -1,17 +1,17 @@ #!/bin/bash BASE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -BOOT2DOCKER_CLI_VERSION=$(node -pe "JSON.parse(process.argv[1])['boot2docker-version']" "$(cat $BASE/package.json)") -BOOT2DOCKER_CLI_FILE=boot2docker-$BOOT2DOCKER_CLI_VERSION +DOCKER_MACHINE_CLI_VERSION=$(node -pe "JSON.parse(process.argv[1])['docker-machine-version']" "$(cat $BASE/package.json)") +DOCKER_MACHINE_CLI_FILE=docker-machine-$DOCKER_MACHINE_CLI_VERSION DOCKER_CLI_VERSION=$(node -pe "JSON.parse(process.argv[1])['docker-version']" "$(cat $BASE/package.json)") DOCKER_CLI_FILE=docker-$DOCKER_CLI_VERSION pushd $BASE/resources > /dev/null -if [ ! -f $BOOT2DOCKER_CLI_FILE ]; then - echo "-----> Downloading Boot2docker CLI..." +if [ ! -f $DOCKER_MACHINE_CLI_FILE ]; then + echo "-----> Downloading Docker Machine CLI..." rm -rf boot2docker-* - curl -L -o $BOOT2DOCKER_CLI_FILE https://github.com/boot2docker/boot2docker-cli/releases/download/v$BOOT2DOCKER_CLI_VERSION/boot2docker-v$BOOT2DOCKER_CLI_VERSION-darwin-amd64 - chmod +x $BOOT2DOCKER_CLI_FILE + curl -L -o $DOCKER_MACHINE_CLI_FILE https://github.com/docker/machine/releases/download/v$DOCKER_MACHINE_CLI_VERSION/docker-machine_darwin-amd64 + chmod +x $DOCKER_MACHINE_CLI_FILE fi if [ ! -f $DOCKER_CLI_FILE ]; then diff --git a/gulpfile.js b/gulpfile.js index e1efcc3c8c..f6d5ac806a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -172,7 +172,7 @@ gulp.task('release', function () { gulp.task('default', ['download', 'copy', 'js', 'images', 'styles'], function () { livereload.listen(); - gulp.watch('src/**/*.js', ['js', function () {livereload();}]); + gulp.watch('src/**/*.js', ['js']); gulp.watch('index.html', ['copy']); gulp.watch('styles/**/*.less', ['styles']); gulp.watch('images/**', ['images']); diff --git a/package.json b/package.json index a899b9bd9c..6da4d35fec 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,8 @@ ] }, "docker-version": "1.5.0", - "boot2docker-version": "1.5.0", - "atom-shell-version": "0.21.1", + "docker-machine-version": "0.1.0", + "atom-shell-version": "0.21.2", "virtualbox-version": "4.3.22", "virtualbox-filename": "VirtualBox-4.3.22.pkg", "virtualbox-checksum": "4a7dff25bdeef0d112e16ac11bee6d52e856d36bb412aa75576036ba560082eb", diff --git a/src/Boot2Docker.js b/src/DockerMachine.js similarity index 62% rename from src/Boot2Docker.js rename to src/DockerMachine.js index f643cf8d51..5de9c9ae5e 100644 --- a/src/Boot2Docker.js +++ b/src/DockerMachine.js @@ -5,20 +5,22 @@ var _ = require('underscore'); var fs = require('fs'); var util = require('./Util'); -var Boot2Docker = { +var NAME = 'dev'; + +var DockerMachine = { command: function () { - return path.join(process.cwd(), 'resources', 'boot2docker-' + this.version()); + return path.join(process.cwd(), 'resources', 'docker-machine-' + this.version()); }, version: function () { try { - return JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'))['boot2docker-version']; + return JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'))['docker-machine-version']; } catch (err) { return null; } }, isoversion: function () { try { - var data = fs.readFileSync(path.join(util.home(), '.boot2docker', 'boot2docker.iso'), 'utf8'); + var data = fs.readFileSync(path.join(util.home(), '.docker', 'machine', 'cache', 'boot2docker.iso'), 'utf8'); var match = data.match(/Boot2Docker-v(\d+\.\d+\.\d+)/); if (match) { return match[1]; @@ -29,35 +31,61 @@ var Boot2Docker = { return null; } }, + info: function () { + return util.exec([DockerMachine.command(), 'ls']).then(stdout => { + var lines = stdout.split('\n').filter(line => line.indexOf('time=') === -1); + var machines = {}; + lines.slice(1, lines.length - 1).forEach(line => { + var tokens = line.trim().split(/[\s]+/); + if (tokens.length === 5) { + tokens.splice(1, 1); + } + var machine = { + name: tokens[0], + driver: tokens[1], + state: tokens[2].toLower(), + url: tokens[3] + }; + machines[machine.name] = machine; + }); + if (machines[NAME]) { + return machines[NAME]; + } else { + throw new Error('Machine does not exist.'); + } + }); + }, exists: function () { - return util.exec([Boot2Docker.command(), 'status']).then(() => { - return Promise.resolve(true); - }).catch(() => { - return Promise.resolve(false); + return DockerMachine.info().then(info => { + if (info) { + return Promise.resolve(true); + } else { + return Promise.resolve(false); + } }); }, status: function () { - return util.exec([Boot2Docker.command(), 'status']).then(stdout => { - return Promise.resolve(stdout.trim()); + DockerMachine.info().then(info => { + return info ? info.status : null; }); }, - init: function () { - return util.exec([Boot2Docker.command(), 'init']); + create: function () { + return util.exec([DockerMachine.command(), 'create', '-d', 'virtualbox', NAME]); }, start: function () { - return util.exec([Boot2Docker.command(), 'start']); + return util.exec([DockerMachine.command(), 'start', NAME]); }, stop: function () { - return util.exec([Boot2Docker.command(), 'stop']); + return util.exec([DockerMachine.command(), 'stop', NAME]); }, upgrade: function () { - return util.exec([Boot2Docker.command(), 'upgrade']); + return util.exec([DockerMachine.command(), 'upgrade', NAME]); }, destroy: function () { - return util.exec([Boot2Docker.command(), 'destroy']); + return util.exec([DockerMachine.command(), 'rm -f', NAME]); }, ip: function () { - return util.exec([Boot2Docker.command(), 'ip']).then(stdout => { + return util.exec([DockerMachine.command(), 'ip']).then(stdout => { return Promise.resolve(stdout.trim().replace('\n', '')); }); }, @@ -65,7 +93,7 @@ var Boot2Docker = { return util.exec(['rm', '-rf', path.join(util.home(), 'VirtualBox\\ VMs/boot2docker-vm')]); }, state: function () { - util.exec([Boot2Docker.command(), 'info']).then(stdout => { + util.exec([DockerMachine.command(), 'info']).then(stdout => { try { var info = JSON.parse(stdout); return Promise.resolve(info.State); @@ -125,12 +153,12 @@ var Boot2Docker = { }); }, stats: function () { - Boot2Docker.state().then(state => { + DockerMachine.state().then(state => { if (state === 'poweroff') { return Promise.resolve({state: state}); } - var memory = Boot2Docker.memory(); - var disk = Boot2Docker.disk(); + var memory = DockerMachine.memory(); + var disk = DockerMachine.disk(); return Promise.all([memory, disk]).spread((memory, disk) => { return Promise.resolve({ state: state, @@ -140,12 +168,9 @@ var Boot2Docker = { }); }); }, - haskeys: function () { - return fs.existsSync(path.join(util.home(), '.ssh', 'id_boot2docker')); - }, waitstatus: Promise.coroutine(function* () { while (true) { - var current = yield Boot2Docker.status(); + var current = yield DockerMachine.status(); if (status !== current.trim()) { return; } @@ -153,4 +178,4 @@ var Boot2Docker = { }) }; -module.exports = Boot2Docker; +module.exports = DockerMachine; diff --git a/src/SetupStore.js b/src/SetupStore.js index 497e8f191f..d9520d60f9 100644 --- a/src/SetupStore.js +++ b/src/SetupStore.js @@ -3,7 +3,7 @@ var _ = require('underscore'); var path = require('path'); var fs = require('fs'); var Promise = require('bluebird'); -var boot2docker = require('./Boot2Docker'); +var machine = require('./DockerMachine'); var virtualBox = require('./VirtualBox'); var setupUtil = require('./SetupUtil'); var util = require('./Util'); @@ -37,7 +37,7 @@ var _steps = [{ seconds: 5, run: Promise.coroutine(function* (progressCallback) { var packagejson = util.packagejson(); - var cmd = util.copyBinariesCmd() + ' && ' + util.fixBinariesCmd(); + var cmd = setupUtil.copyBinariesCmd() + ' && ' + setupUtil.fixBinariesCmd(); if (!virtualBox.installed() || setupUtil.compareVersions(yield virtualBox.version(), packagejson['virtualbox-required-version']) < 0) { yield virtualBox.killall(); cmd += ' && ' + setupUtil.installVirtualBoxCmd(); @@ -55,45 +55,33 @@ var _steps = [{ }) }, { name: 'init', - title: 'Setting up Docker VM', - message: 'To run Docker containers on your computer, we are setting up a Linux virtual machine provided by boot2docker.', - totalPercent: 15, + title: 'Starting Docker VM', + message: 'To run Docker containers on your computer, starting a Linux virutal machine. This may take a minute..', + totalPercent: 60, percent: 0, - seconds: 11, + seconds: 46, run: Promise.coroutine(function* (progressCallback) { setupUtil.simulateProgress(this.seconds, progressCallback); yield virtualBox.vmdestroy('kitematic-vm'); - var exists = yield boot2docker.exists(); + var exists = yield machine.exists(); if (!exists) { - yield boot2docker.init(); + yield machine.create(); return; } - if (!boot2docker.haskeys()) { - throw new Error('Boot2Docker SSH keys do not exist. Fix this by removing the existing Boot2Docker VM setup and re-run the installer. This usually occurs because an old version of Boot2Docker is installed.'); + var isoversion = machine.isoversion(); + if (!isoversion || setupUtil.compareVersions(isoversion, machine.version()) < 0) { + yield machine.stop(); + yield machine.upgrade(); } - var isoversion = boot2docker.isoversion(); - if (!isoversion || setupUtil.compareVersions(isoversion, boot2docker.version()) < 0) { - yield boot2docker.stop(); - yield boot2docker.upgrade(); + setupUtil.simulateProgress(this.seconds, progressCallback); + yield machine.waitstatus('saving'); + var status = machine.status; + if (status !== 'running') { + return yield machine.start(); } }) -}, { - name: 'start', - title: 'Starting Docker VM', - message: "Kitematic is starting the boot2docker VM. This may take about a minute.", - totalPercent: 45, - percent: 0, - seconds: 35, - run: function (progressCallback) { - setupUtil.simulateProgress(this.seconds, progressCallback); - return boot2docker.waitstatus('saving').then(boot2docker.status).then(status => { - if (status !== 'running') { - return boot2docker.start(); - } - }); - } }]; var SetupStore = assign(Object.create(EventEmitter.prototype), { @@ -140,14 +128,13 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), { return Promise.resolve(_requiredSteps); } var packagejson = util.packagejson(); - var isoversion = boot2docker.isoversion(); + var isoversion = machine.isoversion(); var required = {}; var vboxfile = path.join(util.supportDir(), packagejson['virtualbox-filename']); var vboxInstallRequired = virtualBox.installed() ? setupUtil.compareVersions(yield virtualBox.version(), packagejson['virtualbox-required-version']) < 0 : true; required.download = vboxInstallRequired && (!fs.existsSync(vboxfile) || setupUtil.checksum(vboxfile) !== packagejson['virtualbox-checksum']); required.install = vboxInstallRequired || setupUtil.needsBinaryFix(); - required.init = !(yield boot2docker.exists()) || !isoversion || setupUtil.compareVersions(isoversion, boot2docker.version()) < 0; - required.start = required.install || required.init || (yield boot2docker.status()) !== 'running'; + required.init = !(yield machine.exists()) || !isoversion || setupUtil.compareVersions(isoversion, boot2docker.version()) < 0; var exists = yield boot2docker.exists(); if (exists) { diff --git a/src/SetupUtil.js b/src/SetupUtil.js index 5598ecaa01..302d574b67 100644 --- a/src/SetupUtil.js +++ b/src/SetupUtil.js @@ -12,7 +12,7 @@ var SetupUtil = { if (!fs.existsSync('/usr/local') || !fs.existsSync('/usr/local/bin')) { return true; } - if (!fs.existsSync('/usr/local/bin/docker') && !fs.existsSync('/usr/local/bin/boot2docker')) { + if (!fs.existsSync('/usr/local/bin/docker') && !fs.existsSync('/usr/local/bin/docker-machine')) { return fs.statSync('/usr/local/bin').gid !== 80 || fs.statSync('/usr/local/bin').uid !== process.getuid(); } @@ -20,7 +20,7 @@ var SetupUtil = { return true; } - if (fs.existsSync('/usr/local/bin/boot2docker') && (fs.statSync('/usr/local/bin/boot2docker').gid !== 80 || fs.statSync('/usr/local/bin/boot2docker').uid !== process.getuid())) { + 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())) { return true; } return false; @@ -28,10 +28,26 @@ var SetupUtil = { shouldUpdateBinaries: function () { var packagejson = util.packagejson(); return !fs.existsSync('/usr/local/bin/docker') || - !fs.existsSync('/usr/local/bin/boot2docker') || - this.checksum('/usr/local/bin/boot2docker') !== this.checksum(path.join(util.resourceDir(), 'boot2docker-' + packagejson['boot2docker-version'])) || + !fs.existsSync('/usr/local/bin/docker-machine') || + this.checksum('/usr/local/bin/docker-machine') !== this.checksum(path.join(util.resourceDir(), 'docker-machine-' + packagejson['docker-machine-version'])) || this.checksum('/usr/local/bin/docker') !== this.checksum(path.join(util.resourceDir(), 'docker-' + packagejson['docker-version'])); }, + copyBinariesCmd: function () { + var packagejson = this.packagejson(); + var cmd = ['mkdir', '-p', '/usr/local/bin']; + cmd.push('&&'); + cmd.push.apply(cmd, this.copycmd(this.escapePath(path.join(this.resourceDir(), 'docker-machine-' + packagejson['docker-machine-version'])), '/usr/local/bin/docker-machine')); + cmd.push('&&'); + cmd.push.apply(cmd, this.copycmd(this.escapePath(path.join(this.resourceDir(), 'docker-' + packagejson['docker-version'])), '/usr/local/bin/docker')); + return cmd.join(' '); + }, + fixBinariesCmd: function () { + var cmd = []; + cmd.push.apply(cmd, ['chown', `${process.getuid()}:${80}`, this.escapePath(path.join('/usr/local/bin', 'docker-machine'))]); + cmd.push('&&'); + cmd.push.apply(cmd, ['chown', `${process.getuid()}:${80}`, this.escapePath(path.join('/usr/local/bin', 'docker'))]); + return cmd.join(' '); + }, installVirtualBoxCmd: function () { var packagejson = util.packagejson(); return `installer -pkg ${util.escapePath(path.join(util.supportDir(), packagejson['virtualbox-filename']))} -target /`; diff --git a/src/Util.js b/src/Util.js index 9d47e5b921..d27b5bce53 100644 --- a/src/Util.js +++ b/src/Util.js @@ -38,22 +38,6 @@ module.exports = { copycmd: function (src, dest) { return ['rm', '-f', dest, '&&', 'cp', src, dest]; }, - copyBinariesCmd: function () { - var packagejson = this.packagejson(); - var cmd = ['mkdir', '-p', '/usr/local/bin']; - cmd.push('&&'); - cmd.push.apply(cmd, this.copycmd(this.escapePath(path.join(this.resourceDir(), 'boot2docker-' + packagejson['boot2docker-version'])), '/usr/local/bin/boot2docker')); - cmd.push('&&'); - cmd.push.apply(cmd, this.copycmd(this.escapePath(path.join(this.resourceDir(), 'docker-' + packagejson['docker-version'])), '/usr/local/bin/docker')); - return cmd.join(' '); - }, - fixBinariesCmd: function () { - var cmd = []; - cmd.push.apply(cmd, ['chown', `${process.getuid()}:${80}`, this.escapePath(path.join('/usr/local/bin', 'boot2docker'))]); - cmd.push('&&'); - cmd.push.apply(cmd, ['chown', `${process.getuid()}:${80}`, this.escapePath(path.join('/usr/local/bin', 'docker'))]); - return cmd.join(' '); - }, escapePath: function (str) { return str.replace(/ /g, '\\ ').replace(/\(/g, '\\(').replace(/\)/g, '\\)'); }