mirror of https://github.com/docker/docs.git
Merge pull request #340 from kitematic/fix-volumes
Fixes for various volume-related bugs
This commit is contained in:
commit
55f648354f
|
@ -2,19 +2,38 @@ var _ = require('underscore');
|
||||||
var React = require('react/addons');
|
var React = require('react/addons');
|
||||||
var RetinaImage = require('react-retina-image');
|
var RetinaImage = require('react-retina-image');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var exec = require('exec');
|
var shell = require('shell');
|
||||||
|
var util = require('./Util');
|
||||||
var metrics = require('./Metrics');
|
var metrics = require('./Metrics');
|
||||||
var Router = require('react-router');
|
var Router = require('react-router');
|
||||||
|
var ContainerStore = require('./ContainerStore');
|
||||||
|
|
||||||
var ContainerHomeFolder = React.createClass({
|
var ContainerHomeFolder = React.createClass({
|
||||||
mixins: [Router.State, Router.Navigation],
|
mixins: [Router.State, Router.Navigation],
|
||||||
handleClickFolder: function (path) {
|
handleClickFolder: function (hostVolume, containerVolume) {
|
||||||
metrics.track('Opened Volume Directory', {
|
metrics.track('Opened Volume Directory', {
|
||||||
from: 'home'
|
from: 'home'
|
||||||
});
|
});
|
||||||
exec(['open', path], function (err) {
|
|
||||||
if (err) { throw err; }
|
if (hostVolume.indexOf(process.env.HOME) === -1) {
|
||||||
|
var volumes = _.clone(this.props.container.Volumes);
|
||||||
|
var newHostVolume = path.join(util.home(), 'Kitematic', this.props.container.Name, containerVolume);
|
||||||
|
volumes[containerVolume] = newHostVolume;
|
||||||
|
var binds = _.pairs(volumes).map(function (pair) {
|
||||||
|
return pair[1] + ':' + pair[0];
|
||||||
});
|
});
|
||||||
|
ContainerStore.updateContainer(this.props.container.Name, {
|
||||||
|
Binds: binds
|
||||||
|
}, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shell.showItemInFolder(newHostVolume);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
shell.showItemInFolder(hostVolume);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleClickChangeFolders: function () {
|
handleClickChangeFolders: function () {
|
||||||
metrics.track('Viewed Volume Settings', {
|
metrics.track('Viewed Volume Settings', {
|
||||||
|
@ -23,24 +42,21 @@ var ContainerHomeFolder = React.createClass({
|
||||||
this.transitionTo('containerSettingsVolumes', {name: this.getParams().name});
|
this.transitionTo('containerSettingsVolumes', {name: this.getParams().name});
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var folders;
|
if (!this.props.container) {
|
||||||
if (this.props.container) {
|
return false;
|
||||||
var self = this;
|
}
|
||||||
folders = _.map(self.props.container.Volumes, function (val, key) {
|
|
||||||
|
var folders = _.map(this.props.container.Volumes, (val, key) => {
|
||||||
var firstFolder = key.split(path.sep)[1];
|
var firstFolder = key.split(path.sep)[1];
|
||||||
if (!val || val.indexOf(process.env.HOME) === -1) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return (
|
return (
|
||||||
<div key={key} className="folder" onClick={self.handleClickFolder.bind(self, val)}>
|
<div key={key} className="folder" onClick={this.handleClickFolder.bind(this, val, key)}>
|
||||||
<RetinaImage src="folder.png" />
|
<RetinaImage src="folder.png" />
|
||||||
<div className="text">{firstFolder}</div>
|
<div className="text">{firstFolder}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (this.props.container && this.props.container.Volumes && _.keys(this.props.container.Volumes).length > 0 && this.props.container.State.Running) {
|
if (this.props.container.Volumes && _.keys(this.props.container.Volumes).length > 0 && this.props.container.State.Running) {
|
||||||
return (
|
return (
|
||||||
<div className="folders wrapper">
|
<div className="folders wrapper">
|
||||||
<h4>Edit Files</h4>
|
<h4>Edit Files</h4>
|
||||||
|
@ -51,9 +67,7 @@ var ContainerHomeFolder = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return false;
|
||||||
<div></div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,6 +31,21 @@ var ContainerSettingsVolumes = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleRemoveVolumeClick: function (dockerVol) {
|
||||||
|
metrics.track('Removed Volume Directory', {
|
||||||
|
from: 'settings'
|
||||||
|
});
|
||||||
|
var volumes = _.clone(this.props.container.Volumes);
|
||||||
|
delete volumes[dockerVol];
|
||||||
|
var binds = _.pairs(volumes).map(function (pair) {
|
||||||
|
return pair[1] + ':' + pair[0];
|
||||||
|
});
|
||||||
|
ContainerStore.updateContainer(this.props.container.Name, {
|
||||||
|
Binds: binds
|
||||||
|
}, function (err) {
|
||||||
|
if (err) { console.log(err); }
|
||||||
|
});
|
||||||
|
},
|
||||||
handleOpenVolumeClick: function (path) {
|
handleOpenVolumeClick: function (path) {
|
||||||
metrics.track('Opened Volume Directory', {
|
metrics.track('Opened Volume Directory', {
|
||||||
from: 'settings'
|
from: 'settings'
|
||||||
|
@ -50,6 +65,7 @@ var ContainerSettingsVolumes = React.createClass({
|
||||||
<span>
|
<span>
|
||||||
<a className="value-right">No Folder</a>
|
<a className="value-right">No Folder</a>
|
||||||
<a className="btn btn-action small" onClick={self.handleChooseVolumeClick.bind(self, key)}>Change</a>
|
<a className="btn btn-action small" onClick={self.handleChooseVolumeClick.bind(self, key)}>Change</a>
|
||||||
|
<a className="btn btn-action small" onClick={self.handleRemoveVolumeClick.bind(self, key)}>Remove</a>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -57,6 +73,7 @@ var ContainerSettingsVolumes = React.createClass({
|
||||||
<span>
|
<span>
|
||||||
<a className="value-right" onClick={self.handleOpenVolumeClick.bind(self, val)}>{val.replace(process.env.HOME, '~')}</a>
|
<a className="value-right" onClick={self.handleOpenVolumeClick.bind(self, val)}>{val.replace(process.env.HOME, '~')}</a>
|
||||||
<a className="btn btn-action small" onClick={self.handleChooseVolumeClick.bind(self, key)}>Change</a>
|
<a className="btn btn-action small" onClick={self.handleChooseVolumeClick.bind(self, key)}>Change</a>
|
||||||
|
<a className="btn btn-action small" onClick={self.handleRemoveVolumeClick.bind(self, key)}>Remove</a>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var path = require('path');
|
|
||||||
var assign = require('object-assign');
|
var assign = require('object-assign');
|
||||||
var docker = require('./Docker');
|
var docker = require('./Docker');
|
||||||
var metrics = require('./Metrics');
|
var metrics = require('./Metrics');
|
||||||
var registry = require('./Registry');
|
var registry = require('./Registry');
|
||||||
var logstore = require('./LogStore');
|
var logstore = require('./LogStore');
|
||||||
var bugsnag = require('bugsnag-js');
|
var bugsnag = require('bugsnag-js');
|
||||||
var util = require('./Util');
|
|
||||||
|
|
||||||
var _placeholders = {};
|
var _placeholders = {};
|
||||||
var _containers = {};
|
var _containers = {};
|
||||||
|
@ -92,22 +90,7 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
},
|
},
|
||||||
_startContainer: function (name, containerData, callback) {
|
_startContainer: function (name, containerData, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
docker.client().getImage(containerData.Image).inspect(function (err, data) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var binds = containerData.Binds || [];
|
var binds = containerData.Binds || [];
|
||||||
if (data.Config.Volumes) {
|
|
||||||
_.each(data.Config.Volumes, function (value, key) {
|
|
||||||
var existingBind = _.find(binds, b => {
|
|
||||||
return b.indexOf(':' + key) !== -1;
|
|
||||||
});
|
|
||||||
if (!existingBind) {
|
|
||||||
binds.push(path.join(util.home(), 'Kitematic', name, key)+ ':' + key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var startopts = {
|
var startopts = {
|
||||||
Binds: binds
|
Binds: binds
|
||||||
};
|
};
|
||||||
|
@ -124,7 +107,6 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
}
|
}
|
||||||
self.fetchContainer(name, callback);
|
self.fetchContainer(name, callback);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
_createContainer: function (name, containerData, callback) {
|
_createContainer: function (name, containerData, callback) {
|
||||||
var existing = docker.client().getContainer(name);
|
var existing = docker.client().getContainer(name);
|
||||||
|
@ -137,6 +119,9 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
if (containerData.Config && containerData.Config.Image) {
|
if (containerData.Config && containerData.Config.Image) {
|
||||||
containerData.Image = containerData.Config.Image;
|
containerData.Image = containerData.Config.Image;
|
||||||
}
|
}
|
||||||
|
if (containerData.Config && containerData.Config.Env) {
|
||||||
|
containerData.Env = containerData.Config.Env;
|
||||||
|
}
|
||||||
existing.kill(function () {
|
existing.kill(function () {
|
||||||
existing.remove(function () {
|
existing.remove(function () {
|
||||||
docker.client().createContainer(containerData, function (err) {
|
docker.client().createContainer(containerData, function (err) {
|
||||||
|
@ -144,11 +129,7 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), {
|
||||||
callback(err, null);
|
callback(err, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (containerData.State && !containerData.State.Running) {
|
|
||||||
self.fetchContainer(containerData.name, callback);
|
|
||||||
} else {
|
|
||||||
self._startContainer(name, containerData, callback);
|
self._startContainer(name, containerData, callback);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue