Merge pull request #985 from moxiegirl/rebase-docs

Rebase docs
This commit is contained in:
Jeffrey Morgan 2015-08-27 14:28:32 -07:00
commit 54d4ff1400
72 changed files with 734 additions and 656 deletions

View File

@ -1,15 +1,10 @@
var path = require('path');
var fs = require('fs');
var execFile = require('child_process').execFile;
var packagejson = require('./package.json');
var electron = require('electron-prebuilt');
var WINDOWS_DOCKER_URL = 'https://get.docker.com/builds/Windows/x86_64/docker-' + packagejson['docker-version'] + '.exe';
var DARWIN_DOCKER_URL = 'https://get.docker.com/builds/Darwin/x86_64/docker-' + packagejson['docker-version'];
var WINDOWS_DOCKER_MACHINE_URL = 'https://github.com/docker/machine/releases/download/v' + packagejson['docker-machine-version'] + '/docker-machine_windows-amd64.exe';
var DARWIN_DOCKER_MACHINE_URL = 'https://github.com/docker/machine/releases/download/v' + packagejson['docker-machine-version'] + '/docker-machine_darwin-amd64';
var DARWIN_COMPOSE_URL = 'https://github.com/docker/compose/releases/download/' + packagejson['docker-compose-version'] + '/docker-compose-Darwin-x86_64';
var BOOT2DOCKER_ISO_URL = 'https://github.com/boot2docker/boot2docker/releases/download/v' + packagejson['docker-version'] + '/boot2docker.iso';
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
@ -21,25 +16,12 @@ module.exports = function (grunt) {
env.NODE_ENV = target;
var certificateFile = grunt.option('certificateFile');
var certificatePassword = grunt.option('certificatePassword');
var version = function (str) {
var match = str.match(/(\d+\.\d+\.\d+)/);
return match ? match[1] : null;
};
grunt.registerTask('download-boot2docker-iso', 'Downloads provided boot2docker version', function () {
try {
var data = fs.readFileSync(path.join('resources', 'boot2docker.iso'), {encoding: 'utf-8'});
var match = data.match(/Boot2Docker-v(\d+\.\d+\.\d+)/);
if (match && match[1] !== packagejson['docker-version']) {
grunt.task.run('curl:boot2docker-iso');
}
} catch (err) {
grunt.task.run('curl:boot2docker-iso');
}
});
grunt.registerMultiTask('download-binary', 'Downloads binary unless version up to date', function () {
var target = grunt.task.current.target;
var done = this.async();
@ -64,15 +46,19 @@ module.exports = function (grunt) {
APPNAME += ' (Beta)';
}
var OSX_OUT = './dist/osx';
var OSX_FILENAME = OSX_OUT + '/' + APPNAME + '.app';
var OSX_OUT = './dist';
var OSX_OUT_X64 = OSX_OUT + '/' + APPNAME + '-darwin-x64';
var OSX_FILENAME = OSX_OUT_X64 + '/' + APPNAME + '.app';
grunt.initConfig({
IDENTITY: 'Developer ID Application: Docker Inc',
APPNAME: APPNAME,
APPNAME_ESCAPED: APPNAME.replace(/ /g, '\\ ').replace(/\(/g,'\\(').replace(/\)/g,'\\)'),
OSX_OUT: OSX_OUT,
OSX_OUT_ESCAPED: OSX_OUT.replace(/ /g, '\\ ').replace(/\(/g,'\\(').replace(/\)/g,'\\)'),
OSX_OUT_X64: OSX_OUT_X64,
OSX_FILENAME: OSX_FILENAME,
OSX_FILENAME_ESCAPED: OSX_FILENAME.replace(' ', '\\ ').replace('(','\\(').replace(')','\\)'),
OSX_FILENAME_ESCAPED: OSX_FILENAME.replace(/ /g, '\\ ').replace(/\(/g,'\\(').replace(/\)/g,'\\)'),
// electron
electron: {
@ -80,7 +66,7 @@ module.exports = function (grunt) {
options: {
name: BASENAME,
dir: 'build/',
out: 'dist/',
out: 'dist',
version: packagejson['electron-version'],
platform: 'win32',
arch: 'x64',
@ -92,7 +78,7 @@ module.exports = function (grunt) {
options: {
name: APPNAME,
dir: 'build/',
out: '<%= OSX_OUT %>',
out: 'dist',
version: packagejson['electron-version'],
platform: 'darwin',
arch: 'x64',
@ -103,11 +89,25 @@ module.exports = function (grunt) {
}
},
prompt: {
'create-windows-installer': {
options: {
questions: [
{
config: 'certificatePassword',
type: 'password',
message: 'Certificate Password: '
}
]
}
}
},
rcedit: {
exes: {
files: [{
expand: true,
cwd: 'dist/' + BASENAME + '-win32',
cwd: 'dist/' + BASENAME + '-win32-x64',
src: [BASENAME + '.exe']
}],
options: {
@ -115,7 +115,7 @@ module.exports = function (grunt) {
'file-version': packagejson.version,
'product-version': packagejson.version,
'version-string': {
'CompanyName': 'Docker Inc',
'CompanyName': 'Docker',
'ProductVersion': packagejson.version,
'ProductName': APPNAME,
'FileDescription': APPNAME,
@ -128,34 +128,27 @@ module.exports = function (grunt) {
},
'create-windows-installer': {
appDirectory: 'dist/' + BASENAME + '-win32/',
authors: 'Docker Inc.',
loadingGif: 'util/loading.gif',
setupIcon: 'util/setup.ico',
iconUrl: 'https://raw.githubusercontent.com/kitematic/kitematic/master/util/kitematic.ico',
description: APPNAME,
title: APPNAME,
exe: BASENAME + '.exe',
version: packagejson.version,
signWithParams: '/f ' + certificateFile + ' /p ' + certificatePassword + ' /tr http://timestamp.comodoca.com/rfc3161'
config: {
appDirectory: path.join(__dirname, 'dist/' + BASENAME + '-win32-x64'),
outputDirectory: path.join(__dirname, 'dist'),
authors: 'Docker Inc.',
loadingGif: 'util/loading.gif',
setupIcon: 'util/setup.ico',
iconUrl: 'https://raw.githubusercontent.com/kitematic/kitematic/master/util/kitematic.ico',
description: APPNAME,
title: APPNAME,
exe: BASENAME + '.exe',
version: packagejson.version,
signWithParams: '/f ' + certificateFile + ' /p <%= certificatePassword %> /tr http://timestamp.comodoca.com/rfc3161'
}
},
// docker binaries
'download-binary': {
docker: {
version: packagejson['docker-version'],
binary: path.join('resources', 'docker'),
download: 'curl:docker'
},
'docker-machine': {
version: packagejson['docker-machine-version'],
binary: path.join('resources', 'docker-machine'),
download: 'curl:docker-machine'
},
'docker-compose': {
version: packagejson['docker-compose-version'],
binary: path.join('resources', 'docker-compose'),
download: 'curl:docker-compose'
}
},
@ -188,8 +181,8 @@ module.exports = function (grunt) {
files: [{
expand: true,
cwd: 'resources',
src: ['docker*', 'boot2docker.iso', 'ssh.exe', 'OPENSSH_LICENSE', 'msys-*'],
dest: 'dist/' + BASENAME + '-win32/resources/resources/'
src: ['docker*', 'ssh.exe', 'OPENSSH_LICENSE', 'msys-*'],
dest: 'dist/' + BASENAME + '-win32-x64/resources/resources'
}],
options: {
mode: true
@ -199,7 +192,7 @@ module.exports = function (grunt) {
files: [{
expand: true,
cwd: 'resources',
src: ['docker*', 'boot2docker.iso', 'macsudo', 'terminal'],
src: ['docker*', 'macsudo', 'terminal'],
dest: '<%= OSX_FILENAME %>/Contents/Resources/resources/'
}, {
src: 'util/kitematic.icns',
@ -213,28 +206,16 @@ module.exports = function (grunt) {
rename: {
installer: {
src: 'installer/Setup.exe',
dest: 'installer/' + BASENAME + 'Setup-' + packagejson.version + '-Windows-Alpha.exe'
src: 'dist/Setup.exe',
dest: 'dist/' + BASENAME + 'Setup-' + packagejson.version + '-Windows-Alpha.exe'
}
},
// download binaries
curl: {
docker: {
src: process.platform === 'win32' ? WINDOWS_DOCKER_URL : DARWIN_DOCKER_URL,
dest: process.platform === 'win32' ? path.join('resources', 'docker.exe') : path.join('resources', 'docker')
},
'docker-machine': {
src: process.platform === 'win32' ? WINDOWS_DOCKER_MACHINE_URL : DARWIN_DOCKER_MACHINE_URL,
dest: process.platform === 'win32' ? path.join('resources', 'docker-machine.exe') : path.join('resources', 'docker-machine')
},
'docker-compose': {
src: DARWIN_COMPOSE_URL,
dest: 'resources/docker-compose'
},
'boot2docker-iso': {
src: BOOT2DOCKER_ISO_URL,
dest: path.join('resources', 'boot2docker.iso')
}
},
@ -275,41 +256,6 @@ module.exports = function (grunt) {
}
},
plistbuddy: {
addBundleURLTypes: {
method: 'Add',
entry: 'CFBundleURLTypes',
type: 'array',
src: '<%= OSX_FILENAME %>/Contents/Info.plist'
},
addBundleURLTypesDict: {
method: 'Add',
entry: 'CFBundleURLTypes:0',
type: 'dict',
src: '<%= OSX_FILENAME %>/Contents/Info.plist'
},
addBundleURLTypesDictName: {
method: 'Add',
entry: 'CFBundleURLTypes:0:CFBundleURLName',
type: 'string',
value: 'Docker App Protocol',
src: '<%= OSX_FILENAME %>/Contents/Info.plist'
},
addBundleURLTypesDictSchemes: {
method: 'Add',
entry: 'CFBundleURLTypes:0:CFBundleURLSchemes',
type: 'array',
src: '<%= OSX_FILENAME %>/Contents/Info.plist'
},
addBundleURLTypesDictSchemesDocker: {
method: 'Add',
entry: 'CFBundleURLTypes:0:CFBundleURLSchemes:0',
type: 'string',
value: 'docker',
src: '<%= OSX_FILENAME %>/Contents/Info.plist'
}
},
shell: {
electron: {
command: electron + ' ' + 'build',
@ -332,13 +278,27 @@ module.exports = function (grunt) {
].join(' && '),
},
zip: {
command: 'ditto -c -k --sequesterRsrc --keepParent <%= OSX_FILENAME_ESCAPED %> <%= OSX_OUT %>/' + BASENAME + '-' + packagejson.version + '-Mac.zip',
command: 'ditto -c -k --sequesterRsrc --keepParent <%= OSX_FILENAME_ESCAPED %> dist/' + BASENAME + '-' + packagejson.version + '-Mac.zip',
}
},
clean: {
release: ['build/', 'dist/', 'installer/'],
isos: ['resources/boot2docker*']
release: ['build/', 'dist/'],
},
compress: {
windows: {
options: {
archive: './dist/' + BASENAME + '-' + packagejson.version + '-Windows-Alpha.zip',
mode: 'zip'
},
files: [{
expand: true,
dot: true,
cwd: './dist/Kitematic-win32-x64',
src: '**/*'
}]
},
},
// livereload
@ -365,16 +325,12 @@ module.exports = function (grunt) {
}
});
if (process.platform === 'win32') {
grunt.registerTask('default', ['download-binary:docker', 'download-binary:docker-machine', 'download-boot2docker-iso', 'newer:babel', 'less', 'newer:copy:dev', 'shell:electron', 'watchChokidar']);
} else {
grunt.registerTask('default', ['download-binary', 'download-boot2docker-iso', 'newer:babel', 'less', 'newer:copy:dev', 'shell:electron', 'watchChokidar']);
}
grunt.registerTask('default', ['download-binary', 'newer:babel', 'less', 'newer:copy:dev', 'shell:electron', 'watchChokidar']);
if (process.platform === 'win32') {
grunt.registerTask('release', ['clean:release', 'download-binary:docker', 'download-binary:docker-machine', 'download-boot2docker-iso', 'babel', 'less', 'copy:dev', 'electron:windows', 'copy:windows', 'rcedit:exes', 'create-windows-installer', 'rename:installer']);
grunt.registerTask('release', ['clean:release', 'download-binary', 'babel', 'less', 'copy:dev', 'electron:windows', 'copy:windows', 'rcedit:exes', 'compress', 'prompt:create-windows-installer', 'create-windows-installer', 'rename:installer']);
} else {
grunt.registerTask('release', ['clean:release', 'download-binary', 'download-boot2docker-iso', 'babel', 'less', 'copy:dev', 'electron:osx', 'copy:osx', 'plistbuddy', 'shell:sign', 'shell:zip']);
grunt.registerTask('release', ['clean:release', 'download-binary', 'babel', 'less', 'copy:dev', 'electron:osx', 'copy:osx', 'shell:sign', 'shell:zip']);
}
process.on('SIGINT', function () {

4
MAINTAINERS Normal file
View File

@ -0,0 +1,4 @@
Jeff Morgan <jmorgan@docker.com> (@jeffdm)
Sean Li <mail@shang.li> (@elesant)
Michael Chiang <mchiang@docker.com> (@mchiang0610)
Ben French <me@frenchben.com> (@FrenchBen)

View File

@ -11,12 +11,6 @@ Kitematic is a simple application for managing Docker containers on Mac and Wind
[Download the latest version](https://kitematic.com/download) of Kitematic.
On the Mac, Kitematic can copy the binaries for Docker, Docker Machine and Docker Compose into `/usr/local/bin` for command line use outside of Kitematic.
To do so please click on the Kitematic dropdown menu and select `Install Docker Commands`
![Install Docker Commands](https://cloud.githubusercontent.com/assets/3325447/8246881/fa5f1ee0-15fa-11e5-936b-147bd53ec5a0.png)
## Documentation
Kitematic's documentation and other information can be found at [http://kitematic.com/docs](http://kitematic.com/docs).
@ -38,7 +32,7 @@ Please read through our [Contributing Guidelines](https://github.com/kitematic/k
## Community
- [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](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).
- Ask questions on our [user forum](https://forums.docker.com/c/open-source-projects/kitematic).
- **#kitematic** on IRC. [Join the channel](http://webchat.freenode.net/?channels=%23kitematic&uio=d4).
- Follow [@kitematic on Twitter](https://twitter.com/kitematic).

View File

@ -28,4 +28,9 @@
**June 2015**
* Microsoft Windows port
* Microsoft Windows alpha
**July 2015**
* Refactor to Flux Architecture
* Stability & code quality improvements

View File

@ -20,7 +20,7 @@ describe('SetupStore', function () {
pit('downloads virtualbox if it is installed but has an outdated version', function () {
virtualBox.installed.mockReturnValue(true);
virtualBox.version.mockReturnValue(Promise.resolve('4.3.16'));
virtualBox.version.mockReturnValue(Promise.resolve('5.0.0'));
util.compareVersions.mockReturnValue(-1);
setupUtil.download.mockReturnValue(Promise.resolve());
virtualBox.filename.mockReturnValue('');
@ -55,6 +55,7 @@ describe('SetupStore', function () {
machine.stop.mockReturnValue(Promise.resolve());
machine.start.mockReturnValue(Promise.resolve());
machine.upgrade.mockReturnValue(Promise.resolve());
util.packagejson.mockReturnValue({'docker-version':'1.8.0'});
util.compareVersions.mockReturnValue(-1);
machine.create.mockClear();
machine.upgrade.mockClear();

View File

@ -30,6 +30,12 @@ describe('Util', function () {
expect(util.removeSensitiveData(testdata).indexOf('/Users/<redacted>/.docker')).toNotEqual(-1);
});
it('filters Windows username data', function () {
var testdata = String.raw`C:\\Users\\johnappleseed\\.docker\\machine`;
expect(util.removeSensitiveData(testdata).indexOf('johnappleseed')).toEqual(-1);
expect(util.removeSensitiveData(testdata).indexOf('<redacted>')).toNotEqual(-1);
});
it ('returns input if empty or not a string', function () {
expect(util.removeSensitiveData('')).toBe('');
expect(util.removeSensitiveData(1)).toBe(1);

View File

@ -3,17 +3,13 @@ var virtualBox = require('../src/utils/VirtualBoxUtil');
var util = require('../src/utils/Util');
describe('VirtualBox', function () {
it('returns the right command', function () {
expect(virtualBox.command()).toBe('/usr/bin/VBoxManage');
});
describe('version 4.3.20r96996', function () {
describe('version 5.0.0r101573', function () {
pit('correctly parses virtualbox version', function () {
util.exec.mockImplementation(function () {
return Promise.resolve('4.3.20r96996');
return Promise.resolve('5.0.0r101573');
});
return virtualBox.version().then(function (version) {
expect(version).toBe('4.3.20');
expect(version).toBe('5.0.0');
});
});
});

View File

@ -1,30 +1,27 @@
FROM docs/base:hugo
FROM docs/base:latest
MAINTAINER Mary Anthony <mary@docker.com> (@moxiegirl)
# to get the git info for this repo
# To get the git info for this repo
COPY . /src
COPY . /docs/content/kitematic/
RUN svn checkout https://github.com/docker/compose/trunk/docs /docs/content/compose
RUN svn checkout https://github.com/docker/docker/trunk/docs /docs/content/docker
RUN svn checkout https://github.com/docker/swarm/trunk/docs /docs/content/swarm
RUN svn checkout https://github.com/docker/distribution/trunk/docs /docs/content/registry
RUN svn checkout https://github.com/docker/tutorials/trunk/docs /docs/content
RUN svn checkout https://github.com/docker/opensource/trunk/docs /docs/content/opensource
RUN svn checkout https://github.com/docker/machine/trunk/docs /docs/content/machine
# Sed to process GitHub Markdown
# 1-2 Remove comment code from metadata block
# 3 Change ](/word to ](/project/ in links
# 4 Change ](word.md) to ](/project/word)
# 5 Remove .md extension from link text
# 6 Change ](./ to ](/project/word)
# 7 Change ](../../ to ](/project/
# 8 Change ](../ to ](/project/
# 9 Change ](# to ](/project/
# 6 Change ](../ to ](/project/word)
# 7 Change ](../../ to ](/project/ --> not implemented
#
RUN find /docs/content/kitematic -type f -name "*.md" -exec sed -i.old \
-e '/^<!.*metadata]>/g' \
-e '/^<!.*end-metadata.*>/g' \
-e 's/\(\]\)\([(]\)\(\/\)/\1\2\/kitematic\//g' \
-e 's/\(\][(]\)\([A-z].*\)\(\.md\)/\1\/kitematic\/\2/g' \
-e 's/\([(]\)\(.*\)\(\.md\)/\1\2/g' \
-e 's/\(\][(]\)\(\.\/\)/\1\/kitematic\//g' \
-e 's/\(\][(]\)\(\.\.\/\.\.\/\)/\1\/kitematic\//g' \
-e 's/\(\][(]\)\(\.\.\/\)/\1\/kitematic\//g' {} \;
#
RUN /src/pre-process.sh /docs

View File

@ -21,8 +21,7 @@ software released under the Apache 2.0 license.
### How can I contribute to Kitematic?
We always welcome (and deeply appreciate!) new contributions to the project. The
best way to start contributing to Kitematic is to review our doc on
[contributing](https://github.com/kitematic/kitematic/blob/master/CONTRIBUTING.md).
best way to start contributing to Kitematic is to review our doc on <a href="https://github.com/kitematic/kitematic/blob/master/CONTRIBUTING.md">contributing</a>.
### How does Kitematic work with Docker?
@ -31,10 +30,9 @@ the Docker Remote API.
### Which platforms does Kitematic support?
Right now Kitematic only works on Mac OS X. That said, Windows is on the
short-term
[roadmap](https://github.com/kitematic/kitematic/blob/master/ROADMAP.md) (coming
soon!) and a Linux version is in high demand.
Right now Kitematic works on Mac OS X and Windows. Linux is planned in the
future. Review our product <a
href="https://github.com/kitematic/kitematic/blob/master/ROADMAP.md">roadmap</a>.
### Why does Kitematic collect usage analytics and bug reports?

View File

@ -9,45 +9,8 @@ weight=2
+++
<![end-metadata]-->
# Kitematic: Install Kitematic
# Kitematic
You install Kitematic much the same way you install any application on a Mac or
Windows PC: download an image and run an installer.
Kitematic, the Docker GUI, runs on Mac OS X and Windows operating systems. Beginning with the 1.8 Docker release, you use the Docker Toolbox to install Kitematic. See the [Mac OS X installation guide](https://docs.docker.com/mac) or the [Windows installation guide](https://docs.docker.com/installation/windows) for details on installing with Docker Toolbox.
## Download Kitematic
[Download the Kitematic zip file](https://kitematic.com/download/), unzip the
file by double-clicking it, and then double-click the application to run it.
You'll probably also want to put the application in your Applications folder.
## Initial Setup
Opening Kitematic for the first time sets up everything you need to run Docker
containers. If you don't already have VirtualBox installed, Kitematic will
download and install the latest version.
![Installing](../images/installing.png)
All Done! Within a minute you should be ready to start running your first
container!
![containers](../images/containers.png)
## Technical Details
Kitematic is a self-contained .app, with an exception:
- It will install VirtualBox if it's not already installed.
### Why does Kitematic need my root password?
Kitematic needs your root password for two reasons:
- Installing VirtualBox requires root access as it includes Mac OS X kernel extensions.
- Copying `docker` and `docker-machine` to `/usr/local/bin` may require root
permission if the default permissions for this directory have been changed
prior to installing Kitematic.
## Next Steps
For information about using Kitematic, take a look at the [User Guide](/userguide).
For information about using Kitematic, take a look at the [User Guide](userguide).

View File

@ -29,8 +29,8 @@ commands on the command line:
- `docker-machine create -d virtualbox dev`
Then re-open Kitematic. This usually fixes the issue, but if it persists, feel
free to view our [existing GitHub
issues](https://github.com/kitematic/kitematic/issues?q=is%3Aopen+is%3Aissue+label%3Abug).
free to view our <a href="https://github.com/kitematic/kitematic/issues?q=is%3Aopen+is%3Aissue+label%3Abug">existing GitHub
issues</a>.
## Contributing Fixes
@ -46,6 +46,5 @@ if you're looking to help fix specific issues around VM provisioning.
## View All Issues
For a full list of Kitematic bugs or issues see our [GitHub
issues](https://github.com/kitematic/kitematic/issues?q=is%3Aopen+is%3Aissue+label%3Abug)
labelled as `bug`.
For a full list of Kitematic bugs or issues see our <a href="https://github.com/kitematic/kitematic/issues?q=is%3Aopen+is%3Aissue+label%3Abug">existing GitHub
issues</a> labelled as `bug`.

61
docs/pre-process.sh Executable file
View File

@ -0,0 +1,61 @@
#!/bin/bash -e
# Populate an array with just docker dirs and one with content dirs
docker_dir=(`ls -d /docs/content/docker/*`)
content_dir=(`ls -d /docs/content/*`)
# Loop content not of docker/
#
# Sed to process GitHub Markdown
# 1-2 Remove comment code from metadata block
# 3 Remove .md extension from link text
# 4 Change ](/ to ](/project/ in links
# 5 Change ](word) to ](/project/word)
# 6 Change ](../../ to ](/project/
# 7 Change ](../ to ](/project/word)
#
for i in "${content_dir[@]}"
do
:
case $i in
"/docs/content/windows")
;;
"/docs/content/mac")
;;
"/docs/content/linux")
;;
"/docs/content/docker")
y=${i##*/}
find $i -type f -name "*.md" -exec sed -i.old \
-e '/^<!.*metadata]>/g' \
-e '/^<!.*end-metadata.*>/g' {} \;
;;
*)
y=${i##*/}
find $i -type f -name "*.md" -exec sed -i.old \
-e '/^<!.*metadata]>/g' \
-e '/^<!.*end-metadata.*>/g' \
-e 's/\(\]\)\([(]\)\(\/\)/\1\2\/'$y'\//g' \
-e 's/\(\][(]\)\([A-z].*\)\(\.md\)/\1\/'$y'\/\2/g' \
-e 's/\([(]\)\(.*\)\(\.md\)/\1\2/g' \
-e 's/\(\][(]\)\(\.\/\)/\1\/'$y'\//g' \
-e 's/\(\][(]\)\(\.\.\/\.\.\/\)/\1\/'$y'\//g' \
-e 's/\(\][(]\)\(\.\.\/\)/\1\/'$y'\//g' {} \;
;;
esac
done
#
# Move docker directories to content
#
for i in "${docker_dir[@]}"
do
:
if [ -d $i ]
then
mv $i /docs/content/
fi
done
rm -rf /docs/content/docker

View File

@ -2,7 +2,7 @@
+++
title = "Kitematic User Guide: Intro & Overview"
description = "Documentation that provides an overview of Kitematic and installation instructions"
keywords = ["docker, documentation, about, technology, kitematic, gui"]
keywords = ["docker, documentation, about, technology, kitematic, gui"]
[menu.main]
parent="smn_workw_kitematic"
+++
@ -16,12 +16,12 @@ Kitematic is an open source project built to simplify and streamline using
Docker on a Mac or Windows (coming soon) PC. Kitematic automates the Docker
installation and setup process and provides an intuitive graphical user
interface (GUI) for running Docker containers. Kitematic integrates with
[Docker Machine](http://docs.docker.com/machine/) to provision a VirtualBox VM
[Docker Machine](https://docs.docker.com/machine/) to provision a VirtualBox VM
and install the Docker Engine locally on your machine.
Once installed, the Kitematic GUI launches and from the home screen you will be
presented with curated images that you can run instantly. You can search for any
public images on Docker Hub from Kitematic just by typing in the search bar.
public images on Docker Hub from Kitematic just by typing in the search bar.
You can use the GUI to create, run and manage your containers just by clicking
on buttons. Kitematic allows you to switch back and forth between the Docker CLI
and the GUI. Kitematic also automates advanced features such as managing ports
@ -78,17 +78,17 @@ The currently detected "web" ports are, `80`, `8000`, `8080`, `3000`, `5000`,
### Viewing container logs
You can view the entire main container process' log output either by cicking on the "Logs"
You can view the entire main container process' log output either by clicking on the "Logs"
preview image, or by clicking on the "Logs" tab.
You can then scroll through the logs from the current running container. Note that
if you make changes to the container Settings, then the container will be restarted,
so will reset this log view.
if you make changes to the container settings, then the container will be restarted,
so this will reset this log view.
### Starting a terminal in a container
The "Terminal" icon at the top of the container summary will `docker exec sh <your container>`.
This will allow you to make quick changes, or to debug a problem.
This will allow you to make quick changes, or to debug a problem.
> **Note**: Your exec'ed `sh` process will not have the same environment settings
> as the main container process and its children.
@ -100,7 +100,7 @@ on your Mac by clicking on the folders in the "Edit Files" section of the
container summary screen.
This allows you to manage files in volumes via the Finder.
Kitematic exposes a container's volume data under `~/Kitematic/<container's name>/`.
Kitematic exposes a container's volume data under `~/Documents/Kitematic/<container's name>/`.
Quick access to this folder (or directory) is available via the app:
![Accessing the volumes directory](../images/volumes-dir.png)
@ -117,7 +117,7 @@ use the default directory created for the website_files volume. Instead, you
already have the HTML, Javascript, and CSS for your website under
`~/workspace/website`.
Navigate to the "Settings" tab of the container, and goto the "Volumes". This
Navigate to the "Settings" tab of the container, and go to the "Volumes". This
screen allows you to set the mappings individually.
![screen shot 2015-02-28 at 2 48 01 pm](../images/change-folder.png)
@ -142,12 +142,12 @@ Many images use environment variables to let you customise them. The "General"
"Settings" tab allows you to add and modify the environment variables used to
start a container.
The list of Environment variables will show any that have been set on the image
The list of environment variables will show any that have been set on the image
metadata - for example, using the `ENV` instruction in the Dockerfile.
<TODO: image of the jenkins container>
Wen you "Save" the changed environment variables, the container will be stopped
When you "Save" the changed environment variables, the container will be stopped,
removed and re-created.
### Delete container
@ -155,14 +155,14 @@ removed and re-created.
On the "General" "Settings" tab, you can delete the container. Clicking "Delete
Container" will also stop the container if necessary.
You can also delete a container clicking the `X` icon in the container list.
You can also delete a container by clicking the `X` icon in the container list.
Kitematic will prompt you to confirm that you want to delete.
#### List the exposed Ports and how to access them
To see the complete list of exposed ports, go to "Settings" then "Ports". This
page lists all the container ports exposed, and the IP address and host only
page lists all the container ports exposed, and the IP address and host-only
network port that you can access use to access that container from your OS X
system.
@ -172,7 +172,7 @@ You can interact with existing containers in Kitematic or create new containers
via the Docker Command Line Interface (CLI). Any changes you make on the CLI are
directly reflected in Kitematic.
To open a terminal via Kitematic, just press whale button at the bottom left, as
To open a terminal via Kitematic, just press the whale button at the bottom left, as
shown below:
![CLI access button](../images/cli-access-button.png)
@ -185,9 +185,9 @@ will pull and run a new Redis container via the Docker CLI.
![Docker CLI terminal window](../images/cli-terminal.png)
> **Note**: If you're creating containers from the commandline, use `docker run -d`
> **Note**: If you're creating containers from the command line, use `docker run -d`
> so that Kitematic can re-create the container when settings are changed via the
> Kitematic user interface. containers started without `-d` will fail to re-start.
> Kitematic user interface. Containers started without `-d` will fail to re-start.
Now, go back to Kitematic. The Redis container should now be visible.
@ -196,4 +196,4 @@ Now, go back to Kitematic. The Redis container should now be visible.
## Next Steps
For an example using Kitematic to run a Minecraft server, take a look at
the [Mincraft server](./minecraft-server.md) page.
the [Minecraft server](./minecraft-server.md) page.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
images/cartoon-docker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -1,6 +1,6 @@
{
"name": "Kitematic",
"version": "0.7.3",
"version": "0.8.3",
"author": "Kitematic",
"description": "Simple Docker Container management for Mac OS X.",
"homepage": "https://kitematic.com/",
@ -22,15 +22,14 @@
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"docker-version": "1.7.0",
"docker-machine-version": "0.3.0-rc2",
"docker-compose-version": "1.3.0",
"docker-version": "1.8.1",
"docker-machine-version": "0.4.1",
"electron-version": "0.27.2",
"virtualbox-version": "4.3.28",
"virtualbox-filename": "VirtualBox-4.3.28.pkg",
"virtualbox-filename-win": "VirtualBox-4.3.28.exe",
"virtualbox-checksum": "60521caff652fc32ad733eee2eea27f03d0b4f7239af3bf4b21dc6f0251cf47a",
"virtualbox-checksum-win": "82039b615bf18dfff92ac1d9a15b2cbd5c59c608631ccf77e2371d0fd67a6cf7",
"virtualbox-version": "5.0.2",
"virtualbox-filename": "VirtualBox-5.0.2.pkg",
"virtualbox-filename-win": "VirtualBox-5.0.2.exe",
"virtualbox-checksum": "384414edab277c376a2ac3d02e5f316434fa4d54d31db44dc85b6e560eda4143",
"virtualbox-checksum-win": "a8183d21566fc6cb327e4b71303fa0d04fc6cd079ba83d66818d18c5ef427037",
"dependencies": {
"alt": "^0.16.2",
"ansi-to-html": "0.3.0",
@ -71,16 +70,18 @@
"grunt-chmod": "^1.0.3",
"grunt-cli": "^0.1.13",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-compress": "^0.13.0",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-watch-chokidar": "^1.0.0",
"grunt-curl": "^2.2.0",
"grunt-download-electron": "^2.1.1",
"grunt-electron": "^1.0.0",
"grunt-electron-installer": "^0.33.0",
"grunt-electron": "^2.0.0",
"grunt-electron-installer": "^0.37.0",
"grunt-if-missing": "^1.0.0",
"grunt-newer": "^1.1.1",
"grunt-plistbuddy": "^0.1.1",
"grunt-prompt": "^1.3.0",
"grunt-rcedit": "^0.3.1",
"grunt-rename": "^0.1.4",
"grunt-shell": "^1.1.2",

View File

@ -1,8 +1,7 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PATH=$DIR:$PATH
CMD="export PATH='$PATH' && clear && $*"
CMD="clear && $*"
ITERM_EXISTS=`osascript <<EOF
set doesExist to false

View File

@ -1,24 +1,23 @@
require.main.paths.splice(0, 0, process.env.NODE_PATH);
var remote = require('remote');
import remote from 'remote';
var Menu = remote.require('menu');
var React = require('react');
var SetupStore = require('./stores/SetupStore');
var ipc = require('ipc');
var machine = require('./utils/DockerMachineUtil');
var metrics = require('./utils/MetricsUtil');
var router = require('./router');
var template = require('./menutemplate');
var webUtil = require('./utils/WebUtil');
var hubUtil = require('./utils/HubUtil');
import React from 'react';
import SetupStore from './stores/SetupStore';
import ipc from 'ipc';
import machine from './utils/DockerMachineUtil';
import metrics from './utils/MetricsUtil';
import template from './menutemplate';
import webUtil from './utils/WebUtil';
import hubUtil from './utils/HubUtil';
var urlUtil = require ('./utils/URLUtil');
var app = remote.require('app');
var request = require('request');
var docker = require('./utils/DockerUtil');
var hub = require('./utils/HubUtil');
var Router = require('react-router');
var routes = require('./routes');
var routerContainer = require('./router');
var repositoryActions = require('./actions/RepositoryActions');
import request from 'request';
import docker from './utils/DockerUtil';
import hub from './utils/HubUtil';
import Router from 'react-router';
import routes from './routes';
import routerContainer from './router';
import repositoryActions from './actions/RepositoryActions';
hubUtil.init();

View File

@ -1,11 +1,11 @@
var app = require('app');
var autoUpdater = require('auto-updater');
var BrowserWindow = require('browser-window');
var fs = require('fs');
var os = require('os');
var ipc = require('ipc');
var path = require('path');
var child_process = require('child_process');
import app from 'app';
import autoUpdater from 'auto-updater';
import BrowserWindow from 'browser-window';
import fs from 'fs';
import os from 'os';
import ipc from 'ipc';
import path from 'path';
import child_process from 'child_process';
process.env.NODE_PATH = path.join(__dirname, 'node_modules');
process.env.RESOURCES_PATH = path.join(__dirname, '/../resources');

View File

@ -0,0 +1,69 @@
import React from 'react/addons';
import metrics from '../utils/MetricsUtil';
import utils from '../utils/Util';
import Router from 'react-router';
import RetinaImage from 'react-retina-image';
var packages;
try {
packages = utils.packagejson();
} catch (err) {
packages = {};
}
var Preferences = React.createClass({
mixins: [Router.Navigation],
getInitialState: function () {
return {
metricsEnabled: metrics.enabled()
};
},
handleGoBackClick: function () {
this.goBack();
metrics.track('Went Back From About');
},
render: function () {
return (
<div className="preferences">
<div className="about-content">
<a onClick={this.handleGoBackClick}>Go Back</a>
<div className="items">
<div className="item">
<RetinaImage src="cartoon-kitematic.png"/>
<h4>Docker {packages.name}</h4>
<p>{packages.version}</p>
</div>
</div>
<h3>Kitematic is built with:</h3>
<div className="items">
<div className="item">
<RetinaImage src="cartoon-docker.png"/>
<h4>Docker Engine</h4>
<p>{packages["docker-version"]}</p>
</div>
<div className="item">
<RetinaImage src="cartoon-docker-machine.png"/>
<h4>Docker Machine</h4>
<p>{packages["docker-machine-version"]}</p>
</div>
</div>
<h3>Third-Party Software</h3>
<div className="items">
<div className="item">
<h4>VirtualBox</h4>
<p>{packages["virtualbox-version"]}</p>
</div>
</div>
<div className="items">
<div className="item">
<h4>Electron</h4>
<p>{packages["electron-version"]}</p>
</div>
</div>
</div>
</div>
);
}
});
module.exports = Preferences;

View File

@ -1,10 +1,10 @@
var React = require('react/addons');
var Router = require('react-router');
var RetinaImage = require('react-retina-image');
var Header = require('./Header.react');
var metrics = require('../utils/MetricsUtil');
var accountStore = require('../stores/AccountStore');
var accountActions = require('../actions/AccountActions');
import React from 'react/addons';
import Router from 'react-router';
import RetinaImage from 'react-retina-image';
import Header from './Header.react';
import metrics from '../utils/MetricsUtil';
import accountStore from '../stores/AccountStore';
import accountActions from '../actions/AccountActions';
module.exports = React.createClass({
mixins: [Router.Navigation],

View File

@ -1,10 +1,10 @@
var _ = require('underscore');
var React = require('react/addons');
var Router = require('react-router');
var validator = require('validator');
var accountActions = require('../actions/AccountActions');
var metrics = require('../utils/MetricsUtil');
var shell = require('shell');
import _ from 'underscore';
import React from 'react/addons';
import Router from 'react-router';
import validator from 'validator';
import accountActions from '../actions/AccountActions';
import metrics from '../utils/MetricsUtil';
import shell from 'shell';
module.exports = React.createClass({
mixins: [Router.Navigation, React.addons.LinkedStateMixin],
@ -60,7 +60,7 @@ module.exports = React.createClass({
},
handleClickForgotPassword: function () {
shell.openExternal('https://hub.docker.com/account/forgot-password/');
shell.openExternal('https://hub.docker.com/reset-password/');
},
render: function () {

View File

@ -1,9 +1,9 @@
var _ = require('underscore');
var React = require('react/addons');
var Router = require('react-router');
var validator = require('validator');
var accountActions = require('../actions/AccountActions');
var metrics = require('../utils/MetricsUtil');
import _ from 'underscore';
import React from 'react/addons';
import Router from 'react-router';
import validator from 'validator';
import accountActions from '../actions/AccountActions';
import metrics from '../utils/MetricsUtil';
module.exports = React.createClass({
mixins: [Router.Navigation, React.addons.LinkedStateMixin],

View File

@ -1,10 +1,10 @@
var React = require('react/addons');
var Router = require('react-router');
var ContainerDetailsHeader = require('./ContainerDetailsHeader.react');
var ContainerDetailsSubheader = require('./ContainerDetailsSubheader.react');
var containerUtil = require('../utils/ContainerUtil');
var util = require('../utils/Util');
var _ = require('underscore');
import React from 'react/addons';
import Router from 'react-router';
import ContainerDetailsHeader from './ContainerDetailsHeader.react';
import ContainerDetailsSubheader from './ContainerDetailsSubheader.react';
import containerUtil from '../utils/ContainerUtil';
import util from '../utils/Util';
import _ from 'underscore';
var ContainerDetails = React.createClass({
contextTypes: {

View File

@ -1,4 +1,4 @@
var React = require('react/addons');
import React from 'react/addons';
var ContainerDetailsHeader = React.createClass({
render: function () {

View File

@ -1,11 +1,11 @@
var _ = require('underscore');
var React = require('react');
var shell = require('shell');
var metrics = require('../utils/MetricsUtil');
var ContainerUtil = require('../utils/ContainerUtil');
var classNames = require('classnames');
var containerActions = require('../actions/ContainerActions');
var dockerMachineUtil = require('../utils/DockerMachineUtil');
import _ from 'underscore';
import React from 'react';
import shell from 'shell';
import metrics from '../utils/MetricsUtil';
import ContainerUtil from '../utils/ContainerUtil';
import classNames from 'classnames';
import containerActions from '../actions/ContainerActions';
import dockerMachineUtil from '../utils/DockerMachineUtil';
var ContainerDetailsSubheader = React.createClass({
contextTypes: {

View File

@ -1,12 +1,12 @@
var _ = require('underscore');
var $ = require('jquery');
var React = require('react/addons');
var Radial = require('./Radial.react');
var ContainerProgress = require('./ContainerProgress.react');
var ContainerHomePreview = require('./ContainerHomePreview.react');
var ContainerHomeLogs = require('./ContainerHomeLogs.react');
var ContainerHomeFolders = require('./ContainerHomeFolders.react');
var shell = require('shell');
import _ from 'underscore';
import $ from 'jquery';
import React from 'react/addons';
import Radial from './Radial.react';
import ContainerProgress from './ContainerProgress.react';
import ContainerHomePreview from './ContainerHomePreview.react';
import ContainerHomeLogs from './ContainerHomeLogs.react';
import ContainerHomeFolders from './ContainerHomeFolders.react';
import shell from 'shell';
var ContainerHome = React.createClass({
contextTypes: {
@ -39,11 +39,11 @@ var ContainerHome = React.createClass({
showWeb: function () {
return _.keys(this.props.ports).length > 0;
},
showFolders: function () {
return this.props.container.Volumes && _.keys(this.props.container.Volumes).length > 0 && this.props.container.State.Running;
return this.props.container.Mounts && this.props.container.Mounts.length > 0 && this.props.container.State.Running;
},
render: function () {
if (!this.props.container) {
return;

View File

@ -1,42 +1,49 @@
var _ = require('underscore');
var React = require('react/addons');
var RetinaImage = require('react-retina-image');
var path = require('path');
var shell = require('shell');
var util = require('../utils/Util');
var metrics = require('../utils/MetricsUtil');
var containerActions = require('../actions/ContainerActions');
var dialog = require('remote').require('dialog');
var mkdirp = require('mkdirp');
import _ from 'underscore';
import React from 'react/addons';
import RetinaImage from 'react-retina-image';
import path from 'path';
import shell from 'shell';
import util from '../utils/Util';
import metrics from '../utils/MetricsUtil';
import containerActions from '../actions/ContainerActions';
import remote from 'remote';
var dialog = remote.require('dialog');
import mkdirp from 'mkdirp';
var ContainerHomeFolder = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClickFolder: function (hostVolume, containerVolume) {
handleClickFolder: function (source, destination) {
metrics.track('Opened Volume Directory', {
from: 'home'
});
if (hostVolume.indexOf(util.windowsToLinuxPath(util.home())) === -1) {
if (source.indexOf(util.windowsToLinuxPath(util.home())) === -1) {
dialog.showMessageBox({
message: 'Enable all volumes to edit files via Finder? This may not work with all database containers.',
message: `Enable all volumes to edit files? This may not work with all database containers.`,
buttons: ['Enable Volumes', 'Cancel']
}, (index) => {
if (index === 0) {
var volumes = _.clone(this.props.container.Volumes);
var newHostVolume = util.escapePath(path.join(util.home(), util.documents(), 'Kitematic', this.props.container.Name, containerVolume));
volumes[containerVolume] = newHostVolume;
var binds = _.pairs(volumes).map(function (pair) {
if(util.isWindows()) {
return util.windowsToLinuxPath(pair[1]) + ':' + pair[0];
var mounts = _.clone(this.props.container.Mounts);
var newSource = util.escapePath(path.join(util.home(), util.documents(), 'Kitematic', this.props.container.Name, destination));
var binds = mounts.map(function (m) {
let source = m.Source;
if (m.Destination === destination) {
source = newSource;
}
return pair[1] + ':' + pair[0];
if(util.isWindows()) {
return util.windowsToLinuxPath(source) + ':' + m.Destination;
}
return source + ':' + m.Destination;
});
mkdirp(newHostVolume, function (err) {
mkdirp(newSource, function (err) {
console.log(err);
if (!err) {
shell.showItemInFolder(newHostVolume);
shell.showItemInFolder(newSource);
}
});
@ -44,7 +51,7 @@ var ContainerHomeFolder = React.createClass({
}
});
} else {
let path = util.isWindows() ? util.linuxToWindowsPath(hostVolume) : hostVolume;
let path = util.isWindows() ? util.linuxToWindowsPath(source) : source;
shell.showItemInFolder(path);
}
},
@ -59,12 +66,13 @@ var ContainerHomeFolder = React.createClass({
return false;
}
var folders = _.map(_.omit(this.props.container.Volumes, (v, k) => k.indexOf('/Users/') !== -1), (val, key) => {
var firstFolder = key;
var folders = _.map(this.props.container.Mounts, (m, i) => {
let destination = m.Destination;
let source = m.Source;
return (
<div key={key} className="folder" onClick={this.handleClickFolder.bind(this, val, key)}>
<div key={i} className="folder" onClick={this.handleClickFolder.bind(this, source, destination)}>
<RetinaImage src="folder.png" />
<div className="text">{firstFolder}</div>
<div className="text">{destination}</div>
</div>
);
});

View File

@ -1,8 +1,8 @@
var $ = require('jquery');
var React = require('react/addons');
var LogStore = require('../stores/LogStore');
var Router = require('react-router');
var metrics = require('../utils/MetricsUtil');
import $ from 'jquery';
import React from 'react/addons';
import LogStore from '../stores/LogStore';
import Router from 'react-router';
import metrics from '../utils/MetricsUtil';
var _prevBottom = 0;

View File

@ -1,8 +1,8 @@
var _ = require('underscore');
var React = require('react/addons');
var request = require('request');
var shell = require('shell');
var metrics = require('../utils/MetricsUtil');
import _ from 'underscore';
import React from 'react/addons';
import request from 'request';
import shell from 'shell';
import metrics from '../utils/MetricsUtil';
var ContainerHomePreview = React.createClass({
contextTypes: {

View File

@ -1,5 +1,5 @@
var React = require('react/addons');
var ContainerListItem = require('./ContainerListItem.react');
import React from 'react/addons';
import ContainerListItem from './ContainerListItem.react';
var ContainerList = React.createClass({
componentWillMount: function () {

View File

@ -1,12 +1,11 @@
var $ = require('jquery');
var React = require('react/addons');
var Router = require('react-router');
var remote = require('remote');
import $ from 'jquery';
import React from 'react/addons';
import Router from 'react-router';
import remote from 'remote';
var dialog = remote.require('dialog');
var metrics = require('../utils/MetricsUtil');
var OverlayTrigger = require('react-bootstrap').OverlayTrigger;
var Tooltip = require('react-bootstrap').Tooltip;
var containerActions = require('../actions/ContainerActions');
import metrics from '../utils/MetricsUtil';
import {OverlayTrigger, Tooltip} from 'react-bootstrap';
import containerActions from '../actions/ContainerActions';
var ContainerListItem = React.createClass({
handleItemMouseEnter: function () {

View File

@ -1,6 +1,6 @@
var $ = require('jquery');
var React = require('react/addons');
var LogStore = require('../stores/LogStore');
import $ from 'jquery';
import React from 'react/addons';
import LogStore from '../stores/LogStore';
var _prevBottom = 0;

View File

@ -1,4 +1,4 @@
var React = require('react');
import React from 'react';
/*

View File

@ -1,7 +1,7 @@
var $ = require('jquery');
var _ = require('underscore');
var React = require('react/addons');
var Router = require('react-router');
import $ from 'jquery';
import _ from 'underscore';
import React from 'react/addons';
import Router from 'react-router';
var ContainerSettings = React.createClass({
contextTypes: {

View File

@ -1,7 +1,7 @@
var React = require('react/addons');
var metrics = require('../utils/MetricsUtil');
var ContainerUtil = require('../utils/ContainerUtil');
var containerActions = require('../actions/ContainerActions');
import React from 'react/addons';
import metrics from '../utils/MetricsUtil';
import ContainerUtil from '../utils/ContainerUtil';
import containerActions from '../actions/ContainerActions';
var ContainerSettingsAdvanced = React.createClass({
mixins: [React.addons.LinkedStateMixin],

View File

@ -1,11 +1,11 @@
var _ = require('underscore');
var React = require('react/addons');
var remote = require('remote');
var metrics = require('../utils/MetricsUtil');
import _ from 'underscore';
import React from 'react/addons';
import metrics from '../utils/MetricsUtil';
import remote from 'remote';
var dialog = remote.require('dialog');
var ContainerUtil = require('../utils/ContainerUtil');
var containerActions = require('../actions/ContainerActions');
var util = require('../utils/Util');
import ContainerUtil from '../utils/ContainerUtil';
import containerActions from '../actions/ContainerActions';
import util from '../utils/Util';
var ContainerSettingsGeneral = React.createClass({
mixins: [React.addons.LinkedStateMixin],

View File

@ -1,9 +1,9 @@
var _ = require('underscore');
var React = require('react/addons');
var shell = require('shell');
var ContainerUtil = require('../utils/ContainerUtil');
var metrics = require('../utils/MetricsUtil');
var webPorts = require('../utils/Util').webPorts;
import _ from 'underscore';
import React from 'react/addons';
import shell from 'shell';
import ContainerUtil from '../utils/ContainerUtil';
import metrics from '../utils/MetricsUtil';
import {webPorts} from '../utils/Util';
var ContainerSettingsPorts = React.createClass({
contextTypes: {

View File

@ -1,11 +1,11 @@
var _ = require('underscore');
var React = require('react/addons');
var remote = require('remote');
import _ from 'underscore';
import React from 'react/addons';
import remote from 'remote';
var dialog = remote.require('dialog');
var shell = require('shell');
var util = require('../utils/Util');
var metrics = require('../utils/MetricsUtil');
var containerActions = require('../actions/ContainerActions');
import shell from 'shell';
import util from '../utils/Util';
import metrics from '../utils/MetricsUtil';
import containerActions from '../actions/ContainerActions';
var ContainerSettingsVolumes = React.createClass({
handleChooseVolumeClick: function (dockerVol) {
@ -26,16 +26,23 @@ var ContainerSettingsVolumes = React.createClass({
}
metrics.track('Choose Directory for Volume');
if(util.isWindows()) {
directory = util.escapePath(util.windowsToLinuxPath(directory));
}
var volumes = _.clone(this.props.container.Volumes);
volumes[dockerVol] = directory;
var binds = _.pairs(volumes).map(function (pair) {
return pair[1] + ':' + pair[0];
var mounts = _.clone(this.props.container.Mounts);
_.each(mounts, m => {
if (m.Destination === dockerVol) {
m.Source = directory;
}
});
containerActions.update(this.props.container.Name, {Binds: binds, Volumes: volumes});
var binds = mounts.map(m => {
return m.Source + ':' + m.Destination;
});
containerActions.update(this.props.container.Name, {Binds: binds, Mounts: mounts});
});
},
handleRemoveVolumeClick: function (dockerVol) {
@ -45,13 +52,17 @@ var ContainerSettingsVolumes = React.createClass({
var hostConfig = _.clone(this.props.container.HostConfig);
var binds = hostConfig.Binds;
var volumes = _.clone(this.props.container.Volumes);
volumes[dockerVol] = null;
var mounts = _.clone(this.props.container.Mounts);
_.each(mounts, m => {
if (m.Destination === dockerVol) {
m.Source = null;
}
});
var index = _.findIndex(binds, bind => bind.indexOf(`:${dockerVol}`) !== -1);
if (index >= 0) {
binds.splice(index, 1);
}
containerActions.update(this.props.container.Name, {HostConfig: hostConfig, Binds: binds, Volumes: volumes});
containerActions.update(this.props.container.Name, {HostConfig: hostConfig, Binds: binds, Mounts: mounts});
},
handleOpenVolumeClick: function (path) {
metrics.track('Opened Volume Directory', {
@ -69,24 +80,25 @@ var ContainerSettingsVolumes = React.createClass({
}
var homeDir = util.isWindows() ? util.windowsToLinuxPath(util.home()) : util.home();
var volumes = _.map(this.props.container.Volumes, (val, key) => {
if (!val || val.indexOf(homeDir) === -1) {
val = (
var mounts= _.map(this.props.container.Mounts, (m, i) => {
let source = m.Source, destination = m.Destination;
if (!m.Source || m.Source.indexOf(homeDir) === -1) {
source = (
<span className="value-right">No Folder</span>
);
} else {
let local = util.isWindows() ? util.linuxToWindowsPath(val) : val;
val = (
<a className="value-right" onClick={this.handleOpenVolumeClick.bind(this, val)}>{local.replace(process.env.HOME, '~')}</a>
let local = util.isWindows() ? util.linuxToWindowsPath(source) : source;
source = (
<a className="value-right" onClick={this.handleOpenVolumeClick.bind(this, source)}>{local.replace(process.env.HOME, '~')}</a>
);
}
return (
<tr>
<td>{key}</td>
<td>{val}</td>
<td>{destination}</td>
<td>{source}</td>
<td>
<a className="btn btn-action small" disabled={this.props.container.State.Updating} onClick={this.handleChooseVolumeClick.bind(this, key)}>Change</a>
<a className="btn btn-action small" disabled={this.props.container.State.Updating} onClick={this.handleRemoveVolumeClick.bind(this, key)}>Remove</a>
<a className="btn btn-action small" disabled={this.props.container.State.Updating} onClick={this.handleChooseVolumeClick.bind(this, destination)}>Change</a>
<a className="btn btn-action small" disabled={this.props.container.State.Updating} onClick={this.handleRemoveVolumeClick.bind(this, destination)}>Remove</a>
</td>
</tr>
);
@ -104,7 +116,7 @@ var ContainerSettingsVolumes = React.createClass({
</tr>
</thead>
<tbody>
{volumes}
{mounts}
</tbody>
</table>
</div>

View File

@ -1,13 +1,13 @@
var $ = require('jquery');
var _ = require('underscore');
var React = require('react');
var Router = require('react-router');
var containerStore = require('../stores/ContainerStore');
var ContainerList = require('./ContainerList.react');
var Header = require('./Header.react');
var metrics = require('../utils/MetricsUtil');
var shell = require('shell');
var machine = require('../utils/DockerMachineUtil');
import $ from 'jquery';
import _ from 'underscore';
import React from 'react';
import Router from 'react-router';
import containerStore from '../stores/ContainerStore';
import ContainerList from './ContainerList.react';
import Header from './Header.react';
import metrics from '../utils/MetricsUtil';
import shell from 'shell';
import machine from '../utils/DockerMachineUtil';
var Containers = React.createClass({
contextTypes: {

View File

@ -1,17 +1,16 @@
var React = require('react/addons');
var remote = require('remote');
var RetinaImage = require('react-retina-image');
var remote = require('remote');
var ipc = require('ipc');
import React from 'react/addons';
import remote from 'remote';
import RetinaImage from 'react-retina-image';
import ipc from 'ipc';
var autoUpdater = remote.require('auto-updater');
var util = require('../utils/Util');
var metrics = require('../utils/MetricsUtil');
import util from '../utils/Util';
import metrics from '../utils/MetricsUtil';
var Menu = remote.require('menu');
var MenuItem = remote.require('menu-item');
var accountStore = require('../stores/AccountStore');
var accountActions = require('../actions/AccountActions');
var Router = require('react-router');
var classNames = require('classnames');
import accountStore from '../stores/AccountStore';
import accountActions from '../actions/AccountActions';
import Router from 'react-router';
import classNames from 'classnames';
var Header = React.createClass({
mixins: [Router.Navigation],

View File

@ -1,13 +1,13 @@
var $ = require('jquery');
var React = require('react/addons');
var Router = require('react-router');
var shell = require('shell');
var RetinaImage = require('react-retina-image');
var metrics = require('../utils/MetricsUtil');
var containerActions = require('../actions/ContainerActions');
var containerStore = require('../stores/ContainerStore');
var tagStore = require('../stores/TagStore');
var tagActions = require('../actions/TagActions');
import $ from 'jquery';
import React from 'react/addons';
import Router from 'react-router';
import shell from 'shell';
import RetinaImage from 'react-retina-image';
import metrics from '../utils/MetricsUtil';
import containerActions from '../actions/ContainerActions';
import containerStore from '../stores/ContainerStore';
import tagStore from '../stores/TagStore';
import tagActions from '../actions/TagActions';
var ImageCard = React.createClass({
mixins: [Router.Navigation],
@ -108,7 +108,8 @@ var ImageCard = React.createClass({
description = "No description.";
}
var logoStyle = {
backgroundImage: `linear-gradient(-180deg, ${this.props.image.gradient_start} 4%, ${this.props.image.gradient_end} 100%)`
//backgroundImage: `linear-gradient(-180deg, ${this.props.image.gradient_start} 4%, ${this.props.image.gradient_end} 100%)`
backgroundColor: this.props.image.gradient_start
};
var imgsrc;
if (this.props.image.img) {

View File

@ -1,9 +1,9 @@
var React = require('react/addons');
var Router = require('react-router');
var shell = require('shell');
var containerActions = require('../actions/ContainerActions');
var containerStore = require('../stores/ContainerStore');
var metrics = require('../utils/MetricsUtil');
import React from 'react/addons';
import Router from 'react-router';
import shell from 'shell';
import containerActions from '../actions/ContainerActions';
import containerStore from '../stores/ContainerStore';
import metrics from '../utils/MetricsUtil';
module.exports = React.createClass({
mixins: [Router.Navigation],

View File

@ -1,15 +1,15 @@
var _ = require('underscore');
var React = require('react/addons');
var Router = require('react-router');
var RetinaImage = require('react-retina-image');
var ImageCard = require('./ImageCard.react');
var Promise = require('bluebird');
var metrics = require('../utils/MetricsUtil');
var classNames = require('classnames');
var repositoryActions = require('../actions/RepositoryActions');
var repositoryStore = require('../stores/RepositoryStore');
var accountStore = require('../stores/AccountStore');
var accountActions = require('../actions/AccountActions');
import _ from 'underscore';
import React from 'react/addons';
import Router from 'react-router';
import RetinaImage from 'react-retina-image';
import ImageCard from './ImageCard.react';
import Promise from 'bluebird';
import metrics from '../utils/MetricsUtil';
import classNames from 'classnames';
import repositoryActions from '../actions/RepositoryActions';
import repositoryStore from '../stores/RepositoryStore';
import accountStore from '../stores/AccountStore';
import accountActions from '../actions/AccountActions';
var _searchPromise = null;
@ -222,7 +222,7 @@ module.exports = React.createClass({
<div className="new-container-header">
<div className="search">
<div className="search-bar">
<input type="search" ref="searchInput" className="form-control" placeholder="Search image on Docker Hub" onChange={this.handleChange}/>
<input type="search" ref="searchInput" className="form-control" placeholder="Search for Docker images from Docker Hub" onChange={this.handleChange}/>
<div className={magnifierClasses}></div>
<div className={loadingClasses}><div></div></div>
</div>

View File

@ -1,6 +1,6 @@
var React = require('react/addons');
var metrics = require('../utils/MetricsUtil');
var Router = require('react-router');
import React from 'react/addons';
import metrics from '../utils/MetricsUtil';
import Router from 'react-router';
var Preferences = React.createClass({
mixins: [Router.Navigation],
@ -42,7 +42,7 @@ var Preferences = React.createClass({
<div className="title">VM Settings</div>
<div className="option">
<div className="option-name">
Shut Down Linux VM on closing Kitematic
Shutdown Linux VM on closing Kitematic
</div>
<div className="option-value">
<input type="checkbox" checked={this.state.closeVMOnQuit} onChange={this.handleChangeCloseVMOnQuit}/>

View File

@ -1,5 +1,5 @@
var React = require('react');
var classNames = require('classnames');
import React from 'react';
import classNames from 'classnames';
var Radial = React.createClass({
render: function () {

View File

@ -1,11 +1,11 @@
var React = require('react/addons');
var Router = require('react-router');
var Radial = require('./Radial.react.js');
var SetupStore = require('../stores/SetupStore');
var RetinaImage = require('react-retina-image');
var Header = require('./Header.react');
var Util = require('../utils/Util');
var metrics = require('../utils/MetricsUtil');
import React from 'react/addons';
import Router from 'react-router';
import Radial from './Radial.react.js';
import SetupStore from '../stores/SetupStore';
import RetinaImage from 'react-retina-image';
import Header from './Header.react';
import Util from '../utils/Util';
import metrics from '../utils/MetricsUtil';
var Setup = React.createClass({
mixins: [ Router.Navigation ],

View File

@ -17,7 +17,12 @@ var MenuTemplate = function () {
submenu: [
{
label: 'About Kitematic',
selector: 'orderFrontStandardAboutPanel:'
click: function () {
metrics.track('Opened About', {
from: 'menu'
});
router.get().transitionTo('about');
}
},
{
type: 'separator'
@ -37,35 +42,9 @@ var MenuTemplate = function () {
type: 'separator'
},
{
label: 'Install Docker Commands',
enabled: true,
click: function () {
metrics.track('Installed Docker Commands');
if (!setupUtil.shouldUpdateBinaries()) {
dialog.showMessageBox({
message: 'Docker binaries are already installed in /usr/local/bin',
buttons: ['OK']
});
return;
}
let copy = setupUtil.needsBinaryFix() ?
util.exec(setupUtil.macSudoCmd(setupUtil.copyBinariesCmd() + ' && ' + setupUtil.fixBinariesCmd())) :
util.exec(setupUtil.copyBinariesCmd());
copy.then(() => {
dialog.showMessageBox({
message: 'Docker binaries have been installed under /usr/local/bin',
buttons: ['OK']
});
}).catch((err) => {
console.log(err);
});
},
type: 'separator'
},
{
type: 'separator'
}, {
label: 'Hide Kitematic',
accelerator: util.CommandOrCtrl() + '+H',
selector: 'hide:'

View File

@ -1,21 +1,22 @@
var React = require('react/addons');
var Setup = require('./components/Setup.react');
var Account = require('./components/Account.react');
var AccountSignup = require('./components/AccountSignup.react');
var AccountLogin = require('./components/AccountLogin.react');
var Containers = require('./components/Containers.react');
var ContainerDetails = require('./components/ContainerDetails.react');
var ContainerHome = require('./components/ContainerHome.react');
var ContainerLogs = require('./components/ContainerLogs.react');
var ContainerSettings = require('./components/ContainerSettings.react');
var ContainerSettingsGeneral = require('./components/ContainerSettingsGeneral.react');
var ContainerSettingsPorts = require('./components/ContainerSettingsPorts.react');
var ContainerSettingsVolumes = require('./components/ContainerSettingsVolumes.react');
var ContainerSettingsAdvanced = require('./components/ContainerSettingsAdvanced.react');
var Preferences = require('./components/Preferences.react');
var NewContainerSearch = require('./components/NewContainerSearch.react');
var NewContainerPull = require('./components/NewContainerPull.react');
var Router = require('react-router');
import React from 'react/addons';
import Setup from './components/Setup.react';
import Account from './components/Account.react';
import AccountSignup from './components/AccountSignup.react';
import AccountLogin from './components/AccountLogin.react';
import Containers from './components/Containers.react';
import ContainerDetails from './components/ContainerDetails.react';
import ContainerHome from './components/ContainerHome.react';
import ContainerLogs from './components/ContainerLogs.react';
import ContainerSettings from './components/ContainerSettings.react';
import ContainerSettingsGeneral from './components/ContainerSettingsGeneral.react';
import ContainerSettingsPorts from './components/ContainerSettingsPorts.react';
import ContainerSettingsVolumes from './components/ContainerSettingsVolumes.react';
import ContainerSettingsAdvanced from './components/ContainerSettingsAdvanced.react';
import Preferences from './components/Preferences.react';
import About from './components/About.react';
import NewContainerSearch from './components/NewContainerSearch.react';
import NewContainerPull from './components/NewContainerPull.react';
import Router from 'react-router';
var Route = Router.Route;
var DefaultRoute = Router.DefaultRoute;
@ -51,6 +52,7 @@ var routes = (
<Route name="pull" path="containers/new/pull" handler={NewContainerPull}></Route>
</Route>
<Route name="preferences" path="/preferences" handler={Preferences}/>
<Route name="about" path="/about" handler={About}/>
</Route>
<DefaultRoute name="setup" handler={Setup}/>
</Route>

View File

@ -1,8 +1,8 @@
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');
var Convert = require('ansi-to-html');
var docker = require('../utils/DockerUtil');
var stream = require('stream');
import {EventEmitter} from 'events';
import assign from 'object-assign';
import Convert from 'ansi-to-html';
import docker from '../utils/DockerUtil';
import stream from 'stream';
var _convert = new Convert();
var _logs = {};

View File

@ -1,16 +1,16 @@
var EventEmitter = require('events').EventEmitter;
var _ = require('underscore');
var path = require('path');
var fs = require('fs');
var Promise = require('bluebird');
var machine = require('../utils/DockerMachineUtil');
var virtualBox = require('../utils/VirtualBoxUtil');
var setupUtil = require('../utils/SetupUtil');
var util = require('../utils/Util');
var assign = require('object-assign');
var metrics = require('../utils/MetricsUtil');
var bugsnag = require('bugsnag-js');
var docker = require('../utils/DockerUtil');
import {EventEmitter} from 'events';
import _ from 'underscore';
import path from 'path';
import fs from 'fs';
import Promise from 'bluebird';
import machine from '../utils/DockerMachineUtil';
import virtualBox from '../utils/VirtualBoxUtil';
import setupUtil from '../utils/SetupUtil';
import util from '../utils/Util';
import assign from 'object-assign';
import metrics from '../utils/MetricsUtil';
import bugsnag from 'bugsnag-js';
import docker from '../utils/DockerUtil';
var _currentStep = null;
var _error = null;
@ -73,7 +73,8 @@ var _steps = [{
var isoversion = machine.isoversion();
var packagejson = util.packagejson();
if (!isoversion || util.compareVersions(isoversion, packagejson['docker-version']) < 0) {
var packagejsonVersion = packagejson['docker-version'].split('-')[0];
if (!isoversion || util.compareVersions(isoversion, packagejsonVersion) < 0) {
yield machine.start();
yield machine.upgrade();
}

View File

@ -1,5 +1,5 @@
var _ = require('underscore');
var docker = require('../utils/DockerUtil');
import _ from 'underscore';
import docker from '../utils/DockerUtil';
var ContainerUtil = {
env: function (container) {

View File

@ -1,22 +1,20 @@
var _ = require('underscore');
var path = require('path');
var Promise = require('bluebird');
var fs = require('fs');
var util = require('./Util');
var resources = require('./ResourcesUtil');
var NAME = util.isWindows () ? 'kitematic' : 'dev';
import _ from 'underscore';
import path from 'path';
import Promise from 'bluebird';
import fs from 'fs';
import util from './Util';
import resources from './ResourcesUtil';
var DockerMachine = {
command: function () {
return resources.dockerMachine();
},
name: function () {
return NAME;
return 'default';
},
isoversion: function () {
isoversion: function (machineName = this.name()) {
try {
var data = fs.readFileSync(path.join(util.home(), '.docker', 'machine', 'machines', NAME, 'boot2docker.iso'), 'utf8');
var data = fs.readFileSync(path.join(util.home(), '.docker', 'machine', 'machines', machineName, 'boot2docker.iso'), 'utf8');
var match = data.match(/Boot2Docker-v(\d+\.\d+\.\d+)/);
if (match) {
return match[1];
@ -27,7 +25,7 @@ var DockerMachine = {
return null;
}
},
info: function () {
info: function (machineName = this.name()) {
return util.exec([this.command(), 'ls']).then(stdout => {
var lines = stdout.trim().split('\n').filter(line => line.indexOf('time=') === -1);
var machines = {};
@ -41,54 +39,50 @@ var DockerMachine = {
};
machines[machine.name] = machine;
});
if (machines[NAME]) {
return Promise.resolve(machines[NAME]);
if (machines[machineName]) {
return Promise.resolve(machines[machineName]);
} else {
return Promise.reject(new Error('Machine does not exist.'));
}
});
},
exists: function () {
return this.info().then(() => {
exists: function (machineName = this.name()) {
return this.info(machineName).then(() => {
return true;
}).catch(() => {
return false;
});
},
create: function () {
if (util.isWindows()) {
return util.exec([this.command(), '-D', 'create', '-d', 'virtualbox', '--virtualbox-memory', '2048', NAME]);
} else {
return util.exec([this.command(), '-D', 'create', '-d', 'virtualbox' ,'--virtualbox-boot2docker-url', path.join(process.env.RESOURCES_PATH, 'boot2docker.iso'), '--virtualbox-memory', '2048', NAME]);
}
create: function (machineName = this.name()) {
return util.exec([this.command(), '-D', 'create', '-d', 'virtualbox', '--virtualbox-memory', '2048', machineName]);
},
start: function () {
return util.exec([this.command(), '-D', 'start', NAME]);
start: function (machineName = this.name()) {
return util.exec([this.command(), '-D', 'start', machineName]);
},
stop: function () {
return util.exec([this.command(), 'stop', NAME]);
stop: function (machineName = this.name()) {
return util.exec([this.command(), 'stop', machineName]);
},
upgrade: function () {
return util.exec([this.command(), 'upgrade', NAME]);
upgrade: function (machineName = this.name()) {
return util.exec([this.command(), 'upgrade', machineName]);
},
rm: function () {
return util.exec([this.command(), 'rm', '-f', NAME]);
rm: function (machineName = this.name()) {
return util.exec([this.command(), 'rm', '-f', machineName]);
},
ip: function () {
return util.exec([this.command(), 'ip', NAME]).then(stdout => {
ip: function (machineName = this.name()) {
return util.exec([this.command(), 'ip', machineName]).then(stdout => {
return Promise.resolve(stdout.trim().replace('\n', ''));
});
},
regenerateCerts: function () {
return util.exec([this.command(), 'tls-regenerate-certs', '-f', NAME]);
regenerateCerts: function (machineName = this.name()) {
return util.exec([this.command(), 'tls-regenerate-certs', '-f', machineName]);
},
state: function () {
return this.info().then(info => {
state: function (machineName = this.name()) {
return this.info(machineName).then(info => {
return info ? info.state : null;
});
},
disk: function () {
return util.exec([this.command(), 'ssh', NAME, 'df']).then(stdout => {
disk: function (machineName = this.name()) {
return util.exec([this.command(), 'ssh', machineName, 'df']).then(stdout => {
try {
var lines = stdout.split('\n');
var dataline = _.find(lines, function (line) {
@ -111,8 +105,8 @@ var DockerMachine = {
}
});
},
memory: function () {
return util.exec([this.command(), 'ssh', NAME, 'free -m']).then(stdout => {
memory: function (machineName = this.name()) {
return util.exec([this.command(), 'ssh', machineName, 'free -m']).then(stdout => {
try {
var lines = stdout.split('\n');
var dataline = _.find(lines, function (line) {
@ -137,8 +131,8 @@ var DockerMachine = {
}
});
},
stats: function () {
this.state().then(state => {
stats: function (machineName = this.name()) {
this.state(machineName).then(state => {
if (state === 'Stopped') {
return Promise.resolve({state: state});
}
@ -152,10 +146,10 @@ var DockerMachine = {
});
});
},
dockerTerminal: function (cmd) {
dockerTerminal: function (cmd, machineName = this.name()) {
if(util.isWindows()) {
cmd = cmd || '';
this.info().then(machine => {
this.info(machineName).then(machine => {
util.exec('start powershell.exe ' + cmd,
{env: {
'DOCKER_HOST' : machine.url,
@ -166,7 +160,7 @@ var DockerMachine = {
});
} else {
cmd = cmd || process.env.SHELL;
this.info().then(machine => {
this.info(machineName).then(machine => {
util.exec([resources.terminal(), `DOCKER_HOST=${machine.url} DOCKER_CERT_PATH=${path.join(util.home(), '.docker/machine/machines/' + machine.name)} DOCKER_TLS_VERIFY=1 ${cmd}`]).then(() => {});
});
}

View File

@ -120,9 +120,9 @@ export default {
},
fetchContainer (id) {
this.client.getContainer(id).inspect((error, container) => {
this.client.getContainer(id).inspect((error, container) => {
if (error) {
containerServerActions.error({name: id, error});
containerServerActions.error({name: id, error});
} else {
container.Name = container.Name.replace('/', '');
containerServerActions.updated({container});
@ -135,26 +135,23 @@ export default {
if (err) {
return;
}
let modifiedContainers = _.map(containers, container => {
container.Name = container.Names[0].replace('/', '');
delete container.Names;
// HACK: fill in some data based on simple list data
container.State = {};
container.Config = {
Image: container.Image
};
if (container.Status.indexOf('Exited') !== -1) {
container.State.Stopped = true;
} else if (container.Status.indexOf('Paused') !== -1) {
container.State.Stopped = true;
} else if (container.Status.indexOf('Up') !== -1) {
container.State.Running = true;
async.map(containers, (container, callback) => {
this.client.getContainer(container.Id).inspect((error, container) => {
if (error) {
callback(null, null);
return;
}
container.Name = container.Name.replace('/', '');
callback(null, container);
});
}, (err, containers) => {
containers = containers.filter(c => c !== null);
if (err) {
// TODO: add a global error handler for this
return;
}
return container;
containerServerActions.allUpdated({containers: _.indexBy(containers.concat(_.values(this.placeholders)), 'Name')});
});
containerServerActions.allUpdated({containers: _.indexBy(modifiedContainers.concat(_.values(this.placeholders)), 'Name')});
});
},
@ -223,6 +220,11 @@ export default {
existingData.Env = existingData.Config.Env;
}
if ((!existingData.Tty || !existingData.OpenStdin) && existingData.Config && (existingData.Config.Tty || existingData.Config.OpenStdin)) {
existingData.Tty = existingData.Config.Tty;
existingData.OpenStdin = existingData.Config.OpenStdin;
}
var fullData = _.extend(existingData, data);
this.createContainer(name, fullData);
});
@ -305,12 +307,12 @@ export default {
let container = this.client.getContainer(name);
container.unpause(function () {
container.kill(function (error) {
if (error) {
containerServerActions.error({name, error});
return;
}
container.remove(function () {
container.kill(function () {
container.remove(function (error) {
if (error) {
containerServerActions.error({name, error});
return;
}
containerServerActions.destroyed({id: name});
var volumePath = path.join(util.home(), 'Kitematic', name);
if (fs.existsSync(volumePath)) {

View File

@ -1,7 +1,7 @@
var _ = require('underscore');
var request = require('request');
var accountServerActions = require('../actions/AccountServerActions');
var metrics = require('./MetricsUtil');
import _ from 'underscore';
import request from 'request';
import accountServerActions from '../actions/AccountServerActions';
import metrics from './MetricsUtil';
let HUB2_ENDPOINT = process.env.HUB2_ENDPOINT || 'https://hub.docker.com/v2';

View File

@ -1,11 +1,11 @@
var assign = require('object-assign');
var Mixpanel = require('mixpanel');
var uuid = require('node-uuid');
var fs = require('fs');
var path = require('path');
var util = require('./Util');
var os = require('os');
var osxRelease = require('osx-release');
import assign from 'object-assign';
import Mixpanel from 'mixpanel';
import uuid from 'node-uuid';
import fs from 'fs';
import path from 'path';
import util from './Util';
import os from 'os';
import osxRelease from 'osx-release';
var settings;
try {

View File

@ -1,10 +1,10 @@
var _ = require('underscore');
var request = require('request');
var async = require('async');
var util = require('../utils/Util');
var hubUtil = require('../utils/HubUtil');
var repositoryServerActions = require('../actions/RepositoryServerActions');
var tagServerActions = require('../actions/TagServerActions');
import _ from 'underscore';
import request from 'request';
import async from 'async';
import util from '../utils/Util';
import hubUtil from '../utils/HubUtil';
import repositoryServerActions from '../actions/RepositoryServerActions';
import tagServerActions from '../actions/TagServerActions';
let REGHUB2_ENDPOINT = process.env.REGHUB2_ENDPOINT || 'https://registry.hub.docker.com/v2';
let searchReq = null;
@ -103,11 +103,11 @@ module.exports = {
}, (error, response, body) => {
if (response.statusCode === 200) {
let data = JSON.parse(body);
tagServerActions.tagsUpdated({repo, tags: data});
if (callback) { callback(null, data); }
} else if (error || response.statusCode === 401) {
tagServerActions.tagsUpdated({repo, tags: data.results || []});
if (callback) { callback(null, data.results || []); }
} else {
repositoryServerActions.error({repo});
if (callback) { callback(new Error('Failed to fetch repos')); }
if (callback) { callback(new Error('Failed to fetch tags for repo')); }
}
});
},

View File

@ -1,5 +1,5 @@
var util = require('./Util');
var path = require('path');
import util from './Util';
import path from 'path';
module.exports = {
resourceDir: function () {

View File

@ -1,12 +1,12 @@
var _ = require('underscore');
var crypto = require('crypto');
var fs = require('fs');
var path = require('path');
var request = require('request');
var progress = require('request-progress');
var Promise = require('bluebird');
var util = require('./Util');
var resources = require('./ResourcesUtil');
import _ from 'underscore';
import crypto from 'crypto';
import fs from 'fs';
import path from 'path';
import request from 'request';
import progress from 'request-progress';
import Promise from 'bluebird';
import util from './Util';
import resources from './ResourcesUtil';
var virtualBox = require ('./VirtualBoxUtil');
var SetupUtil = {

View File

@ -1,6 +1,6 @@
var util = require('./Util');
var parseUri = require('parseUri');
var containerServerActions = require('../actions/ContainerServerActions');
import util from './Util';
import parseUri from 'parseUri';
import containerServerActions from '../actions/ContainerServerActions';
module.exports = {
TYPE_WHITELIST: ['repository'],

View File

@ -1,10 +1,10 @@
var exec = require('exec');
var child_process = require('child_process');
var Promise = require('bluebird');
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var remote = require('remote');
import exec from 'exec';
import child_process from 'child_process';
import Promise from 'bluebird';
import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
import remote from 'remote';
var app = remote.require('app');
module.exports = {
@ -71,7 +71,8 @@ module.exports = {
}
return str.replace(/-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----/mg, '<redacted>')
.replace(/-----BEGIN RSA PRIVATE KEY-----.*-----END RSA PRIVATE KEY-----/mg, '<redacted>')
.replace(/\/Users\/[^\/]*\//mg, '/Users/<redacted>/');
.replace(/\/Users\/[^\/]*\//mg, '/Users/<redacted>/')
.replace(/\\Users\\[^\/]*\\/mg, '\\Users\\<redacted>\\');
},
packagejson: function () {
return JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));

View File

@ -1,13 +1,13 @@
var fs = require('fs');
var util = require('./Util');
var Promise = require('bluebird');
import fs from 'fs';
import util from './Util';
import Promise from 'bluebird';
var VirtualBox = {
command: function () {
if(util.isWindows()) {
return 'C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe';
} else {
return '/usr/bin/VBoxManage';
return '/Applications/VirtualBox.app/Contents/MacOS/VBoxManage';
}
},
filename: function () {
@ -23,7 +23,7 @@ var VirtualBox = {
if(util.isWindows()) {
return fs.existsSync('C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe') && fs.existsSync('C:\\Program Files\\Oracle\\VirtualBox\\VirtualBox.exe');
} else {
return fs.existsSync('/usr/bin/VBoxManage') && fs.existsSync('/Applications/VirtualBox.app') && fs.existsSync('/Applications/VirtualBox.app/Contents/MacOS/VBoxManage');
return fs.existsSync('/Applications/VirtualBox.app') && fs.existsSync('/Applications/VirtualBox.app/Contents/MacOS/VBoxManage');
}
},
active: function () {

View File

@ -1,9 +1,10 @@
var app = require('remote').require('app');
var fs = require('fs');
var util = require('./Util');
var path = require('path');
var bugsnag = require('bugsnag-js');
var metrics = require('./MetricsUtil');
import remote from 'remote';
var app = remote.require('app');
import fs from 'fs';
import util from './Util';
import path from 'path';
import bugsnag from 'bugsnag-js';
import metrics from './MetricsUtil';
var WebUtil = {
addWindowSizeSaving: function () {

View File

@ -284,7 +284,7 @@
border-bottom-left-radius: @border-radius;
justify-content: center;
text-align: center;
box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.2);
box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.1);
img {
width: 35px;
height: auto;
@ -293,7 +293,7 @@
}
.card {
position: relative;
border: 1px solid darken(@gray-lightest, 5%);
border: 1px solid darken(@gray-lightest, 0%);
border-left: 0;
border-top-right-radius: @border-radius;
border-bottom-right-radius: @border-radius;

View File

@ -6,7 +6,7 @@
align-items: flex-start;
justify-content: center;
.preferences-content {
.preferences-content, .about-content {
flex: 1 auto;
margin-top: 45px;
padding: 50px;
@ -37,4 +37,34 @@
}
}
}
.about-content {
margin-top: 0px;
height: 100%;
overflow: auto;
.items {
display: flex;
.item {
flex: 1 auto;
margin-right: 1rem;
text-align: center;
}
}
h3 {
color: @gray-normal;
font-weight: 400;
font-size: 18px;
text-align: center;
}
img {
height: 100px;
width: auto;
}
h4 {
margin-bottom: 0.5rem;
}
p {
color: @gray-light;
font-size: 1.5rem;
}
}
}

View File

@ -197,6 +197,7 @@
border-radius: 4px;
max-height: 400px;
overflow: auto;
-webkit-user-select: initial;
}
}
.setup-actions {