This commit is contained in:
Jeffrey Morgan 2015-02-26 20:14:43 -05:00
Родитель 25302cc1a9
Коммит b5bd6803d6
18 изменённых файлов: 172 добавлений и 196 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -9,7 +9,6 @@ npm-debug.log
identity
# Resources
resources/boot2docker-*
resources/docker-*
# Cache

Просмотреть файл

@ -1,29 +0,0 @@
jest.dontMock('../src/Boot2Docker');
var boot2docker = require('../src/Boot2Docker');
var fs = require('fs');
var util = require('../src/Util');
var Promise = require('bluebird');
describe('Boot2Docker', () => {
it('iso version parsed correctly', function () {
fs.readFileSync.mockReturnValueOnce('9adjaldijaslkjd123Boot2Docker-v1.4.1aisudhha82jj123');
expect(boot2docker.isoversion()).toBe('1.4.1');
});
pit('should exist if status command succeeds', function () {
util.exec.mockReturnValueOnce(Promise.resolve(true));
return boot2docker.exists().then(exists => {
expect(util.exec).toBeCalledWith([boot2docker.command(), 'status']);
expect(exists).toBe(true);
});
});
pit('should not exist if status command fails', function () {
util.exec.mockReturnValueOnce(Promise.reject(false));
return boot2docker.exists().then(exists => {
expect(util.exec).toBeCalledWith([boot2docker.command(), 'status']);
expect(exists).toBe(false);
});
});
});

Просмотреть файл

