mirror of https://github.com/docker/docs.git
Merge branch 'master' into hub-button
This commit is contained in:
commit
53cf2b696b
|
@ -1,7 +1,7 @@
|
|||
[](https://travis-ci.org/kitematic/kitematic)
|
||||
[](https://coveralls.io/r/kitematic/kitematic?branch=master)
|
||||
[](https://www.bithound.io/github/kitematic/kitematic)
|
||||
[](https://gitter.im/kitematic/kitematic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
|
||||

|
||||
|
||||
|
@ -27,9 +27,9 @@ Please read through our [Contributing Guidelines](https://github.com/kitematic/k
|
|||
|
||||
## Community
|
||||
|
||||
- For questions on how to use Kitematic, see our [user forum](https://forums.docker.com/c/kitematic).
|
||||
- [](https://gitter.im/kitematic/kitematic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
- Ask questions on our [user forum](https://forums.docker.com/c/kitematic).
|
||||
- **#kitematic** on IRC. [Join the channel](http://webchat.freenode.net/?channels=%23kitematic&uio=d4).
|
||||
- Join the Kitematic [Gitter Channel](https://gitter.im/kitematic/kitematic)
|
||||
- Follow [@kitematic on Twitter](https://twitter.com/kitematic).
|
||||
- Read and subscribe to [the Kitematic Blog](http://blog.kitematic.com).
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ var ContainerHome = React.createClass({
|
|||
<ContainerHomePreview />
|
||||
</div>
|
||||
<div className="right">
|
||||
<ContainerHomeLogs/>
|
||||
<ContainerHomeLogs container={this.props.container}/>
|
||||
<ContainerHomeFolders container={this.props.container} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -138,7 +138,7 @@ var ContainerHome = React.createClass({
|
|||
<div className="details-panel home">
|
||||
<div className="content">
|
||||
<div className="left">
|
||||
<ContainerHomeLogs/>
|
||||
<ContainerHomeLogs container={this.props.container}/>
|
||||
</div>
|
||||
{right}
|
||||
</div>
|
||||
|
|
|
@ -6,51 +6,50 @@ var metrics = require('./Metrics');
|
|||
|
||||
var _prevBottom = 0;
|
||||
|
||||
var ContainerHomeLogs = React.createClass({
|
||||
mixins: [Router.State, Router.Navigation],
|
||||
module.exports = React.createClass({
|
||||
mixins: [Router.Navigation],
|
||||
getInitialState: function () {
|
||||
return {
|
||||
logs: []
|
||||
};
|
||||
},
|
||||
componentWillReceiveProps: function () {
|
||||
this.init();
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.init();
|
||||
LogStore.on(LogStore.SERVER_LOGS_EVENT, this.updateLogs);
|
||||
if (!this.props.container) {
|
||||
return;
|
||||
}
|
||||
this.update();
|
||||
this.scrollToBottom();
|
||||
LogStore.on(LogStore.SERVER_LOGS_EVENT, this.update);
|
||||
LogStore.fetch(this.props.container.Name);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
LogStore.removeListener(LogStore.SERVER_LOGS_EVENT, this.updateLogs);
|
||||
LogStore.detach(this.props.container.Name);
|
||||
LogStore.removeListener(LogStore.SERVER_LOGS_EVENT, this.update);
|
||||
},
|
||||
componentDidUpdate: function () {
|
||||
// Scroll logs to bottom
|
||||
this.scrollToBottom();
|
||||
},
|
||||
scrollToBottom: function () {
|
||||
var parent = $('.logs');
|
||||
if (parent.scrollTop() >= _prevBottom - 50) {
|
||||
parent.scrollTop(parent[0].scrollHeight - parent.height());
|
||||
}
|
||||
_prevBottom = parent[0].scrollHeight - parent.height();
|
||||
},
|
||||
init: function () {
|
||||
this.updateLogs();
|
||||
},
|
||||
updateLogs: function (name) {
|
||||
if (name && name !== this.getParams().name) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
logs: LogStore.logs(this.getParams().name)
|
||||
});
|
||||
},
|
||||
handleClickLogs: function () {
|
||||
metrics.track('Viewed Logs', {
|
||||
from: 'preview'
|
||||
});
|
||||
this.transitionTo('containerLogs', {name: this.getParams().name});
|
||||
this.transitionTo('containerLogs', {name: this.props.container.Name});
|
||||
},
|
||||
update: function () {
|
||||
this.setState({
|
||||
logs: LogStore.logs(this.props.container.Name)
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
var logs = this.state.logs.map(function (l, i) {
|
||||
return <p key={i} dangerouslySetInnerHTML={{__html: l}}></p>;
|
||||
return <span key={i} dangerouslySetInnerHTML={{__html: l}}></span>;
|
||||
});
|
||||
if (logs.length === 0) {
|
||||
logs = "No logs for this container.";
|
||||
|
@ -62,11 +61,8 @@ var ContainerHomeLogs = React.createClass({
|
|||
<div className="logs">
|
||||
{logs}
|
||||
</div>
|
||||
<div className="mini-logs-overlay" onClick={this.handleClickLogs}><span className="icon icon-scale-spread-1"></span><div className="text">View Logs</div></div>
|
||||
</div>
|
||||
<div className="mini-logs-overlay" onClick={this.handleClickLogs}><span className="icon icon-scale-spread-1"></span><div className="text">View Logs</div></div> </div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = ContainerHomeLogs;
|
||||
|
|
|
@ -1,49 +1,46 @@
|
|||
var $ = require('jquery');
|
||||
var React = require('react/addons');
|
||||
var LogStore = require('./LogStore');
|
||||
var Router = require('react-router');
|
||||
|
||||
var _prevBottom = 0;
|
||||
|
||||
var ContainerLogs = React.createClass({
|
||||
mixins: [Router.State],
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
logs: []
|
||||
};
|
||||
},
|
||||
componentWillReceiveProps: function () {
|
||||
this.init();
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.init();
|
||||
LogStore.on(LogStore.SERVER_LOGS_EVENT, this.updateLogs);
|
||||
if (!this.props.container) {
|
||||
return;
|
||||
}
|
||||
this.update();
|
||||
this.scrollToBottom();
|
||||
LogStore.on(LogStore.SERVER_LOGS_EVENT, this.update);
|
||||
LogStore.fetch(this.props.container.Name);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
LogStore.removeListener(LogStore.SERVER_LOGS_EVENT, this.updateLogs);
|
||||
LogStore.detach(this.props.container.Name);
|
||||
LogStore.removeListener(LogStore.SERVER_LOGS_EVENT, this.update);
|
||||
},
|
||||
componentDidUpdate: function () {
|
||||
// Scroll logs to bottom
|
||||
this.scrollToBottom();
|
||||
},
|
||||
scrollToBottom: function () {
|
||||
var parent = $('.details-logs');
|
||||
if (parent.scrollTop() >= _prevBottom - 50) {
|
||||
parent.scrollTop(parent[0].scrollHeight - parent.height());
|
||||
}
|
||||
_prevBottom = parent[0].scrollHeight - parent.height();
|
||||
},
|
||||
init: function () {
|
||||
this.updateLogs();
|
||||
},
|
||||
updateLogs: function (name) {
|
||||
if (name && name !== this.getParams().name) {
|
||||
return;
|
||||
}
|
||||
update: function () {
|
||||
this.setState({
|
||||
logs: LogStore.logs(this.getParams().name)
|
||||
logs: LogStore.logs(this.props.container.Name)
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
var logs = this.state.logs.map(function (l, i) {
|
||||
return <p key={i} dangerouslySetInnerHTML={{__html: l}}></p>;
|
||||
return <span key={i} dangerouslySetInnerHTML={{__html: l}}></span>;
|
||||
});
|
||||
if (logs.length === 0) {
|
||||
logs = "No logs for this container.";
|
||||
|
@ -55,5 +52,3 @@ var ContainerLogs = React.createClass({
|
|||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = ContainerLogs;
|
||||
|
|
|
@ -2,59 +2,77 @@ var EventEmitter = require('events').EventEmitter;
|
|||
var assign = require('object-assign');
|
||||
var Convert = require('ansi-to-html');
|
||||
var docker = require('./Docker');
|
||||
var stream = require('stream');
|
||||
|
||||
var _convert = new Convert();
|
||||
var _logs = {};
|
||||
var _streams = {};
|
||||
|
||||
var LogStore = assign(Object.create(EventEmitter.prototype), {
|
||||
var MAX_LOG_SIZE = 3000;
|
||||
|
||||
module.exports = assign(Object.create(EventEmitter.prototype), {
|
||||
SERVER_LOGS_EVENT: 'server_logs_event',
|
||||
_escapeHTML: function (html) {
|
||||
_escape: function (html) {
|
||||
var text = document.createTextNode(html);
|
||||
var div = document.createElement('div');
|
||||
div.appendChild(text);
|
||||
return div.innerHTML;
|
||||
},
|
||||
fetchLogs: function (name) {
|
||||
fetch: function (name) {
|
||||
if (!name || !docker.client()) {
|
||||
return;
|
||||
}
|
||||
var index = 0;
|
||||
var self = this;
|
||||
docker.client().getContainer(name).logs({
|
||||
follow: true,
|
||||
stdout: true,
|
||||
stderr: true,
|
||||
timestamps: true
|
||||
}, function (err, stream) {
|
||||
if (_streams[name]) {
|
||||
return;
|
||||
}
|
||||
_streams[name] = stream;
|
||||
timestamps: false,
|
||||
tail: MAX_LOG_SIZE,
|
||||
follow: false
|
||||
}, (err, logStream) => {
|
||||
if (err) {
|
||||
return;
|
||||
throw err;
|
||||
}
|
||||
_logs[name] = [];
|
||||
stream.setEncoding('utf8');
|
||||
stream.on('data', function (buf) {
|
||||
// Every other message is a header
|
||||
if (index % 2 === 1) {
|
||||
//var time = buf.substr(0,buf.indexOf(' '));
|
||||
var msg = buf.substr(buf.indexOf(' ')+1);
|
||||
_logs[name].push(_convert.toHtml(self._escapeHTML(msg)));
|
||||
self.emit(self.SERVER_LOGS_EVENT);
|
||||
}
|
||||
index += 1;
|
||||
var logs = [];
|
||||
logStream.setEncoding('utf-8');
|
||||
logStream.on('data', (chunk) => {
|
||||
logs.push(_convert.toHtml(this._escape(chunk)));
|
||||
});
|
||||
stream.on('end', function () {
|
||||
delete _streams[name];
|
||||
logStream.on('end', () => {
|
||||
_logs[name] = logs;
|
||||
this.emit(this.SERVER_LOGS_EVENT);
|
||||
this.attach(name);
|
||||
});
|
||||
});
|
||||
},
|
||||
logs: function (name) {
|
||||
if (!_streams[name]) {
|
||||
this.fetchLogs(name);
|
||||
attach: function (name) {
|
||||
if (!name || !docker.client() || _streams[name]) {
|
||||
return;
|
||||
}
|
||||
docker.client().getContainer(name).attach({
|
||||
stdout: true,
|
||||
stderr: true,
|
||||
logs: false,
|
||||
stream: true
|
||||
}, (err, logStream) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
logStream.setEncoding('utf-8');
|
||||
logStream.on('data', (chunk) => {
|
||||
_logs[name].push(_convert.toHtml(this._escape(chunk)));
|
||||
if (_logs[name].length > MAX_LOG_SIZE) {
|
||||
_logs[name] = _logs[name].slice(_logs[name].length - MAX_LOG_SIZE, MAX_LOG_SIZE);
|
||||
}
|
||||
this.emit(this.SERVER_LOGS_EVENT);
|
||||
});
|
||||
});
|
||||
},
|
||||
detach: function (name) {
|
||||
if (_streams[name]) {
|
||||
_streams[name].destroy();
|
||||
}
|
||||
},
|
||||
logs: function (name) {
|
||||
return _logs[name] || [];
|
||||
},
|
||||
rename: function (name, newName) {
|
||||
|
@ -63,5 +81,3 @@ var LogStore = assign(Object.create(EventEmitter.prototype), {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = LogStore;
|
||||
|
|
Loading…
Reference in New Issue