diff --git a/package.json b/package.json index fcc00df32d..2fc733d444 100644 --- a/package.json +++ b/package.json @@ -65,12 +65,15 @@ "bugsnag-js": "^2.4.7", "classnames": "^1.2.0", "coveralls": "^2.11.2", + "deep-extend": "^0.4.0", "dockerode": "^2.1.1", "exec": "0.2.0", + "install": "^0.1.8", "jquery": "^2.1.3", "mixpanel": "0.2.0", "mkdirp": "^0.5.0", "node-uuid": "^1.4.3", + "npm": "^2.9.1", "object-assign": "^2.0.0", "parseUri": "^1.2.3-2", "react": "^0.13.1", diff --git a/src/actions/ContainerActions.js b/src/actions/ContainerActions.js index 07f75167e9..e5fd4e1dae 100644 --- a/src/actions/ContainerActions.js +++ b/src/actions/ContainerActions.js @@ -1,7 +1,7 @@ import alt from '../alt'; import dockerUtil from '../utils/DockerUtil'; -class ContainerServerActions { +class ContainerActions { start (name) { this.dispatch({name}); dockerUtil.start(name); @@ -12,7 +12,6 @@ class ContainerServerActions { dockerUtil.destroy(name); } - // TODO: don't require all container data for this method rename (name, newName) { this.dispatch({name, newName}); dockerUtil.rename(name, newName); @@ -24,7 +23,7 @@ class ContainerServerActions { } update (name, container) { - this.dispatch({container}); + this.dispatch({name, container}); dockerUtil.updateContainer(name, container); } @@ -37,4 +36,4 @@ class ContainerServerActions { } } -export default alt.createActions(ContainerServerActions); +export default alt.createActions(ContainerActions); diff --git a/src/actions/ContainerServerActions.js b/src/actions/ContainerServerActions.js index 3bc0d29ce6..bbbf9c82ff 100644 --- a/src/actions/ContainerServerActions.js +++ b/src/actions/ContainerServerActions.js @@ -8,9 +8,10 @@ class ContainerServerActions { 'destroyed', 'error', 'muted', - 'unmuted', - 'progress', 'pending', + 'progress', + 'started', + 'unmuted', 'updated', 'waiting' ); diff --git a/src/components/ContainerDetails.react.js b/src/components/ContainerDetails.react.js index 58cf2fb628..793de1cbd2 100644 --- a/src/components/ContainerDetails.react.js +++ b/src/components/ContainerDetails.react.js @@ -12,14 +12,19 @@ var ContainerDetails = React.createClass({ }, render: function () { + if (!this.props.container) { + return false; + } + let ports = containerUtil.ports(this.props.container); let defaultPort = _.find(_.keys(ports), port => { return util.webPorts.indexOf(port) !== -1; }); + return (
- +
); diff --git a/src/components/ContainerDetailsHeader.react.js b/src/components/ContainerDetailsHeader.react.js index abb2009645..adbf2d2326 100644 --- a/src/components/ContainerDetailsHeader.react.js +++ b/src/components/ContainerDetailsHeader.react.js @@ -7,7 +7,9 @@ var ContainerDetailsHeader = React.createClass({ return false; } - if (this.props.container.State.Running && !this.props.container.State.Paused && !this.props.container.State.ExitCode && !this.props.container.State.Restarting) { + if (this.props.container.State.Updating) { + state = UPDATING; + } else if (this.props.container.State.Running && !this.props.container.State.Paused && !this.props.container.State.ExitCode && !this.props.container.State.Restarting) { state = RUNNING; } else if (this.props.container.State.Restarting) { state = RESTARTING; diff --git a/src/components/ContainerDetailsSubheader.react.js b/src/components/ContainerDetailsSubheader.react.js index efce15965c..9b4cda575f 100644 --- a/src/components/ContainerDetailsSubheader.react.js +++ b/src/components/ContainerDetailsSubheader.react.js @@ -20,31 +20,31 @@ var ContainerDetailsSubheader = React.createClass({ if (!this.props.container) { return false; } - return (!this.props.container.State.Running || !this.props.defaultPort); + return (!this.props.container.State.Running || !this.props.defaultPort || this.props.container.State.Updating); }, disableRestart: function () { if (!this.props.container) { return false; } - return (this.props.container.State.Downloading || this.props.container.State.Restarting); + return (this.props.container.State.Downloading || this.props.container.State.Restarting || this.props.container.State.Updating); }, disableStop: function () { if (!this.props.container) { return false; } - return (this.props.container.State.Downloading || this.props.container.State.ExitCode || !this.props.container.State.Running); + return (this.props.container.State.Downloading || this.props.container.State.ExitCode || !this.props.container.State.Running || this.props.container.State.Updating); }, disableStart: function () { if (!this.props.container) { return false; } - return (this.props.container.State.Downloading || this.props.container.State.Running); + return (this.props.container.State.Downloading || this.props.container.State.Running || this.props.container.State.Updating); }, disableTerminal: function () { if (!this.props.container) { return false; } - return (!this.props.container.State.Running); + return (!this.props.container.State.Running || this.props.container.State.Updating); }, disableTab: function () { if (!this.props.container) { diff --git a/src/components/ContainerHome.react.js b/src/components/ContainerHome.react.js index 45ffec576b..08016322d1 100644 --- a/src/components/ContainerHome.react.js +++ b/src/components/ContainerHome.react.js @@ -35,12 +35,16 @@ var ContainerHome = React.createClass({ }, render: function () { + if (!this.props.container) { + return; + } + let body; - if (this.props.error) { + if (this.props.container.Error) { body = (

An error occurred:

-

{this.props.error.statusCode} {this.props.error.reason} - {this.props.error.json}

+

{this.props.container.Error.message}

If you feel that this error is invalid, please file a ticket on our GitHub repo.

diff --git a/src/components/ContainerHomeLogs.react.js b/src/components/ContainerHomeLogs.react.js index 40d3fede58..f8d7ac4570 100644 --- a/src/components/ContainerHomeLogs.react.js +++ b/src/components/ContainerHomeLogs.react.js @@ -22,6 +22,14 @@ module.exports = React.createClass({ LogStore.on(LogStore.SERVER_LOGS_EVENT, this.update); LogStore.fetch(this.props.container.Name); }, + + componentWillReceiveProps: function (nextProps) { + if (this.props.container && nextProps.container && this.props.container.Name !== nextProps.container.Name) { + LogStore.detach(this.props.container.Name); + LogStore.fetch(nextProps.container.Name); + } + }, + componentWillUnmount: function() { if (!this.props.container) { return; diff --git a/src/components/ContainerSettingsGeneral.react.js b/src/components/ContainerSettingsGeneral.react.js index f2a910e0ea..f07439bfbb 100644 --- a/src/components/ContainerSettingsGeneral.react.js +++ b/src/components/ContainerSettingsGeneral.react.js @@ -16,7 +16,6 @@ var ContainerSettingsGeneral = React.createClass({ getInitialState: function () { let env = ContainerUtil.env(this.props.container) || []; env.push(['', '']); - console.log(env); return { slugName: null, nameError: null, @@ -28,9 +27,7 @@ var ContainerSettingsGeneral = React.createClass({ if (nextState.slugName !== this.state.slugName || nextState.nameError !== this.state.nameError) { return true; } - if (nextState.env.length === this.state.env.length) { - return false; - } + return true; }, @@ -195,7 +192,7 @@ var ContainerSettingsGeneral = React.createClass({ } return ( -
); + return false; } - var self = this; - var volumes = _.map(self.props.container.Volumes, function (val, key) { + + var volumes = _.map(this.props.container.Volumes, (val, key) => { if (!val || val.indexOf(process.env.HOME) === -1) { val = ( No Folder - Change - Remove + Change + Remove ); } else { val = ( - {val.replace(process.env.HOME, '~')} - Change - Remove + {val.replace(process.env.HOME, '~')} + Change + Remove ); } diff --git a/src/components/Containers.react.js b/src/components/Containers.react.js index a5829d82ce..03319d7d20 100644 --- a/src/components/Containers.react.js +++ b/src/components/Containers.react.js @@ -195,7 +195,7 @@ var Containers = React.createClass({
- + ); diff --git a/src/stores/ContainerStore.js b/src/stores/ContainerStore.js index ddb8a9d676..d3b63099a0 100644 --- a/src/stores/ContainerStore.js +++ b/src/stores/ContainerStore.js @@ -1,4 +1,5 @@ import _ from 'underscore'; +import deepExtend from 'deep-extend'; import alt from '../alt'; import containerServerActions from '../actions/ContainerServerActions'; import containerActions from '../actions/ContainerActions'; @@ -9,13 +10,18 @@ class ContainerStore { this.bindActions(containerServerActions); this.containers = {}; - // Blacklist of containers to avoid updating - this.muted = {}; - // Pending container to create this.pending = null; } + error ({name, error}) { + let containers = this.containers; + if (containers[name]) { + containers[name].Error = error; + } + this.setState({containers}); + } + start ({name}) { let containers = this.containers; if (containers[name]) { @@ -24,6 +30,15 @@ class ContainerStore { } } + started ({name}) { + let containers = this.containers; + if (containers[name]) { + containers[name].State.Starting = false; + containers[name].State.Updating = false; + this.setState({containers}); + } + } + stop ({name}) { let containers = this.containers; if (containers[name]) { @@ -36,6 +51,11 @@ class ContainerStore { let containers = this.containers; let data = containers[name]; data.Name = newName; + + if (data.State) { + data.State.Updating = true; + } + containers[newName] = data; delete containers[name]; this.setState({containers}); @@ -44,23 +64,32 @@ class ContainerStore { added ({container}) { let containers = this.containers; containers[container.Name] = container; - delete this.muted[container.Name]; + this.setState({containers}); + } + + update ({name, container}) { + let containers = this.containers; + if (containers[name] && containers[name].State && containers[name].State.Updating) { + return; + } + + deepExtend(containers[name], container); + + if (containers[name].State) { + containers[name].State.Updating = true; + } + this.setState({containers}); } updated ({container}) { - if (this.muted[container.Name]) { + let containers = this.containers; + if (!containers[container.Name] || containers[container.Name].State.Updating) { return; } - let containers = this.containers; - if (!containers[container.Name]) { - return; - } containers[container.Name] = container; - if (container.State.Running) { - delete container.State.Starting; - } + this.setState({containers}); } @@ -87,20 +116,17 @@ class ContainerStore { let container = _.find(_.values(this.containers), container => { return container.Id === name || container.Name === name; }); - if (container && !this.muted[container.Name]) { + + if (container && container.State && container.State.Updating) { + return; + } + + if (container) { delete containers[container.Name]; this.setState({containers}); } } - muted ({name}) { - this.muted[name] = true; - } - - unmuted ({name}) { - this.muted[name] = false; - } - waiting({name, waiting}) { let containers = this.containers; if (containers[name]) { @@ -109,14 +135,6 @@ class ContainerStore { this.setState({containers}); } - error ({name, error}) { - let containers = this.containers; - if (containers[name]) { - containers[name].Error = error; - } - this.setState({containers}); - } - pending ({repo, tag}) { let pending = {repo, tag}; this.setState({pending}); @@ -127,10 +145,10 @@ class ContainerStore { } static generateName (repo) { - let base = _.last(repo.split('/')); - let count = 1; - let name = base; - let names = _.keys(this.getState().containers); + const base = _.last(repo.split('/')); + const names = _.keys(this.getState().containers); + var count = 1; + var name = base; while (true) { if (names.indexOf(name) === -1) { return name; diff --git a/src/utils/DockerUtil.js b/src/utils/DockerUtil.js index 99e925687d..a2f107d619 100644 --- a/src/utils/DockerUtil.js +++ b/src/utils/DockerUtil.js @@ -79,7 +79,7 @@ export default { containerServerActions.error({name, error}); return; } - containerServerActions.unmuted({name}); + containerServerActions.started({name, error}); this.fetchContainer(name); }); }, @@ -184,9 +184,6 @@ export default { updateContainer (name, data) { let existing = this.client.getContainer(name); existing.inspect((error, existingData) => { - if (error) { - return; - } if (error) { containerServerActions.error({name, error}); return; @@ -202,7 +199,6 @@ export default { } var fullData = _.extend(existingData, data); - containerServerActions.muted({name}); this.createContainer(name, fullData); }); }, @@ -213,7 +209,6 @@ export default { containerServerActions.error({name, error}); return; } - this.fetchAllContainers(); var oldPath = path.join(util.home(), 'Kitematic', name); var newPath = path.join(util.home(), 'Kitematic', newName); @@ -223,7 +218,6 @@ export default { containerServerActions.error({newName, error}); } rimraf(newPath, () => { - console.log('removed'); if (fs.existsSync(oldPath)) { fs.renameSync(oldPath, newPath); } @@ -295,9 +289,7 @@ export default { containerServerActions.destroyed({id: name}); var volumePath = path.join(util.home(), 'Kitematic', name); if (fs.existsSync(volumePath)) { - rimraf(volumePath, function (err) { - console.log(err); - }); + rimraf(volumePath, () => {}); } }); });