@ -2,7 +2,7 @@ jest.dontMock('../src/SetupStore');
var setupStore = require('../src/SetupStore');
var virtualBox = require('../src/VirtualBox');
var util = require('../src/Util');
var boot2docker = require('../src/Boot2Docker');
var machine = require('../src/DockerMachine');
var setupUtil = require('../src/SetupUtil');
var Promise = require('bluebird');
@ -12,6 +12,8 @@ describe('SetupStore', function () {
pit('downloads virtualbox if it is not installed', function () {
virtualBox.installed.mockReturnValue(false);
setupUtil.download.mockReturnValue(Promise.resolve());
util.packagejson.mockReturnValue({'virtualbox-filename': ''});
util.supportDir.mockReturnValue('');
return setupStore.steps().download.run().then(() => {
expect(setupUtil.download).toBeCalled();
});
@ -22,6 +24,8 @@ describe('SetupStore', function () {
virtualBox.version.mockReturnValue(Promise.resolve('4.3.16'));
setupUtil.compareVersions.mockReturnValue(-1);
setupUtil.download.mockReturnValue(Promise.resolve());
util.packagejson.mockReturnValue({'virtualbox-filename': ''});
util.supportDir.mockReturnValue('');
return setupStore.steps().download.run().then(() => {
expect(setupUtil.download).toBeCalled();
});
@ -30,8 +34,8 @@ describe('SetupStore', function () {
describe('install step', function () {
util.exec.mockReturnValue(Promise.resolve());
util.copyBinariesCmd.mockReturnValue('copycmd');
util.fixBinariesCmd.mockReturnValue('fixcmd');
setupUtil.copyBinariesCmd.mockReturnValue('copycmd');
setupUtil.fixBinariesCmd.mockReturnValue('fixcmd');
virtualBox.killall.mockReturnValue(Promise.resolve());
setupUtil.installVirtualBoxCmd.mockReturnValue('installvb');
setupUtil.macSudoCmd.mockImplementation(cmd => 'macsudo ' + cmd);
@ -69,35 +73,30 @@ describe('SetupStore', function () {
describe('init step', function () {
virtualBox.vmdestroy.mockReturnValue(Promise.resolve());
pit('inintializes the boot2docker vm if it does not exist', function () {
boot2docker.exists.mockReturnValue(Promise.resolve(false));
boot2docker.init.mockReturnValue(Promise.resolve());
machine.exists.mockReturnValue(Promise.resolve(false));
machine.create.mockReturnValue(Promise.resolve());
return setupStore.steps().init.run().then(() => {
expect(boot2docker.init).toBeCalled();
expect(machine.create).toBeCalled();
});
});
pit('upgrades the boot2docker vm if it exists and is out of date', function () {
boot2docker.exists.mockReturnValue(Promise.resolve(true));
boot2docker.isoversion.mockReturnValue('1.0');
boot2docker.haskeys.mockReturnValue(true);
boot2docker.stop.mockReturnValue(Promise.resolve());
boot2docker.upgrade.mockReturnValue(Promise.resolve());
pit('upgrades the vm if it exists and is out of date', function () {
machine.exists.mockReturnValue(Promise.resolve(true));
machine.state.mockReturnValue(Promise.resolve('Running'));
machine.isoversion.mockReturnValue('1.0');
machine.stop.mockReturnValue(Promise.resolve());
machine.start.mockReturnValue(Promise.resolve());
machine.upgrade.mockReturnValue(Promise.resolve());
setupUtil.compareVersions.mockReturnValue(-1);
return setupStore.steps().init.run().then(() => {
boot2docker.init.mockClear();
expect(boot2docker.init).not.toBeCalled();
expect(boot2docker.upgrade).toBeCalled();
});
});
});
describe('start step', function () {
pit('starts the boot2docker vm if it is not running', function () {
boot2docker.status.mockReturnValue(false);
boot2docker.waitstatus.mockReturnValue(Promise.resolve());
boot2docker.start.mockReturnValue(Promise.resolve());
return setupStore.steps().start.run().then(() => {
expect(boot2docker.start).toBeCalled();
machine.create.mockClear();
machine.upgrade.mockClear();
machine.stop.mockClear();
machine.start.mockClear();
return setupStore.steps().init.run(() => {}).then(() => {
expect(machine.create).not.toBeCalled();
expect(machine.stop).toBeCalled();
expect(machine.start).toBeCalled();
expect(machine.upgrade).toBeCalled();
});
});
});

Просмотреть файл

@ -26,7 +26,7 @@ var windowOptions = {
'min-height': 700,
resizable: true,
frame: false,
show: true
show: false
};
app.on('activate-with-no-open-windows', function () {
@ -45,7 +45,7 @@ app.on('ready', function() {
mainWindow.loadUrl(path.normalize('file://' + path.join(__dirname, '..', 'build/index.html')));
app.on('will-quit', function () {
if (saveVMOnQuit) {
exec('/usr/bin/VBoxManage controlvm boot2docker-vm savestate', function () {});
exec('/usr/bin/VBoxManage controlvm dev savestate', function () {});
}
});
}

Просмотреть файл

@ -30,9 +30,11 @@ settings.beta = isBeta;
var options = {
dev: process.argv.indexOf('release') === -1,
beta: isBeta,
filename: isBeta ? 'Kitematic (Beta).app' : 'Kitematic.app',
name: isBeta ? 'Kitematic (Beta)' : 'Kitematic',
icon: isBeta ? './util/kitematic-beta.icns' : './util/kitematic.icns'
appFilename: isBeta ? 'Kitematic (Beta).app' : 'Kitematic.app',
appName: isBeta ? 'Kitematic (Beta)' : 'Kitematic',
name: 'Kitematic',
icon: isBeta ? './util/kitematic-beta.icns' : './util/kitematic.icns',
bundle: 'com.kitemaic.app'
};
gulp.task('js', function () {
@ -46,14 +48,14 @@ gulp.task('js', function () {
.pipe(react())
.pipe(babel({blacklist: ['regenerator']}))
.pipe(gulpif(options.dev, sourcemaps.write('.')))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.appFilename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
});
gulp.task('images', function() {
return gulp.src('images/*')
.pipe(gulpif(options.dev, changed('./build')))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.appFilename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
});
@ -68,7 +70,7 @@ gulp.task('styles', function () {
.pipe(gulpif(options.dev, sourcemaps.init()))
.pipe(less())
.pipe(gulpif(options.dev, sourcemaps.write()))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.appFilename + '/Contents/Resources/app/build'))
.pipe(gulpif(!options.dev, cssmin()))
.pipe(concat('main.css'))
.pipe(gulpif(options.dev, livereload()));
@ -83,12 +85,12 @@ gulp.task('download', function (cb) {
gulp.task('copy', function () {
gulp.src('index.html')
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.appFilename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
gulp.src('fonts/**')
.pipe(gulpif(options.dev, changed('./build')))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.appFilename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
});
@ -112,10 +114,10 @@ gulp.task('dist', function () {
'/usr/libexec/PlistBuddy -c "Set :CFBundleExecutable <%= name %>" dist/osx/<%= filename %>/Contents/Info.plist'
], {
templateData: {
filename: options.filename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)'),
name: options.name.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)'),
filename: options.appFilename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)'),
name: options.appName.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)'),
version: packagejson.version,
bundle: 'com.kitematic.app',
bundle: options.bundle,
icon: options.icon
}
}));
@ -125,7 +127,7 @@ gulp.task('dist', function () {
'cp -R node_modules/' + d + ' dist/osx/<%= filename %>/Contents/Resources/app/node_modules/'
], {
templateData: {
filename: options.filename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)')
filename: options.appFilename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)')
}
}));
});
@ -137,7 +139,7 @@ gulp.task('sign', function () {
try {
var signing_identity = fs.readFileSync('./identity', 'utf8').trim();
return gulp.src('').pipe(shell([
'codesign --deep --force --verbose --sign "' + signing_identity + '" ' + options.filename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)')
'codesign --deep --force --verbose --sign "' + signing_identity + '" ' + options.appFilename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)')
], {
cwd: './dist/osx/'
}));
@ -148,7 +150,7 @@ gulp.task('sign', function () {
gulp.task('zip', function () {
return gulp.src('').pipe(shell([
'ditto -c -k --sequesterRsrc --keepParent ' + options.filename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)') + ' ' + options.name.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)') + '-' + packagejson.version + '.zip'
'ditto -c -k --sequesterRsrc --keepParent ' + options.appFilename.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)') + ' ' + options.name.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)') + '-' + packagejson.version + '.zip'
], {
cwd: './dist/osx/'
}));
@ -163,7 +165,7 @@ gulp.task('settings', function () {
};
return src;
};
string_src('settings.json', JSON.stringify(settings)).pipe(gulp.dest('dist/osx/' + options.filename.replace(' ', '\ ').replace('(','\(').replace(')','\)') + '/Contents/Resources/app'));
string_src('settings.json', JSON.stringify(settings)).pipe(gulp.dest('dist/osx/' + options.appFilename.replace(' ', '\ ').replace('(','\(').replace(')','\)') + '/Contents/Resources/app'));
});
gulp.task('release', function () {

Просмотреть файл

@ -47,43 +47,43 @@
"virtualbox-checksum": "4a7dff25bdeef0d112e16ac11bee6d52e856d36bb412aa75576036ba560082eb",
"virtualbox-required-version": "4.3.0",
"dependencies": {
"ansi-to-html": "0.2.0",
"ansi-to-html": "0.3.0",
"async": "^0.9.0",
"bluebird": "^2.9.6",
"bluebird": "^2.9.12",
"bugsnag-js": "^2.4.7",
"dockerode": "^2.0.7",
"exec": "0.1.2",
"exec": "0.2.0",
"jquery": "^2.1.3",
"minimist": "^1.1.0",
"mixpanel": "0.0.20",
"node-uuid": "^1.4.2",
"object-assign": "^2.0.0",
"react": "^0.12.2",
"react-bootstrap": "^0.13.2",
"react-bootstrap": "^0.15.1",
"react-retina-image": "^1.1.2",
"react-router": "^0.11.6",
"react-router": "^0.12.4",
"request": "^2.53.0",
"request-progress": "^0.3.1",
"rimraf": "^2.2.8",
"underscore": "^1.7.0"
"underscore": "^1.8.2"
},
"devDependencies": {
"babel": "^4.0.1",
"gulp": "^3.8.10",
"babel": "^4.5.5",
"gulp": "^3.8.11",
"gulp-babel": "^4.0.0",
"gulp-changed": "^1.1.1",
"gulp-concat": "^2.3.4",
"gulp-concat": "^2.5.2",
"gulp-cssmin": "^0.1.6",
"gulp-download-atom-shell": "0.0.4",
"gulp-if": "^1.2.4",
"gulp-less": "^2.0.1",
"gulp-livereload": "^2.1.1",
"gulp-if": "^1.2.5",
"gulp-less": "^3.0.1",
"gulp-livereload": "^3.8.0",
"gulp-plumber": "^0.6.6",
"gulp-react": "^2.0.0",
"gulp-shell": "^0.2.11",
"gulp-sourcemaps": "^1.2.8",
"gulp-util": "^3.0.0",
"jest-cli": "^0.2.2",
"gulp-shell": "^0.3.0",
"gulp-sourcemaps": "^1.5.0",
"gulp-util": "^3.0.4",
"jest-cli": "^0.4.0",
"jsxhint": "^0.12.1",
"react-tools": "^0.12.2",
"run-sequence": "^1.0.2"

Просмотреть файл

@ -6,7 +6,7 @@ var path = require('path');
var metrics = require('./Metrics');
var ContainerStore = require('./ContainerStore');
var ContainerUtil = require('./ContainerUtil');
var boot2docker = require('./Boot2Docker');
var machine = require('./DockerMachine');
var RetinaImage = require('react-retina-image');
var Router = require('react-router');
var webPorts = require('./Util').webPorts;
@ -105,11 +105,13 @@ var ContainerDetailsSubheader = React.createClass({
metrics.track('Terminaled Into Container');
var container = this.props.container;
var terminal = path.join(process.cwd(), 'resources', 'terminal');
var cmd = [terminal, boot2docker.command().replace(/ /g, '\\\\\\\\ ').replace(/\(/g, '\\\\\\\\(').replace(/\)/g, '\\\\\\\\)'), 'ssh', '-t', 'sudo', 'docker', 'exec', '-i', '-t', container.Name, 'sh'];
exec(cmd, function (stderr, stdout, code) {
if (code) {
console.log(stderr);
}
machine.ip().then(ip => {
var cmd = [terminal, 'ssh', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'LogLevel=quiet', '-o', 'StrictHostKeyChecking=no', '-i', '~/.docker/machine/machines/' + machine.name() + '/id_rsa', 'docker@' + ip, '-t', 'docker', 'exec', '-i', '-t', container.Name, 'sh'];
exec(cmd, function (stderr, stdout, code) {
if (code) {
console.log(stderr);
}
});
});
}
},

Просмотреть файл

@ -17,7 +17,7 @@ var ContainerUtil = {
return {};
}
var res = {};
var ip = docker.host;
var ip = docker.host();
_.each(container.NetworkSettings.Ports, function (value, key) {
var dockerPort = key.split('/')[0];
var localUrl = null;

Просмотреть файл

@ -9,8 +9,7 @@ var remote = require('remote');
var metrics = require('./Metrics');
var autoUpdater = remote.require('auto-updater');
var RetinaImage = require('react-retina-image');
var path = require('path');
var docker = require('./Docker');
var machine = require('./DockerMachine');
var util = require('./Util');
var Containers = React.createClass({
@ -94,14 +93,21 @@ var Containers = React.createClass({
ipc.send('command', 'application:quit-install');
},
handleClickPreferences: function () {
metrics.track('Opened Preferences', {
from: 'app'
});
this.transitionTo('preferences');
},
handleClickDockerTerminal: function () {
var terminal = path.join(process.cwd(), 'resources', 'terminal');
var cmd = [terminal, `DOCKER_HOST=${'tcp://' + docker.host + ':2376'} DOCKER_CERT_PATH=${path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.boot2docker/certs/boot2docker-vm')} DOCKER_TLS_VERIFY=1 $SHELL`];
util.exec(cmd).then(() => {});
metrics.track('Opened Docker Terminal', {
from: 'app'
});
machine.dockerTerminal();
},
handleClickReportIssue: function () {
metrics.track('Opened Issue Reporter', {
from: 'app'
});
util.exec(['open', 'https://github.com/kitematic/kitematic/issues/new']);
},
handleMouseEnterDockerTerminal: function () {

Просмотреть файл

@ -3,17 +3,20 @@ var path = require('path');
var dockerode = require('dockerode');
var Docker = {
host: null,
_host: null,
_client: null,
setHost: function(host) {
this.host = host;
var certDir = path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.boot2docker/certs/boot2docker-vm');
setup: function(url, name) {
var certDir = path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.docker/machine/machines', name);
if (!fs.existsSync(certDir)) {
return;
}
var ip = url.split(':')[1].replace('//', '');
var port = url.split(':')[2];
this._host = ip;
this._client = new dockerode({
host: host,
port: 2376,
protocol: 'https',
host: ip,
port: port,
ca: fs.readFileSync(path.join(certDir, 'ca.pem')),
cert: fs.readFileSync(path.join(certDir, 'cert.pem')),
key: fs.readFileSync(path.join(certDir, 'key.pem'))
@ -21,6 +24,9 @@ var Docker = {
},
client: function () {
return this._client;
},
host: function () {
return this._host;
}
};

Просмотреть файл

@ -11,6 +11,9 @@ var DockerMachine = {
command: function () {
return path.join(process.cwd(), 'resources', 'docker-machine-' + this.version());
},
name: function () {
return NAME;
},
version: function () {
try {
return JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'))['docker-machine-version'];
@ -33,18 +36,15 @@ var DockerMachine = {
},
info: function () {
return util.exec([DockerMachine.command(), 'ls']).then(stdout => {
var lines = stdout.split('\n').filter(line => line.indexOf('time=') === -1);
var lines = stdout.trim().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);
}
lines.slice(1, lines.length).forEach(line => {
var tokens = line.trim().split(/[\s]+/).filter(token => token !== '*');
var machine = {
name: tokens[0],
driver: tokens[1],
state: tokens[2].toLower(),
url: tokens[3]
state: tokens[2],
url: tokens[3] || ''
};
machines[machine.name] = machine;
});
@ -56,21 +56,15 @@ var DockerMachine = {
});
},
exists: function () {
return DockerMachine.info().then(info => {
if (info) {
return Promise.resolve(true);
} else {
return Promise.resolve(false);
}
});
},
status: function () {
DockerMachine.info().then(info => {
return info ? info.status : null;
return DockerMachine.info().then(() => {
return true;
}).catch(() => {
return false;
});
},
create: function () {
return util.exec([DockerMachine.command(), 'create', '-d', 'virtualbox', NAME]);
return util.exec([DockerMachine.command(), 'create', '-d', 'virtualbox', '--virtualbox-memory', '2048', NAME]);
},
start: function () {
return util.exec([DockerMachine.command(), 'start', NAME]);
@ -81,29 +75,21 @@ var DockerMachine = {
upgrade: function () {
return util.exec([DockerMachine.command(), 'upgrade', NAME]);
},
destroy: function () {
return util.exec([DockerMachine.command(), 'rm -f', NAME]);
rm: function () {
return util.exec([DockerMachine.command(), 'rm', '-f', NAME]);
},
ip: function () {
return util.exec([DockerMachine.command(), 'ip']).then(stdout => {
return Promise.resolve(stdout.trim().replace('\n', ''));
});
},
erase: function () {
return util.exec(['rm', '-rf', path.join(util.home(), 'VirtualBox\\ VMs/boot2docker-vm')]);
},
state: function () {
util.exec([DockerMachine.command(), 'info']).then(stdout => {
try {
var info = JSON.parse(stdout);
return Promise.resolve(info.State);
} catch (err) {
return Promise.reject(err);
}
return DockerMachine.info().then(info => {
return info ? info.state : null;
});
},
disk: function () {
return util.exec([Boot2Docker.command(), 'ssh', 'df']).then(stdout => {
return util.exec([DockerMachine.command(), 'ssh', NAME, 'df']).then(stdout => {
try {
var lines = stdout.split('\n');
var dataline = _.find(lines, function (line) {
@ -127,7 +113,7 @@ var DockerMachine = {
});
},
memory: function () {
return util.exec([this.command(), 'ssh', 'free -m']).then(stdout => {
return util.exec([this.command(), 'ssh', NAME, 'free -m']).then(stdout => {
try {
var lines = stdout.split('\n');
var dataline = _.find(lines, function (line) {
@ -154,28 +140,34 @@ var DockerMachine = {
},
stats: function () {
DockerMachine.state().then(state => {
if (state === 'poweroff') {
if (state === 'Stopped') {
return Promise.resolve({state: state});
}
var memory = DockerMachine.memory();
var disk = DockerMachine.disk();
return Promise.all([memory, disk]).spread((memory, disk) => {
return Promise.resolve({
state: state,
memory: memory,
disk: disk
});
});
});
},
waitstatus: Promise.coroutine(function* () {
waitWhileState: Promise.coroutine(function* (status) {
while (true) {
var current = yield DockerMachine.status();
var current = yield DockerMachine.state();
if (status !== current.trim()) {
return;
}
}
})
}),
dockerTerminal: function () {
var terminal = path.join(process.cwd(), 'resources', 'terminal');
this.info().then(machine => {
var cmd = [terminal, `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 $SHELL`];
util.exec(cmd).then(() => {});
});
},
};
module.exports = DockerMachine;

Просмотреть файл

@ -5,8 +5,8 @@ if (localStorage.getItem('settings.width') && localStorage.getItem('settings.hei
}
window.addEventListener('resize', function () {
localStorage.setItem('settings.width', window.innerWidth);
localStorage.setItem('settings.height', window.innerHeight);
localStorage.setItem('settings.width', window.outerWidth);
localStorage.setItem('settings.height', window.outerHeight);
});
require.main.paths.splice(0, 0, process.env.NODE_PATH);
@ -16,7 +16,7 @@ var fs = require('fs');
var path = require('path');
var docker = require('./Docker');
var router = require('./router');
var boot2docker = require('./boot2docker');
var machine = require('./DockerMachine');
var ContainerStore = require('./ContainerStore');
var SetupStore = require('./SetupStore');
var metrics = require('./Metrics');
@ -82,13 +82,14 @@ setInterval(function () {
}, 14400000);
router.run(Handler => React.render(<Handler/>, document.body));
SetupStore.run().then(boot2docker.ip).then(ip => {
docker.setHost(ip);
SetupStore.run().then(machine.info).then(machine => {
docker.setup(machine.url, machine.name);
ContainerStore.init(function (err) {
if (err) { console.log(err); }
router.transitionTo('containers');
});
}).catch(err => {
console.log(err);
console.log(err.stack);
bugsnag.notify(err);
});

Просмотреть файл

@ -1,10 +1,9 @@
var remote = require('remote');
var app = remote.require('app');
var path = require('path');
var docker = require('./Docker');
var router = require('./Router');
var util = require('./Util');
var metrics = require('./Metrics');
var machine = require('./DockerMachine');
// main.js
var MenuTemplate = [
@ -22,6 +21,9 @@ var MenuTemplate = [
label: 'Preferences',
accelerator: 'Command+,',
click: function () {
metrics.track('Opened Preferences', {
from: 'menu'
});
router.transitionTo('preferences');
}
},
@ -71,10 +73,10 @@ var MenuTemplate = [
label: 'Open Docker Terminal',
accelerator: 'Command+Shift+T',
click: function() {
metrics.track('Opened Docker Terminal');
var terminal = path.join(process.cwd(), 'resources', 'terminal');
var cmd = [terminal, `DOCKER_HOST=${'tcp://' + docker.host + ':2376'} DOCKER_CERT_PATH=${path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.boot2docker/certs/boot2docker-vm')} DOCKER_TLS_VERIFY=1 $SHELL`];
util.exec(cmd).then(() => {});
metrics.track('Opened Docker Terminal', {
from: 'menu'
});
machine.dockerTerminal();
}
},
]
@ -157,6 +159,9 @@ var MenuTemplate = [
{
label: 'Report an Issue...',
click: function () {
metrics.track('Opened Issue Reporter', {
from: 'menu'
});
util.exec(['open', 'https://github.com/kitematic/kitematic/issues/new']);
}
},

Просмотреть файл

@ -67,6 +67,12 @@ var _steps = [{
if (!exists) {
yield machine.create();
return;
} else if ((yield machine.state()) === 'Error') {
try {
yield machine.rm();
} catch (err) {}
yield machine.create();
return;
}
var isoversion = machine.isoversion();
@ -74,13 +80,7 @@ var _steps = [{
yield machine.stop();
yield machine.upgrade();
}
setupUtil.simulateProgress(this.seconds, progressCallback);
yield machine.waitstatus('saving');
var status = machine.status;
if (status !== 'running') {
return yield machine.start();
}
yield machine.start();
})
}];
@ -134,11 +134,11 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
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 machine.exists()) || !isoversion || setupUtil.compareVersions(isoversion, boot2docker.version()) < 0;
required.init = !(yield machine.exists()) || (yield machine.state()) !== 'Running' || !isoversion || setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0;
var exists = yield boot2docker.exists();
if (exists) {
this.steps().start.seconds = 13;
var exists = yield machine.exists();
if (exists && (yield machine.state()) !== 'Error') {
this.steps().init.seconds = 13;
}
_requiredSteps = _steps.filter(function (step) {
@ -151,7 +151,7 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
return Promise.resolve();
}
if (setupUtil.shouldUpdateBinaries()) {
return util.exec(util.copyBinariesCmd());
return util.exec(setupUtil.copyBinariesCmd());
}
return Promise.resolve();
},
@ -181,9 +181,10 @@ var SetupStore = assign(Object.create(EventEmitter.prototype), {
metrics.track('Setup Failed', {
step: step.name
});
console.log('Setup encountered an error.');
console.log(err);
if (err) {
console.log('Setup encountered an error.');
console.log(err);
console.log(err.stack);
_error = err;
this.emit(this.ERROR_EVENT);
} else {

Просмотреть файл

@ -25,6 +25,12 @@ var SetupUtil = {
}
return false;
},
copycmd: function (src, dest) {
return ['rm', '-f', dest, '&&', 'cp', src, dest];
},
escapePath: function (str) {
return str.replace(/ /g, '\\ ').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
},
shouldUpdateBinaries: function () {
var packagejson = util.packagejson();
return !fs.existsSync('/usr/local/bin/docker') ||
@ -33,12 +39,12 @@ var SetupUtil = {
this.checksum('/usr/local/bin/docker') !== this.checksum(path.join(util.resourceDir(), 'docker-' + packagejson['docker-version']));
},
copyBinariesCmd: function () {
var packagejson = this.packagejson();
var packagejson = util.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.apply(cmd, this.copycmd(this.escapePath(path.join(util.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'));
cmd.push.apply(cmd, this.copycmd(this.escapePath(path.join(util.resourceDir(), 'docker-' + packagejson['docker-version'])), '/usr/local/bin/docker'));
return cmd.join(' ');
},
fixBinariesCmd: function () {
@ -50,14 +56,14 @@ var SetupUtil = {
},
installVirtualBoxCmd: function () {
var packagejson = util.packagejson();
return `installer -pkg ${util.escapePath(path.join(util.supportDir(), packagejson['virtualbox-filename']))} -target /`;
return `installer -pkg ${this.escapePath(path.join(util.supportDir(), packagejson['virtualbox-filename']))} -target /`;
},
virtualBoxUrl: function () {
var packagejson = util.packagejson();
return `https://github.com/kitematic/virtualbox/releases/download/${packagejson['virtualbox-version']}/${packagejson['virtualbox-filename']}`;
},
macSudoCmd: function (cmd) {
return `${util.escapePath(path.join(util.resourceDir(), 'macsudo'))} -p "Kitematic requires administrative privileges to install." sh -c \"${cmd}\"`;
return `${this.escapePath(path.join(util.resourceDir(), 'macsudo'))} -p "Kitematic requires administrative privileges to install." sh -c \"${cmd}\"`;
},
simulateProgress: function (estimateSeconds, progress) {
var times = _.range(0, estimateSeconds * 1000, 200);

Просмотреть файл

@ -35,11 +35,5 @@ module.exports = {
packagejson: function () {
return JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
},
copycmd: function (src, dest) {
return ['rm', '-f', dest, '&&', 'cp', src, dest];
},
escapePath: function (str) {
return str.replace(/ /g, '\\ ').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
},
webPorts: ['80', '8000', '8080', '3000', '5000', '2368', '9200', '8983']
};

Просмотреть файл

@ -1,14 +1,8 @@
#!/bin/bash
<<<<<<< HEAD:deps
BASE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
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
=======
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BASE=$DIR/..
BOOT2DOCKER_CLI_VERSION=$(node -pe "JSON.parse(process.argv[1])['boot2docker-version']" "$(cat $BASE/package.json)")
BOOT2DOCKER_CLI_FILE=boot2docker-$BOOT2DOCKER_CLI_VERSION
>>>>>>> master:util/deps
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
@ -16,7 +10,7 @@ pushd $BASE/resources > /dev/null
if [ ! -f $DOCKER_MACHINE_CLI_FILE ]; then
echo "-----> Downloading Docker Machine CLI..."
rm -rf boot2docker-*
rm -rf docker-machine*
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

Просмотреть файл

@ -2,12 +2,10 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
sudo rm -f /usr/local/bin/docker
sudo rm -f /usr/local/bin/boot2docker
sudo rm -f /usr/local/bin/docker*
pkill VirtualBox
pkill VBox
rm -rf ~/Library/Application\ Support/Kitematic/
rm -rf ~/.boot2docker
rm -rf ~/VirtualBox\ VMs/boot2docker-vm
rm -rf ~/.docker
rm -rf ~/Library/VirtualBox/
$DIR/VirtualBox_Uninstall.tool