Compare commits

..

588 Commits

Author SHA1 Message Date
Solomon Hykes a4fc52305a Bumping version to 0.1.3 2013-04-04 23:05:03 -07:00
Solomon Hykes 2aad4a3478 Choose which TCP frontend port to allocate with '-p :PORT' 2013-04-04 22:58:01 -07:00
Solomon Hykes a5fb1d6c01 Refactored PortAllocator to allow for same-frontend constraint 2013-04-04 22:56:12 -07:00
Solomon Hykes f344212b93 Renamed PortAllocator.populate() to run() 2013-04-04 19:49:32 -07:00
Solomon Hykes 0424998f38 Print a less confusing error message when lxcbr0 doesn't exist 2013-04-04 19:14:10 -07:00
Solomon Hykes 8bfbdd7afa Add versioning to docker image format. IMPORTANT: the format versioning is pegged to docker's versioning, so changes to the format MUST trigger an increment in version number. 2013-04-04 18:38:43 -07:00
Solomon Hykes 3de51b7bfe Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-04-04 17:00:59 -07:00
Solomon Hykes a58cd8c616 Merge pull request #322 from sa2ajj/port-map-nitpick
change option description to reflect the semantics
2013-04-04 16:39:54 -07:00
Solomon Hykes 586a79cca0 Merge remote-tracking branch 'dominikh/minor-code-touchups' 2013-04-04 16:20:37 -07:00
Solomon Hykes 349edf1bea Merge pull request #331 from lynaghk/master
Fix broken link on documentation website between examples.
2013-04-04 16:18:27 -07:00
Solomon Hykes 677908910c Merge pull request #320 from sa2ajj/cli-docs
move each command description into a separate document
2013-04-04 16:17:53 -07:00
Solomon Hykes 6b5fe8c2ec Merge remote-tracking branch 'origin/257-container_real_running_state-fix' 2013-04-04 15:34:18 -07:00
Solomon Hykes 26088a72b3 Merge remote-tracking branch 'dominikh/improve-attachopts' 2013-04-04 15:18:41 -07:00
Solomon Hykes ebc837957f Continue cleaning up iptables rules from previous version, to avoid crashing after an upgrade 2013-04-04 15:16:42 -07:00
Solomon Hykes c4d3da5871 Merge remote-tracking branch 'unclejack/137-fix-nat' 2013-04-04 15:06:20 -07:00
unclejack 32f5811476 stop looping remote:port from host to containers 2013-04-04 23:07:10 +03:00
Solomon Hykes a7f191d51d Merge remote-tracking branch 'origin/328-i_o_error_uncloced_connection-fix' 2013-04-04 11:03:39 -07:00
Kevin J. Lynagh 92186d7cf7 Fix broken link in doc site.
Broken link was from python_web_app to nonexistent "base commands page"; updated to point to next item in examples menu, running_ssh_service screencast.
2013-04-03 22:23:17 -07:00
Solomon Hykes 5d3c0767da Simplified Graph.Delete() - no more garbage collecting, just atomic deregister then os.RemoveAll 2013-04-03 22:14:28 -07:00
Solomon Hykes dce5a06aba Bumped version to 0.1.2 2013-04-03 15:35:32 -07:00
unclejack 3b65be9127 Fix NAT problem with ports looping back to containers 2013-04-04 01:32:46 +03:00
shin- ad0183e419 Check WaitTimeout return in test, replaced lock initialization in runtime.Register() with call to initLock() 2013-04-03 10:48:02 -07:00
Dominik Honnef 4f36039e7b clean up AttachOpts type
Primarily, there is no reason to have a pointer to a map. Furthermore,
make() can be used on AttachOpts directly.
2013-04-03 16:06:35 +02:00
Mikhail Sobolev b74d1c9247 change option description to reflect the semantics
At least, for me, 'map' means that there are two values and one is "mapped" to
another.

In this case, just one value is provided (container's port), the other value is
automatically obtained (host's port) and the actual mapping can be seen using
``docker port`` command.
2013-04-03 16:37:56 +03:00
Mikhail Sobolev cf8b8c1969 move each command description into a separate document 2013-04-03 15:55:18 +03:00
shin- d1767bbf67 Moved resetLock() to the Load() method ; changed resetLock() to initLock() and changed behavior to not modify the lock if it was already set (not nil) 2013-04-03 05:39:39 -07:00
shin- 7b74b9cab5 Integrated @creack's feedback on TestRestore 2013-04-03 05:37:45 -07:00
Dominik Honnef 14d3880daf remove superfluous panic 2013-04-03 11:19:48 +02:00
Dominik Honnef 22f1cc955d replace unreachable returns with panics
Not only is this a more common idiom, it'll make finding bugs easier,
and it'll make porting to Go 1.1 easier.

Go 1.1 will not require the final return or panic because it has a
notion of terminating statements.
2013-04-03 11:18:23 +02:00
Dominik Honnef cab31fd512 use wg.Done() isntead of wg.Add(-1) 2013-04-03 11:11:34 +02:00
Dominik Honnef 1fc55c2bb9 kill the right containers in runtime_test 2013-04-03 11:11:06 +02:00
Dominik Honnef 5ecd940a59 remove dead code in CmdPush 2013-04-03 11:08:32 +02:00
Dominik Honnef 3b8c2417fb use fmt.Fprintf instead of fmt.Fprint
fmt.Fprint does not allow format strings
2013-04-03 11:04:33 +02:00
Solomon Hykes 15c3096e89 Merged attachStdin 2013-04-02 20:46:32 -07:00
Solomon Hykes 22d1622926 Merge remote-tracking branch 'robryk/writebroadcaster-stuff' 2013-04-02 20:35:13 -07:00
Solomon Hykes 35c68944c7 Merged shawnsi/git-version 2013-04-02 20:26:22 -07:00
Solomon Hykes b1fa26bb76 TestRunHostname checks that 'docker run -h' correctly sets a custom hostname 2013-04-02 19:00:05 -07:00
Solomon Hykes d6fb2a0836 Merge remote-tracking branch 'sa2ajj/hostname-parameter' 2013-04-02 18:41:14 -07:00
Solomon Hykes 65aa3dda85 Merged dhrp/docs 2013-04-02 18:39:39 -07:00
Solomon Hykes a05af3ebf3 Fix a bug which caused 'docker push' to fail with 411-lenght-required in Go 1.0 2013-04-02 18:37:29 -07:00
Solomon Hykes 0e1781af26 Merge remote-tracking branch 'unclejack/194-high-image-compression' 2013-04-02 18:10:07 -07:00
Solomon Hykes 14d9f51bbe Merge branch 'master' into attach-stdin 2013-04-02 18:07:45 -07:00
Solomon Hykes c04af2a330 docker run [-a [stdin|stdout|stderr] [...]]: choose which streams to attach to when running a command. Fixes #234. 2013-04-02 18:07:16 -07:00
Solomon Hykes c77063afcd Add test for attaching only stdin at run with 'docker run -i -a=stdin' 2013-04-02 18:05:19 -07:00
Guillaume J. Charmes a19a9e3ca8 Discarding errors in CmdRun 2013-04-02 12:21:35 -07:00
Guillaume J. Charmes ad2bbe23be Close the broadcaster once they are not needed anymore 2013-04-02 12:19:01 -07:00
Guillaume J. Charmes 6882c78ce4 Add a stdincloser to container.Attach in order to close the client connection when needed 2013-04-02 12:18:20 -07:00
Solomon Hykes 2db358146f 'docker run' in attached mode no longer waits for the process to exit. Take this into account in the tests. 2013-04-02 11:07:49 -07:00
Solomon Hykes 1cc1cb099e When simulating disconnects in the tests, make sure that the command returns - but don't check for a specific return value 2013-04-02 11:06:42 -07:00
Solomon Hykes aea2675f7b Activate Config.StdinOnce at argument parsing 2013-04-02 11:02:19 -07:00
Solomon Hykes 8f9e454241 [unit tests] Cleanly kill all containers before nuking a temporary runtime 2013-04-02 11:00:14 -07:00
Solomon Hykes 7666307931 Use an environment variable to activate debug mode, instead of a package-specific flag 2013-04-02 10:58:16 -07:00
shin- 791ca6fde4 Better crash simulation in TestRestore ; force state lock creation when loading a container from disk 2013-04-02 10:06:49 -07:00
Guillaume J. Charmes 43484e8b50 Add a TestRunExit, make sure cmdRun returns after process dies 2013-04-02 09:22:30 -07:00
Shawn Siefkas 5471f5b2ee Implementing dirty git checkout indicator 2013-04-02 09:58:19 -05:00
shin- 02c211a0dc variable names 2013-04-02 07:13:42 -07:00
shin- c780ff5ae7 More thorough test case, use container.Stop() instead of lxc-kill,
use setStopped() during the restore step
2013-04-02 07:01:43 -07:00
shin- 8edf0ca7f3 Merge branch 'master' into 257-container_real_running_state-fix 2013-04-02 06:37:50 -07:00
Joffrey F 927308cfd9 Merge pull request #317 from dotcloud/307-loginfix
Fix for #307
2013-04-02 03:01:23 -07:00
shin- 8fed600077 Fix for #307 2013-04-02 03:00:21 -07:00
Robert Obryk a83d87abd4 Renamed writeBroadcaster.Close() to CloseWriters(). 2013-04-02 10:45:17 +02:00
Solomon Hykes c808940c04 Refactored CmdRun and CmdAttach to use Container.Attach 2013-04-01 23:52:20 -07:00
Thatcher Peskens 81874ad442 Fixed a lot of language and small things. 2013-04-01 19:11:09 -07:00
Solomon Hykes 3478d6f706 Merge pull request #288 from titanous/expand-contributing
Expand the contributing guidelines
2013-04-01 18:45:18 -07:00
Solomon Hykes 13b6309138 Merge pull request #312 from sa2ajj/devenv-doc-fix
fix code block formatting
2013-04-01 18:40:29 -07:00
Mikhail Sobolev 90db9e7517 fix code block formatting 2013-04-02 04:35:54 +03:00
Thatcher Peskens f15889461d Merge remote-tracking branch 'dotcloud/master' into dhrp/docs 2013-04-01 18:11:46 -07:00
Guillaume J. Charmes dea4194f8b Merge pull request #286 from titanous/285-close-bodies
Close HTTP response bodies
2013-04-01 17:59:22 -07:00
Solomon Hykes e331f1ee0e Merge pull request #305 from fsouza/master
Makefile: simplify "fmt" target
2013-04-01 16:28:29 -07:00
unclejack 0ddc6867fb use xz compression when pushing images to the registry
This makes the xz compression the default.
2013-04-02 02:19:34 +03:00
unclejack 3c5d2e4661 add support for xz compression
This adds xz as a compression option.
xz is alread supported by bsdtar without the external xz program.
2013-04-02 02:16:28 +03:00
Solomon Hykes ff5cb8e864 Images can be removed by short-hand ID. Solves #306. 2013-04-01 16:04:44 -07:00
Solomon Hykes 7ad2e022fb Add test to reproduce issue #306 2013-04-01 16:02:02 -07:00
Mikhail Sobolev f65fc1e766 add host name parameter to "run" command
fixes #243
2013-04-02 01:26:17 +03:00
Mikhail Sobolev dcc9dfb27d make complex options to stand out 2013-04-02 01:26:17 +03:00
Francisco Souza 650dff73bd makefile: simplify "fmt" target, and include -s flag 2013-04-01 18:50:25 -03:00
Solomon Hykes 6d00145076 Merge pull request #304 from paulhammond/mkimage-busybox-fixes
Fix mkimage-busybox
2013-04-01 14:38:00 -07:00
Paul Hammond cc2558bf10 Fix mkimage-busybox 2013-04-01 14:34:12 -07:00
Shawn Siefkas e566b89a5f Shortening the git commit used in the version command 2013-04-01 16:31:33 -05:00
Solomon Hykes 47c4c2abd4 Merge remote-tracking branch 'origin/progress_bar_push_pull' 2013-04-01 13:49:07 -07:00
Solomon Hykes fa5bb5acf1 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-04-01 13:44:19 -07:00
Solomon Hykes 50500cfcb6 Merge pull request #300 from cespare/make-fmt
Add a 'fmt' target to the Makefile.
2013-04-01 13:41:53 -07:00
Guillaume J. Charmes 9e81ab65cb Merge pull request #301 from dotcloud/container_test_improvment-1
Avoid destroy() timeout by closing stdin in TestStart()
2013-04-01 13:36:02 -07:00
Guillaume J. Charmes ff26493fd5 Merge pull request #298 from cespare/cleanup-1
Some style, text, and comment cleanup.
2013-04-01 13:26:40 -07:00
Caleb Spare 9b13d21fc9 Add a 'fmt' target to the Makefile.
A convenience for gofmting all the code, including subpackages.
2013-04-01 13:05:00 -07:00
Caleb Spare 887f509d1d Don't use an interface{} where a string will do. 2013-04-01 12:56:59 -07:00
Caleb Spare 13d2b08638 A few spelling/grammar corrections. 2013-04-01 12:56:50 -07:00
Caleb Spare c298a91f95 Use a *println or *print function instead of *printf where appropriate. 2013-04-01 12:17:00 -07:00
Shawn Siefkas 37a78902db Adding git commit to the version output
The Makefile must be used in order to inject the git commit
via -ldflags.
2013-04-01 13:52:45 -05:00
Caleb Spare 15b3088157 Don't convert []byte to string unnecessarily. 2013-04-01 11:15:40 -07:00
Caleb Spare 7830cf9166 Don't use a strings.Reader where a bytes.Reader will do.
There are several places where a []byte is converted to a string
and then fed into strings.NewReader().
2013-04-01 11:15:10 -07:00
Jonathan Rudenberg 321d94b17e Expand the contributing guidelines 2013-04-01 12:35:04 -04:00
Jonathan Rudenberg 6b59cc8a10 Close HTTP response bodies
Fixes #285.
2013-04-01 09:51:56 -04:00
Guillaume J. Charmes 91b1f9eee9 Avoid destroy() timeout by closing stdin in TestStart() 2013-03-31 22:42:10 -07:00
Solomon Hykes c9a13147fe Merge pull request #238 from johncosta/42-contribution-guidelines
Contribution guidelines
2013-03-31 22:14:18 -07:00
Solomon Hykes 1632566ecb Show shorthand image IDs for convenience. Shorthand IDs (or any non-conflicting prefix) can be used to lookup images 2013-03-31 22:11:55 -07:00
Solomon Hykes a52a28b609 Temporarily disable a broken test (waiting for @creack to fix it), and silence a warning which pollutes unit tests but is complicated to fix 2013-03-31 22:05:14 -07:00
Solomon Hykes 54443c092c gofmt 2013-03-31 22:04:59 -07:00
Guillaume J. Charmes ad1e8a9b0f Add unit test for CmdAttach 2013-03-31 21:48:18 -07:00
Solomon Hykes 29b7ecb017 Merge pull request #272 from dominikh/improve/lazy-ip-allocator
Make IP allocator lazy
2013-03-31 21:04:35 -07:00
Dominik Honnef 6f9a67a7c7 Make IP allocator lazy
Instead of allocating all possible IPs in advance, generate them as
needed.

A loop will cycle through all possible IPs in sequential order,
allocating them as needed and marking them as in use. Once the loop
exhausts all IPs, it will wrap back to the beginning. IPs that are
already in use will be skipped. When an IP is released, it will be
cleared and be available for allocation again.

Two decisions went into this design:

1) Minimize memory footprint by only allocating IPs that are actually
in use

2) Minimize reuse of released IP addresses to avoid sending traffic to
the wrong containers

As a side effect, the functions for IP/Mask<->int conversion have been
rewritten to never be able to fail in order to reduce the amount of
error returns.

Fixes gh-231
2013-04-01 06:02:44 +02:00
Guillaume J. Charmes cfeed391d7 Change the commands unit tests in order to reflect the proper behaviour of CmdRun 2013-03-31 20:52:35 -07:00
Guillaume J. Charmes 8c36e6920a Working in progress: add unit tests for the running state check 2013-03-31 20:14:54 -07:00
Guillaume J. Charmes 3dcaf20d6b Check if the containers are really running when starting docker 2013-03-31 17:40:39 -07:00
Guillaume J. Charmes d949e2804a Add a check to avoid double start (resulting in dockerd to panic) and unit test for it 2013-03-31 14:15:10 -07:00
Guillaume J. Charmes 1fc9405537 Add progress bar on docker push 2013-03-31 13:53:47 -07:00
Guillaume J. Charmes b64dfdd8cd Add a progress bar to docker pull 2013-03-31 13:04:41 -07:00
Solomon Hykes a6779bcae2 Revert regression introduced in 81eac415ad, which caused 'docker run -i' to never close stdin 2013-03-31 02:44:56 -07:00
Solomon Hykes 8293a0d533 Bumped version to 0.1.1 2013-03-31 02:18:04 -07:00
Solomon Hykes 0b9a3c86a2 Show shorthand container IDs for convenience. Shorthand IDs (or any non-conflicting prefix) can be used to lookup containers 2013-03-31 02:02:01 -07:00
Solomon Hykes 5a2a044e24 Merge remote-tracking branch 'origin/125-reattach_attached_run_command-fix' 2013-03-31 00:20:31 -07:00
Guillaume J. Charmes 99f9b69716 Add debug infos in CmdInfo to know the amount of fds and goroutines in use 2013-03-30 10:33:10 -07:00
Guillaume J. Charmes b336d928fe Make sure to close all pipes when detaching client (#228) 2013-03-30 09:47:09 -07:00
Guillaume J. Charmes 4760749402 Close the containers stdin when the process dies 2013-03-30 09:08:53 -07:00
Guillaume J. Charmes 7efde5eb83 Fix a scope issue preventing the close of slave stdin pty (#228) 2013-03-30 09:07:54 -07:00
Guillaume J. Charmes 5252ab697c Store the master ptys in order to close them when the process dies (#228) 2013-03-30 09:05:53 -07:00
Guillaume J. Charmes 41555f67e0 Merge pull request #269 from cespare/gofmt-1
Gofmt.
2013-03-30 12:46:47 -07:00
Robert Obryk 75ba07cb3a Swapped a map for a list in writeBroadcaster. 2013-03-30 16:04:19 +01:00
Robert Obryk 0bdfcfaa33 Make writeBroadcaster safe for concurrent use. 2013-03-30 16:02:22 +01:00
Guillaume J. Charmes 8cceafc834 Add unit test for the #125 scenario. Reattach after client disconnect on stdin allocated container 2013-03-30 06:55:47 -07:00
Caleb Spare 2d4c5ddbdd Gofmt. 2013-03-29 23:58:30 -07:00
Solomon Hykes d1ed28cb94 Merge remote-tracking branch 'robryk/cmdstream-deadlock' 2013-03-29 23:43:02 -07:00
Solomon Hykes 7dbb1eacc1 Merge remote-tracking branch 'origin/improve_container_tests' 2013-03-29 23:41:09 -07:00
Thatcher Peskens e9d17b1f91 Redundant message in basics. 2013-03-29 17:38:31 -07:00
Thatcher Peskens 6437648176 Added a lot of basic instructions on various topics 2013-03-29 17:30:10 -07:00
Robert Obryk 68278b66c5 Added a timeout to TestCmdStreamLargeStderr. 2013-03-29 22:36:36 +01:00
Solomon Hykes f483b214bb Merge remote-tracking branch 'robryk/bufreader-race' 2013-03-29 13:50:33 -07:00
Solomon Hykes f5b458b1dc Merge pull request #250 from metachord/master
Remove unnecessary path parts
2013-03-29 13:42:23 -07:00
Solomon Hykes f7b4f0c193 FIXME: implement a timeout in TestCmdStreamLArgStderr to avoid blocking the whole test suite when it fails 2013-03-29 13:37:52 -07:00
Solomon Hykes 6ede6bc8f2 Comment CmdStream a little bit to facilitate future fixes and contributions 2013-03-29 13:26:02 -07:00
Solomon Hykes fdae64d8d7 Merge remote-tracking branch 'robryk/cmdstream-deadlock' 2013-03-29 13:20:17 -07:00
Solomon Hykes f85e6548c7 Comment to explain CmdStream 2013-03-29 13:18:59 -07:00
Solomon Hykes c937e237ad Merged Ctrl-C interception by @creack 2013-03-29 13:12:04 -07:00
Guillaume J. Charmes 0ebdca5e61 Add unit test for multiple attach / restart 2013-03-29 10:56:49 -07:00
Guillaume J. Charmes 81eac415ad Do not close the stdin of the process when the client deattaches himslef 2013-03-29 09:42:42 -07:00
Guillaume J. Charmes 0b2eee8b33 Fix #108, reattach now works properly 2013-03-29 09:31:47 -07:00
Solomon Hykes d0d5d5ff09 Merge pull request #265 from dotcloud/formating_debug_harmonize
Formating debug harmonize
2013-03-29 21:30:43 -07:00
Solomon Hykes 57dfca052b Merge pull request #266 from dotcloud/do_not_log_stopped_container
Do not log non-running containers
2013-03-29 21:29:19 -07:00
Solomon Hykes 99b36c2c32 Add comments in graph.go 2013-03-29 21:13:59 -07:00
Solomon Hykes b013d93786 Merge remote-tracking branch 'origin/264-remove_cmdAttach_option' 2013-03-29 20:30:43 -07:00
Solomon Hykes b1fa21aa0e Merge remote-tracking branch 'lopter/master' 2013-03-29 20:17:33 -07:00
Louis Opter 9740102990 Fix output in the login command
It was broken because the terminal is in raw mode.

This changeset adds code in the login commmand to do a little bit of
interpretation on the user input (something usually done by the terminal
emulator itself).
2013-03-29 11:39:41 -07:00
Guillaume J. Charmes 0f7a4534c1 Do not log non-running containers 2013-03-29 08:46:06 -07:00
Guillaume J. Charmes 7a565a0479 Remove unused variable from container struct 2013-03-29 08:41:48 -07:00
Guillaume J. Charmes 69c2250ec2 Add some error checking in container monitor 2013-03-29 08:29:59 -07:00
Guillaume J. Charmes d17f78c373 Harmonize the error management. Use fmt.Errorf instead of errors.New 2013-03-29 08:19:42 -07:00
Guillaume J. Charmes ccac5b1382 Add debug infos 2013-03-29 08:18:43 -07:00
Guillaume J. Charmes 9442d6b349 Remove the options of CmdAttach 2013-03-29 07:49:26 -07:00
Guillaume J. Charmes 232dbb1864 Improve the containers unit tests (add error checking) 2013-03-29 07:44:58 -07:00
Robert Obryk 58befe3081 Fix a deadlock in CmdStream.
As per FIXME, CmdStream could have deadlocked if a command printed
enough on stderr. This commit fixes that, but still keeps all of
the stderr output in memory.
2013-03-29 12:55:48 +01:00
John Costa bd3c6793a1 remove dulicated text and correct contributing link 2013-03-29 07:06:58 -04:00
Robert Obryk d52451bcf8 Fix a race condition in bufReader.
The race condition cen be detected by running existing bufReader tests
with Go's race detector.
2013-03-29 11:00:50 +01:00
Maxim Treskin 6d72758f12 Remove unnecessary part of paths to lxc executables 2013-03-29 12:07:25 +07:00
Solomon Hykes 1d6929c8bc Fixed leftover from docs merge. Thanks @cespare for spotting! 2013-03-28 19:18:03 -07:00
Solomon Hykes 48a208baf1 Merging dhrp/docs 2013-03-28 19:12:58 -07:00
Thatcher Peskens 61cf09b2e7 Fixed some links in gettingstarted 2013-03-28 19:03:06 -07:00
Solomon Hykes b51fe837a4 Merge pull request #241 from titanous/cleanup-deps
Remove unneeded sqlite deps from puppet and debian control
2013-03-28 18:45:44 -07:00
Solomon Hykes 4e11e42546 Merge pull request #244 from dotcloud/docs-julien
Docs: Changed the url of the LEGO img to point to the one with copyright
2013-03-28 18:45:20 -07:00
Solomon Hykes ba33d67a1a Test that iptables() looks for iptables in the PATH 2013-03-28 18:44:47 -07:00
Solomon Hykes 70853785b6 Merge remote-tracking branch 'shawnsi/iptables-wrapper' 2013-03-28 18:40:02 -07:00
Solomon Hykes 12a65dc4a8 Merge remote-tracking branch 'titanous/camelize' 2013-03-28 18:23:59 -07:00
Solomon Hykes b67fe1ecb9 Merge pull request #246 from titanous/update-authors
Update AUTHORS and add .mailmap
2013-03-28 18:19:05 -07:00
Jonathan Rudenberg 6bcc55f7d0 Update AUTHORS and add .mailmap 2013-03-28 20:53:54 -04:00
Jonathan Rudenberg a6da7f138c Camelize some snake_case variable names 2013-03-28 20:12:23 -04:00
Julien Barbier d66de319bd Docs: Changed the url of the LEGO img to point to the one with copyright 2013-03-28 17:09:36 -07:00
John Costa 760736b3f3 add contributing guidlines md file 2013-03-28 20:04:21 -04:00
Solomon Hykes 0636c11f0b Merge remote-tracking branch 'origin/165-push_permission_check-fix' 2013-03-28 15:45:00 -07:00
Jonathan Rudenberg 5dc1e66366 Remove unneeded sqlite deps from puppet and debian control 2013-03-28 18:38:53 -04:00
John Costa a5054184a1 move documentation changes to reStructuredText docs under website. https://github.com/dotcloud/docker/issues/42 2013-03-28 16:32:31 -04:00
Thatcher Peskens 09910785c8 Merge remote-tracking branch 'dotcloud/master' into dhrp/docs
Conflicts:
	docs/sources/examples/python_web_app.rst
2013-03-28 12:48:32 -07:00
Shawn Siefkas 523803d633 Handling iptables() errors more usefully during portmapper setup 2013-03-28 14:44:54 -05:00
Thatcher Peskens 4bd21e0d7f Merge remote-tracking branch 'dotcloud/master' into dhrp/docs 2013-03-28 12:36:14 -07:00
Shawn Siefkas c66d2b6a53 Return error when iptables is not found 2013-03-28 14:30:56 -05:00
Thatcher Peskens da69df5f42 Added the lego illustration to the docs.docker.io 'homepage' 2013-03-28 12:27:37 -07:00
Thatcher Peskens 32b58159cd Changed the lego illustration on /README.md to the version which contains the copyright in the image itself. 2013-03-28 12:18:22 -07:00
Shawn Siefkas dfc3904f77 Looking for iptables in PATH 2013-03-28 14:02:50 -05:00
Solomon Hykes 4825d3a537 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-28 11:54:33 -07:00
Ken Cochrane 5c639118d3 fixed some of the syntax in example
The example was broken, I updated it to work with latest version of code.
2013-03-28 15:51:10 -03:00
Thatcher Peskens 9bc7e71f16 Removed $'s from examples to make them easier to copy paste 2013-03-28 11:50:00 -07:00
Solomon Hykes 19316955dd Merge remote-tracking branch 'origin/174-remove_image_twice-fix' 2013-03-28 11:48:41 -07:00
Thatcher Peskens 172f746e4d Fixed links on gettingstarted to point to the right places in docs 2013-03-28 11:44:33 -07:00
Solomon Hykes 47e5d2f5e1 Merge remote-tracking branch 'origin/docs' 2013-03-28 11:12:00 -07:00
Thatcher Peskens 70594bdd16 Merge remote-tracking branch 'dotcloud/master' into local/dotcloud/docs 2013-03-28 10:58:01 -07:00
Ken Cochrane 09e69e45a6 Merge pull request #225 from dhrp/readthedocs
#225 Update the docs to work with http://docs.docker.io
2013-03-28 06:58:21 -07:00
Ken Cochrane 9528b8685f Merge pull request #229 from mynamewastaken/master
Fixed typo in description
2013-03-28 06:55:40 -07:00
mynamewastaken b3cbe87b62 Update README.md
Fixed typo
2013-03-28 02:55:28 -05:00
Guillaume J. Charmes 6a236184af Change hardcoded "0" onto os.Stdin.Fd() 2013-03-27 23:56:36 -07:00
Guillaume J. Charmes 108acc0511 #214 Better signal handling 2013-03-27 23:54:53 -07:00
Charles Hooper e37ce11cfa Merge pull request #227 from chooper/issue226_vagrant
Remove /usr/local/bin/docker from Vagrant VirtualMachine image during provisioning
2013-03-27 22:56:37 -07:00
Charles Hooper fa89076673 Remove /usr/local/bin/docker 2013-03-28 05:28:11 +00:00
Charles Hooper 5aba56e0e0 Merge remote-tracking branch 'upstream/master' 2013-03-28 02:08:04 +00:00
Charles Hooper daa7e4a203 Merge pull request #184 from titanous/simplify-vagrant
vagrant: Simplify provisioning to build from repo
2013-03-27 19:07:20 -07:00
Jonathan Rudenberg a3ab89df2b vagrant: Simplify provisioning to build from repo
This sets up an idiomatic Go workspace in /opt/go with the source
shared from the host directory in
/opt/go/src/github.com/dotcloud/docker and docker installed into
/opt/go
2013-03-27 21:55:25 -04:00
Thatcher Peskens 90fb5dc962 Made all paths "pretty url's" including gettingstarted. 2013-03-27 17:01:50 -07:00
Thatcher Peskens 3b71336edc Made changes to incorporate extermal docs.docker.io. Also took out /documentation/ dir so sources are easier accessible and the folder is not redundant on docs.docker.io/documentation/ 2013-03-27 16:43:13 -07:00
Guillaume J. Charmes baea0a98f8 Add unit test for #174 Delete image already deleted then repulled 2013-03-27 12:09:58 -07:00
Solomon Hykes d8dc6d4583 Merged branch sa2ajj/top-level-makefile 2013-03-27 11:50:01 -07:00
Charles Hooper 95d87f1ac0 Merge remote-tracking branch 'upstream/master' 2013-03-27 14:50:42 +00:00
Charles Hooper 7e9975d00a Merge pull request #205 from crazysim/docker-local-shared
Use the directory where the Vagrantfile is located for SyncFolders instead of a hard-coded "~/docker"
2013-03-27 07:34:58 -07:00
Ken Cochrane 212a044a55 changed docker import to docker pull
changed docker import to docker pull, still need to make sure that the image is in the registry.
2013-03-27 10:44:20 -03:00
Ken Cochrane 165a7f3670 change docker import to docker pull
change docker import to docker pull in the basecommands doc
2013-03-27 10:43:05 -03:00
Ken Cochrane 0d75c68e5e Merge pull request #209 from gottagetmac/patch-1
Fixed typo in command description for pull
2013-03-27 06:06:15 -07:00
Daniel Robinson ff04ce3ddf Fixed typo in command description for pull 2013-03-27 10:02:11 -03:00
Nelson Chen 43213dfc4a use the directory where the vagrantfile is located for mounting 2013-03-26 23:14:50 -07:00
Solomon Hykes 4a086dfc08 Fixed broken examples in docs 2013-03-26 20:28:46 -07:00
Charles Hooper 6b54a439b2 Merge pull request #204 from dhrp/master
Added amazon install path to documentation.
2013-03-26 20:23:21 -07:00
Charles Hooper 00b81936aa Merge pull request #192 from chooper/vagrant11-providers
Fix AWS provisioning with Vagrant
2013-03-26 20:18:09 -07:00
Solomon Hykes b2e16f941d Merge pull request #199 from dotcloud/smalldocs
Small update to docs
2013-03-26 20:12:03 -07:00
Solomon Hykes 72563925a1 Merge pull request #200 from dhrp/update-examples
Update examples
2013-03-26 20:11:07 -07:00
Solomon Hykes f951f7876b Merge pull request #203 from hblanks/remove-run-dash-a
docs - remove references to run -a
2013-03-26 20:08:25 -07:00
Hunter Blanks 7e4ac6c689 docs - remove references to run -a 2013-03-26 19:31:50 -07:00
Charles Hooper 9e5a25c100 Merge remote-tracking branch 'upstream/master' 2013-03-27 02:19:52 +00:00
Charles Hooper 8461196a79 Stop using custom AMI and use standard Ubuntu AMI 2013-03-27 01:41:47 +00:00
Charles Hooper 5bec4b8f04 Fix Rackspace cloud user, remove dupe /home/vagrant definition 2013-03-27 01:41:06 +00:00
Thatcher Peskens 502f772839 not debian, but ubuntu is in base image 2013-03-26 18:28:46 -07:00
Thatcher Peskens 8cfaf658cc Updated hello world examples 2013-03-26 18:21:52 -07:00
Charles Hooper 2b7284db4f Remove duplicate user definition 2013-03-27 01:20:45 +00:00
Charles Hooper 2b090320be Merge remote-tracking branch 'upstream/master' into vagrant11-providers
Conflicts:
	puppet/modules/docker/manifests/init.pp
2013-03-27 01:09:22 +00:00
root 378dacdf1c added copyright for LEGO picture 2013-03-26 17:25:35 -07:00
Thatcher Peskens 8513c179f3 Added files REQUIRED to have succesfull gh-pages deploy (i.c.w. sphinx) 2013-03-26 17:25:26 -07:00
Solomon Hykes a710475726 Merge pull request #135 from amesserl/raxcloud-support
Added support to use docker with Rackspace Cloud Servers
2013-03-26 16:55:01 -07:00
Solomon Hykes a8ae0aafe3 Add unit test for container id format 2013-03-26 16:54:13 -07:00
Jonathan Rudenberg 9518503ebe Remove extraneous rand.Seed 2013-03-26 19:29:53 -04:00
Jonathan Rudenberg 141b5fc7d7 Simplify id generation
Instead of using a SHA-256 of a random number, hex encode 32 bytes
of random data from crypto/rand (sourced from /dev/urandom).
2013-03-26 19:29:44 -04:00
Thatcher Peskens 709849e717 Added Amazon AWS tutorial (can be activated after @sub_'s pull request is accepted. 2013-03-26 16:29:21 -07:00
Solomon Hykes 2ee3db6cd2 Merge pull request #193 from vivekagr/master
Fixed a misspelled command in the docs.
2013-03-26 15:39:48 -07:00
Solomon Hykes 84d1929973 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-26 15:36:07 -07:00
Charles Hooper 195208593d Merge remote-tracking branch 'upstream/master' into HEAD
Conflicts:
	README.md
2013-03-26 22:30:49 +00:00
Solomon Hykes 846a9e8963 When doing a reverse-lookup of an image's tag, if the image has multiple tags, the first tag in alphabetical order will be used 2013-03-26 15:30:16 -07:00
Vivek Agarwal 5cec37de53 Fixed a misspelled command in the docs.
`vagrant up` command was misspelled as `vagant up`.
2013-03-27 03:54:26 +05:30
Thatcher Peskens 261003ceb0 Merge remote-tracking branch 'dotcloud/docs' 2013-03-26 14:52:00 -07:00
Guillaume J. Charmes e260e80814 Merge pull request #190 from dotcloud/189-broken_env_tty_mode-fix
#189 Fix the env in TTY mode
2013-03-26 14:44:30 -07:00
Ken Cochrane 2d71e2a44c Merge pull request #186 from pbogdan/fix-docs-document-title
Improve document <title>'s for the docs.
2013-03-26 14:36:43 -07:00
Thatcher Peskens 84df72222d Typo in macosx tutorial 2013-03-26 14:31:45 -07:00
Piotr Bogdan 08f1e3af48 Improve document <title>'s for the docs. 2013-03-26 21:25:42 +00:00
Charles Hooper afdf29e57f Fix issue where Vagrant AWS deploys outside of my dev account would fail 2013-03-26 21:21:54 +00:00
Daniel Mizyrycki 262be79041 Merge pull request #181 from dhrp/master
These are the necessary changes to tell github to not use jekyill and listen to http://docker.io
2013-03-26 13:20:51 -07:00
Solomon Hykes 8da1810975 Merge remote-tracking branch 'origin/175-auto_download_run-feature' 2013-03-26 13:20:32 -07:00
Solomon Hykes 9df7023497 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-26 13:15:21 -07:00
Solomon Hykes 54fa59c8ec Set the container's hostname to the truncated ID 2013-03-26 13:14:44 -07:00
Solomon Hykes 2664139da4 Example of sharing an image in the README 2013-03-26 13:07:06 -07:00
Solomon Hykes 6bf4a10ed4 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-26 12:57:42 -07:00
Solomon Hykes 7f79fabaee Added missing 'docker pull' to first example 2013-03-26 12:52:11 -07:00
Solomon Hykes 3813fa8a16 Rephrased answer to Q4 in the FAQ 2013-03-26 12:34:23 -07:00
Daniel Mizyrycki 75a116bdaa Add more links and a question to the faq 2013-03-26 12:14:58 -07:00
Thatcher Peskens f87aa7e336 Added files REQUIRED to have succesfull gh-pages deploy (i.c.w. sphinx) 2013-03-26 12:00:46 -07:00
Solomon Hykes 1904003511 Emphasized 'not for production' warning 2013-03-26 11:58:42 -07:00
Solomon Hykes 84cca8afc8 Changed project description in home page 2013-03-26 11:46:51 -07:00
Solomon Hykes 1a96ce552f Merge remote-tracking branch 'dhrp/master' 2013-03-26 11:34:21 -07:00
Solomon Hykes 7db1890c99 New 'make github-deploy' rule to deploy the docs to github-pages 2013-03-26 11:27:36 -07:00
Charles Hooper 5cebc226cc Use new AMI that won't cause issues with cloud-init apply_creds 2013-03-26 17:40:56 +00:00
Thatcher Peskens 1c5162c5a9 Added two user quotes. Cleanup of images. 2013-03-26 10:03:10 -07:00
Solomon Hykes 53641e8b8d Merged documentation 2013-03-26 09:49:10 -07:00
Solomon Hykes 038fb523f1 Merge pull request #168 from johncosta/42-contribution-guidlines
incorporate feedback from https://github.com/dotcloud/docker/issues/42
2013-03-26 09:42:14 -07:00
Solomon Hykes b70858ccae Merge pull request #169 from sa2ajj/no-executable-sources
remove executable bit from lxc_template.go
2013-03-26 09:41:37 -07:00
Thatcher Peskens f7d69601c5 Added line "docker is not ready for production" to tutorials 2013-03-26 08:50:34 -07:00
shin- 2333be46aa Re-enabled help for run command and added client-side error messages when arguments are missing 2013-03-26 08:31:26 -07:00
Mikhail Sobolev f961ec55e7 print the location of the built binary 2013-03-26 17:19:58 +02:00
Mikhail Sobolev 21f55419b7 allow for verbose output from go tools 2013-03-26 17:19:58 +02:00
Mikhail Sobolev a26c58e27e slightly re-phrase the build from source in README 2013-03-26 17:19:58 +02:00
Mikhail Sobolev 5a0010abe9 do not print executed commands 2013-03-26 17:19:58 +02:00
Mikhail Sobolev a57b37ed0e use .gopath/ instead of build/ 2013-03-26 17:19:57 +02:00
Mikhail Sobolev 6b4bc971fd add a test target 2013-03-26 17:19:57 +02:00
Mikhail Sobolev 7009d6c6dd introduce top-level Makefile to build the docker binary 2013-03-26 17:19:54 +02:00
Mikhail Sobolev b2b6d519c5 remove executable bit from lxc_template.go 2013-03-26 16:36:49 +02:00
shin- 3cce89d8ed Fixed issue with misplaced cursor after output 2013-03-26 07:10:31 -07:00
Guillaume J. Charmes cca59081de #189 Fix the env in TTY mode 2013-03-26 07:01:59 -07:00
John Costa e53f45f621 incorporate feedback from https://github.com/dotcloud/docker/issues/42 2013-03-26 09:17:44 -04:00
Guillaume J. Charmes 004a5310d9 Try to fetch missing base only on "not found" error 2013-03-26 05:28:17 -07:00
Guillaume J. Charmes 6ccd473127 Improve the pre-push repository lookup for permisisons 2013-03-26 04:12:08 -07:00
Guillaume J. Charmes 161526d99d Add a lookup before pushing repository to check permissions 2013-03-26 04:12:08 -07:00
Guillaume J. Charmes 069918e1fd #174 Check if the image is already in the garbage before moving it. If it does, remove (really) the older one. 2013-03-26 03:33:47 -07:00
Guillaume J. Charmes 91d78a10c3 #175 Add autodownload on run command 2013-03-26 03:05:10 -07:00
Thatcher Peskens 6f80674d66 Fixed a little problem in the style 2013-03-25 21:16:33 -07:00
Thatcher Peskens 3150a789c1 Fixed a little problem in the style 2013-03-25 21:07:56 -07:00
Thatcher Peskens f37a693825 Improved README 2013-03-25 20:48:04 -07:00
Guillaume J. Charmes 7e540a083f Merge pull request #164 from kencochrane/users
Fixed help commands that were printing double.
2013-03-25 20:18:30 -07:00
Solomon Hykes 522b8bf2c1 Merge branch 'origin/18-termcap_issues-fix' 2013-03-25 20:09:58 -07:00
Thatcher Peskens 243eea36ca Merge remote-tracking branch 'origin/master' 2013-03-25 19:53:14 -07:00
Thatcher Peskens 69b09ccfc8 Merge of docker-website into the docker documentation. 2013-03-25 19:52:52 -07:00
Guillaume J. Charmes 41a2954e4e MakeRaw on given fd instead of 0 2013-03-25 19:31:20 -07:00
Guillaume J. Charmes c85db1003b Force xterm as TERM in tty mode 2013-03-25 19:20:18 -07:00
Solomon Hykes 7943a02cb6 Improved error checking of 'docker pull' by printing body of HTTP error 2013-03-25 18:50:02 -07:00
Solomon Hykes f70bc2c98c Cleaned up error checking of 'docker pull', to be symmetrical to 'docker push' 2013-03-25 18:48:57 -07:00
dhrp 022a1f9957 Updated README.md to prepare for docs merge 2013-03-25 18:46:13 -07:00
Guillaume J. Charmes 211ed0a766 Merge branch '18-termcap_issues-fix' of github.com:dotcloud/docker into 18-termcap_issues-fix 2013-03-25 18:45:07 -07:00
Guillaume J. Charmes 50bee2f811 Fix termcaps on the linux client 2013-03-25 18:44:05 -07:00
Guillaume J. Charmes 922a8648fc Fix termcaps on the linux client 2013-03-25 18:43:25 -07:00
Ken Cochrane c9d93cd333 fixed issue with rmi help showing help twice 2013-03-25 21:35:31 -04:00
Ken Cochrane a9a439183d fixed an issue with the help history command, printed twice 2013-03-25 21:33:56 -04:00
Solomon Hykes e4a69b1044 Cleaned up error checking of 'docker push' 2013-03-25 17:20:55 -07:00
Solomon Hykes b31211cbe9 Cleaned up UI of 'docker push' 2013-03-25 17:20:26 -07:00
Solomon Hykes d01b5894c4 Unit tests fetch their base image with 'docker pull docker-ut' 2013-03-25 17:18:56 -07:00
Guillaume J. Charmes 504663a6ee Skip missing images instead of failing the push 2013-03-25 15:29:42 -07:00
Solomon Hykes bd63ae72e6 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-25 14:25:17 -07:00
Charles Hooper 4c19c9341c Merge remote-tracking branch 'upstream/master' 2013-03-25 19:41:24 +00:00
Sam Alba 222c04a7e7 Merge pull request #154 from dotcloud/153-commitnorepo
Clearer information when listing images
2013-03-25 12:04:57 -07:00
Charles Hooper fcdfd696ec Merge remote-tracking branch 'upstream/master' 2013-03-25 18:24:45 +00:00
shin- c8ca50b483 Fixed issue #158 (docker crashes when docker run is called with not enough arguments) 2013-03-25 07:17:11 -07:00
Guillaume J. Charmes a61e68275a Merge branch 'master' of github.com:dotcloud/docker 2013-03-25 01:29:09 -07:00
Guillaume J. Charmes 6576b19a28 Improve the debug function 2013-03-25 01:29:01 -07:00
Guillaume J. Charmes ceb66fd035 Merge pull request #152 from srid/patch-1
`docker import` doesn't download an image
2013-03-24 16:58:35 -07:00
Guillaume J. Charmes 22598ee572 Merge pull request #155 from sa2ajj/debian-control-fix
fix run-time dependency
2013-03-24 16:54:01 -07:00
Guillaume J. Charmes 52969416bc Merge pull request #147 from dotcloud/146_autologin-feature
#146 Auto login on push
2013-03-24 16:52:50 -07:00
Mikhail Sobolev c61172f9c2 fix run-time dependency 2013-03-25 01:36:59 +02:00
shin- 0786d9ec22 Show <none> instead of an empty string in docker images listing for images with no repository or tag 2013-03-24 15:01:41 -07:00
shin- 938bf4c901 Reverted previous change 2013-03-24 14:53:00 -07:00
shin- 87d4e16568 Quick fix to avoid creating empty-string repositories when committing 2013-03-24 14:38:10 -07:00
Sridhar Ratnakumar 55c8908756 docker import doesn't download an image
```
$ docker import base
Downloading from http://base
Error: Get http://base: lookup base: no such host
```
only `docker pull` does:

```
$ docker pull base
Pulling base...
Pulling repo: https://registry.docker.io/v1/users/base
Pull completed
```
2013-03-24 14:13:08 -07:00
Guillaume J. Charmes 51455b1ee0 Merge pull request #138 from srid/handle-port-mapper-error
handle errors during the creation of port mapper
2013-03-24 10:27:03 -07:00
Ken Cochrane 906626b8f8 Merge pull request #143 from dotcloud/141-142_update_help-fix
141 142 update help fix
2013-03-24 07:07:24 -07:00
Charles Hooper 94b9ca988d Fix missing group "Vagrant" error 2013-03-24 10:49:16 +00:00
Charles Hooper bea7894166 Merge remote-tracking branch 'amesserl/raxcloud-support'
Conflicts:
	Vagrantfile
2013-03-24 10:16:50 +00:00
Solomon Hykes b32436cd2e Prevent container.Kill() from crashing if container.cmd is nil 2013-03-23 19:51:35 -07:00
Solomon Hykes 190e2fa50f Generate full-size SHA256 IDs for images and containers 2013-03-23 19:33:00 -07:00
Solomon Hykes 0d46ddf7b4 'docker commit -m': optional commit message 2013-03-23 19:16:42 -07:00
Solomon Hykes f7eaaa3adb Clean up 'container' environment variable injected by lxc-start 2013-03-23 19:11:00 -07:00
Solomon Hykes 57e2126a02 Bumped version to 0.1.0 2013-03-23 17:48:18 -07:00
Solomon Hykes 5130d3d6ec Merge branch 'graph' 2013-03-23 17:47:33 -07:00
Solomon Hykes 587debf92e Merge branch 'graph' of http://github.com/dotcloud/docker into graph 2013-03-23 17:04:37 -07:00
Solomon Hykes d301c7b98c 'docker images' doesn't show all anonymous images by default - only anonymous heads 2013-03-23 17:03:30 -07:00
Solomon Hykes f43fbda2a4 No more dependency on sqlite 2013-03-23 16:17:01 -07:00
Guillaume J. Charmes e09383bccf Remove json alteration 2013-03-23 14:54:18 -07:00
Solomon Hykes 301a8afff5 Properly cleanup iptables rules inserted in OUTPUT (introduced in 3c6b8bb888) 2013-03-22 22:31:20 -07:00
Sridhar Ratnakumar 371225520f handle errors during the creation of port mapper
example:

  2013/03/22 21:42:55 Unable to setup port networking: Failed to create DOCKER chain

  (which was possibly introduced by commit 3c6b8bb88)
2013-03-22 21:44:01 -07:00
Guillaume J. Charmes eb95e49150 #146 Auto login on push 2013-03-22 19:04:12 -07:00
Guillaume J. Charmes 96010e3ca1 Allow anonymous pulls 2013-03-22 18:46:47 -07:00
Guillaume J. Charmes e55b8b2fd9 Merge pull request #145 from dotcloud/144-login_daemon_mode-fix
Login now works with daemon mode
2013-03-23 20:30:19 -07:00
Guillaume J. Charmes ffe5370e35 Login now works with daemon mode 2013-03-22 18:37:53 -07:00
Guillaume J. Charmes df19863b23 #142 Change the help for push and pull in order for it to be more clear 2013-03-22 18:17:49 -07:00
Guillaume J. Charmes cb3c4af404 #141 Update and order the help 2013-03-22 18:15:44 -07:00
Guillaume J. Charmes bd2a55cd26 Merge branch 'no_root_repo_push' 2013-03-22 17:58:34 -07:00
Guillaume J. Charmes b370acd679 Forbid users to push "root" repositories 2013-03-22 17:58:00 -07:00
Guillaume J. Charmes 5c04d3488a Implement the "library" repository endpoint on the registry 2013-03-22 17:43:11 -07:00
Solomon Hykes 690cae0ef4 Merge pull request #133 from shawnsi/master
Vagrant Provision Touch Up
2013-03-22 15:11:52 -07:00
Solomon Hykes 936bd87a52 Merge pull request #124 from donspaulding/master
Fix typos in the README
2013-03-22 15:10:13 -07:00
Guillaume J. Charmes dc2d930520 Remove the json alterations when decoding 2013-03-22 14:27:10 -07:00
Guillaume J. Charmes 966cddf26b Add some verbosity to the push/pull 2013-03-22 13:21:44 -07:00
Guillaume J. Charmes 6e35f28352 Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 13:10:31 -07:00
Solomon Hykes 0146c80c40 An image embeds the configuration of its parent container ('ContainerConfig') 2013-03-23 14:48:16 -07:00
Solomon Hykes b809dc4271 Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-23 14:18:41 -07:00
Solomon Hykes f37c432bd5 Fixed 'docker inspect' to exit silently when an image doesn't exist 2013-03-23 14:18:35 -07:00
Solomon Hykes d9471bee3d Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-23 12:39:36 -07:00
Solomon Hykes 6ce64e8458 Moved image name into config. runtime.Create() now receives a single Config parameter 2013-03-23 12:39:09 -07:00
Solomon Hykes 031f91df1a runtime.Create receives an image name + Config. The Config includes all required runtime information: command, environment, ports etc. 2013-03-23 12:16:58 -07:00
Guillaume J. Charmes 89763bc8af Remove the lookup before pushing 2013-03-22 13:10:17 -07:00
Guillaume J. Charmes 6e507b9460 Add a Debugf() helper and a -D (debug) flag to docker 2013-03-22 11:44:12 -07:00
Guillaume J. Charmes c57727fd65 Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 11:18:33 -07:00
Guillaume J. Charmes a2e5333a93 Make sure the remote repository exists prior to push 2013-03-22 10:42:13 -07:00
Guillaume J. Charmes 5e6355d182 Fix the lookup method 2013-03-22 10:22:22 -07:00
Joffrey F e4886a9e33 Merge pull request #134 from shawnsi/98-natfix
Fixing Issue #98: Adding DOCKER to output chain during iptables setup
2013-03-22 09:35:07 -07:00
Antony Messerli 95ad9e4573 Adding support for the Rackspace Open Cloud 2013-03-22 11:30:54 -05:00
Shawn Siefkas 3c6b8bb888 Fixing Issue #98: Adding DOCKER to output chain during iptables setup 2013-03-22 11:28:15 -05:00
Shawn Siefkas cff01ec5ec Redirecting docker daemon stdout/stderr to /var/log/dockerd 2013-03-22 10:30:47 -05:00
creack 0c4b639083 Update makefile gotest 2013-03-22 08:04:53 -07:00
creack d1c8eabc63 Fix/Improve push/pull registry 2013-03-22 07:56:44 -07:00
creack c000a5ed75 Remove the possibility to choose the remote name on push 2013-03-22 07:10:52 -07:00
Shawn Siefkas 9542876d2f Waiting to start docker until the fresh binaries have been copied in 2013-03-22 08:48:50 -05:00
creack 899613f788 Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 06:39:08 -07:00
Solomon Hykes 829eeb07f8 'docker run' with no argument no longer hardcodes a default image and command 2013-03-22 20:55:17 -07:00
Solomon Hykes 841c7ac0f9 Deprecated 'docker run -a'. Containers are run in the foreground by default. '-d' enables detached mode 2013-03-22 20:46:14 -07:00
Solomon Hykes 34fbaa5f6d 'docker run -e': set environment variables in a container 2013-03-22 20:36:34 -07:00
Solomon Hykes 9b5f0fac81 Fix 'docker import' to accept urls without explicit http:// scheme 2013-03-22 19:47:32 -07:00
creack 1ed78ee160 Improve (drastically) the push 2013-03-22 06:38:54 -07:00
creack e726bdcce2 Fix the rootPath for auth 2013-03-22 05:52:13 -07:00
creack ab3a57d01b Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 04:44:46 -07:00
Solomon Hykes bc51d961cd Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-22 19:22:24 -07:00
Solomon Hykes 12049f956a 'docker {history,ps,images}': show human-friendly image names when applicable 2013-03-22 19:22:06 -07:00
Solomon Hykes 7952e6befe Merge branch 'master' into graph 2013-03-22 18:30:46 -07:00
Solomon Hykes 72e16f6d96 Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-22 18:27:32 -07:00
Solomon Hykes bf7602bc09 'docker tag': assign a repository+tag to an image 2013-03-22 18:27:18 -07:00
Solomon Hykes 520af226c0 Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-22 17:52:27 -07:00
Solomon Hykes 542c66997f 'docker inspect' can lookup image by repository and tag 2013-03-22 17:52:19 -07:00
Solomon Hykes f8ebeaae10 Removed debug command 'docker mount' 2013-03-22 17:44:12 -07:00
Solomon Hykes 56752158af Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-22 17:40:32 -07:00
Solomon Hykes 09b27f9e8d Fancier output for 'docker history' 2013-03-22 17:22:32 -07:00
creack 77549ad4f6 Improve the error management with the registry communication 2013-03-22 04:44:07 -07:00
creack fc0eac37e4 Put back the "official" repo 2013-03-22 04:37:18 -07:00
creack db8f2a1a9d Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 04:35:19 -07:00
creack 08cb430281 Move the debian makefile to avoid confusions 2013-03-22 04:34:46 -07:00
shin- 9fa3d891c6 Merge branch 'master' of github.com:dotcloud/docker 2013-03-22 04:25:37 -07:00
shin- b00ff47963 Fixing newlines in attached mode 2013-03-22 04:24:03 -07:00
creack e02f7912bc Enforce login for push/pull 2013-03-22 03:43:57 -07:00
creack e4f9a0dca0 Update the help with push/pull 2013-03-22 03:24:37 -07:00
creack 3870ebee6d Add content type to Push 2013-03-22 03:22:36 -07:00
creack 062ebff098 Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 03:10:30 -07:00
creack 0eed4b4386 Add some verbosity to the push/pull features 2013-03-22 03:10:09 -07:00
creack 4307b7dd8e Add authentification to all registry call 2013-03-22 02:57:28 -07:00
creack c72ff318d3 Integrate Auth in runtime and make the config file relative to runtime root 2013-03-22 02:19:39 -07:00
creack 5e561a9d52 Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-22 01:27:16 -07:00
Solomon Hykes 640026ec59 Looking up a tag by repository name will default to REPOSITORY:latest. The empty tag '' is no longer allowed. 2013-03-22 16:07:13 -07:00
creack 11c4294846 Handle push/pull of repositories 2013-03-22 01:25:27 -07:00
Solomon Hykes 1850e8d49c Merge pull request #128 from cespare/markdown-fixes2
Fix numbering in README markdown.
2013-03-21 22:46:22 -07:00
Solomon Hykes afb4a36ffa Merge pull request #130 from dotcloud/113_vagrant-compat
113 vagrant compat
2013-03-21 22:44:38 -07:00
Daniel Mizyrycki 45df6f7801 vagrant; issue #113: normalize whitespaces 2013-03-21 22:26:18 -07:00
Daniel Mizyrycki 6295a02275 vagrant; issue #113: Make Vagrantfile backward compatible with versions < 1.1 2013-03-21 22:16:52 -07:00
dhrp 13e597a5ad create README.md at this place for preview. 2013-03-21 21:47:14 -07:00
Caleb Spare d515e2b06c Fix numbering in README markdown. 2013-03-21 21:46:00 -07:00
Solomon Hykes 41c664cacf Merge pull request #126 from cespare/markdown-fixes
Markdown fixes in the readme.
2013-03-21 18:24:46 -07:00
Caleb Spare 7566006d0d Markdown fixes in the readme. 2013-03-21 18:20:54 -07:00
creack d8fa52b7b5 Comply the tests with golang TIP 2013-03-21 10:31:02 -07:00
creack f246cc9cdd Apply the new WalkHistory prototype to merge 2013-03-21 10:12:05 -07:00
creack da266e6c7b Factorize the pull/push commands and create a registry.go 2013-03-21 10:10:14 -07:00
Solomon Hykes f50dcbe404 Image.ParentCommand and Image.ParentConatiner should be stored 2013-03-21 22:45:22 -07:00
Solomon Hykes cdd62522b6 Merge branch 'graph' of ssh://github.com/dotcloud/docker into graph 2013-03-21 22:21:00 -07:00
Solomon Hykes 1ad69ad415 'docker history': show the history of an image 2013-03-21 21:42:18 -07:00
Solomon Hykes 05ae69a6eb 'docker commit' records parent container id and command, in addition to parent image 2013-03-21 21:13:27 -07:00
Solomon Hykes 8396798eba 'docker commit' can optionally tag the new image into a repository 2013-03-21 20:07:37 -07:00
Solomon Hykes 49a78929c6 Repositories and tags can't have ':' in their name (to allow parsing the REPO:TAG notation) 2013-03-21 20:06:20 -07:00
Solomon Hykes 379d449c44 'docker run' can reference an image by REPOSITORY:TAG 2013-03-21 19:01:55 -07:00
Solomon Hykes d0c776528b Fix a bug which caused repository metadata to be cleared at startup 2013-03-21 19:00:43 -07:00
Solomon Hykes 4af8b711c0 Fixed output quirks in 'docker images' 2013-03-21 18:59:12 -07:00
Solomon Hykes ef711962d5 Folded graph/ back into main package 2013-03-21 17:47:23 -07:00
Solomon Hykes 44faa07b6c First integration of runtime with repositories & tags 2013-03-21 17:35:49 -07:00
Solomon Hykes 680f40c37e graph.RepoStore: first draft of a Repository/Tag on top of the graph 2013-03-21 12:18:47 -07:00
shin- 3aefed2dc2 When lxcbr0 has several associated IPs, default to first one found 2013-03-21 09:19:22 -07:00
Don Spaulding 8ff60ddef4 Typos in the README 2013-03-21 08:39:52 -05:00
creack eef9659c95 merge graph in graph 2013-03-21 06:35:57 -07:00
creack 42cf74d56b POC: push/pull are (kinda) working 2013-03-21 06:33:29 -07:00
creack 04ba4348de Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-21 04:32:04 -07:00
creack 864a8d9aca Merge branch 'graph' of github.com:dotcloud/docker into graph 2013-03-21 03:54:24 -07:00
creack edcfd687ef POC of push/pull for images, pull works, push do push but without the layer 2013-03-21 03:53:27 -07:00
creack 3e8d1dfb69 Enforce model for the json image format 2013-03-21 03:52:58 -07:00
Solomon Hykes b6b5e5cec1 Merged master 2013-03-21 02:13:21 -07:00
Solomon Hykes f783759928 Docker currently doesn't support 32-bit hosts. Let's make that clear by failing right away with an informative message 2013-03-21 02:04:10 -07:00
Solomon Hykes c37d7aad36 Merge branch 'master' into graph 2013-03-21 01:43:32 -07:00
Solomon Hykes d65983f386 No need for a Container.networkManager field: it can be accessed via Container.runtime 2013-03-21 01:43:03 -07:00
Solomon Hykes 1ed13f65fe Merge branch 'master' into graph 2013-03-21 01:38:44 -07:00
Solomon Hykes 377cebe36f Renamed docker*.go to runtime*.go 2013-03-21 01:24:54 -07:00
Solomon Hykes 2f781f2128 Removed 'sparse export' mode, it is deprecated by the new diff-based transfer protocol 2013-03-21 01:24:12 -07:00
Solomon Hykes e627a0da1e Renamed 'docker tar' to 'docker export' for symmetry with 'docker import' 2013-03-21 01:23:00 -07:00
Solomon Hykes 623e91e2e3 Moved Go() to the main package... And got rid of the useless docker/future package 2013-03-21 01:13:55 -07:00
Solomon Hykes deb603aaf4 Removed unused utility future.Pv() 2013-03-21 01:10:44 -07:00
Solomon Hykes 0208b6accd moved GenerateId() to the graph package 2013-03-21 01:07:07 -07:00
Solomon Hykes d7c5d060c4 Moved Download() and progressReader{} to the main package 2013-03-21 00:54:54 -07:00
Solomon Hykes 299d0b2720 Moved HumanDuration() to the main package 2013-03-21 00:52:43 -07:00
Solomon Hykes b8547f31e4 Renamed Docker{} to Runtime{} for clarity 2013-03-21 00:41:15 -07:00
Solomon Hykes 7c57a4cfc0 Simplified the core container API, ported it to the new graph. Some features are missing eg. image 'paths' and tags 2013-03-21 00:25:00 -07:00
Solomon Hykes 84e8c4aa1d Fixed a bug in graph.Graph.Get() 2013-03-21 00:21:32 -07:00
Solomon Hykes 89a140fb75 Removed redundant mount_test.go (graph_test.go already tests the mount ability) 2013-03-21 00:21:03 -07:00
Guillaume J. Charmes 3e9877a30f Merge pull request #122 from srid/patch-1
remove ! from command line
2013-03-20 23:26:50 -07:00
Sridhar Ratnakumar 3bb176d8ae remove ! from command line
bash does not like it

```
$ JOB=$(docker run base /bin/sh -c "while true; do echo Hello world!; sleep 1; done")
bash: !: event not found
$
```
2013-03-20 22:53:42 -07:00
Solomon Hykes 34023558f5 Pruned more semi-useless commands: 'docker cat', 'docker cp', 'docker ls', 'docker write'. Removed outdated commands from help message 2013-03-20 22:48:52 -07:00
Solomon Hykes 9d82bab041 Removed anal warning from 'go vet' 2013-03-20 22:42:50 -07:00
Solomon Hykes 3eff62394b Removed dependency on the fake package in graph unit tests 2013-03-20 22:42:08 -07:00
Solomon Hykes 4d9c324495 Removed extra import 2013-03-20 22:41:31 -07:00
Solomon Hykes 75c866d6a3 Unmount() and Mounted(): utility functions to unmount a mountpoint and check if it's mounted, respectively 2013-03-20 22:41:03 -07:00
Solomon Hykes 6f6eaca861 Removed mount code from container. It belongs in graph 2013-03-20 22:16:02 -07:00
Solomon Hykes ea258c4492 docker/fs is deprecated by docker/graph 2013-03-20 22:15:09 -07:00
Solomon Hykes 240333277a Removed Image.Unmount(). It belongs in container code 2013-03-20 22:13:57 -07:00
Solomon Hykes 9e8278134d Image.Mount(): create rw and rootfs directory if they don't exist 2013-03-20 22:13:28 -07:00
Solomon Hykes c8db980add Image.Changes(): list all changes between an image and a rw directory 2013-03-20 22:12:38 -07:00
Guillaume J. Charmes 3f63e3426e Merge pull request #121 from ezbercih/patch-1
Fix issue #120, initialize TCPAddr w/ field names
2013-03-20 20:25:16 -07:00
Solomon Hykes 31296cc3f7 Removed deprecated or useless commands (cp, layers, reset, mirror, debug, web) 2013-03-20 20:21:59 -07:00
Solomon Hykes 33d2905cde Merge pull request #115 from termie/readme_update
update the dependencies for the dev environment
2013-03-20 15:20:18 -07:00
termie 2048354c8b update the dev requirements in readme
a little pedantic, perhaps, but on a fresh precise image from vagrant I
still needed these two packages to run the commands following it
2013-03-20 20:17:46 +00:00
Solomon Hykes 98542d4497 Merge branch 'master' into graph 2013-03-20 09:41:37 -07:00
shin- 6d580247c2 Removed 'fake' package. 2013-03-20 07:49:38 -07:00
creack ab99e9252d Complete pull request #121, init TCPAddr with named field 2013-03-20 06:02:25 -07:00
ezbercih fac32cda5a Fix issue #120, initialize TCPAddr w/ field names
Current Go tip (+74e65f07a0c8) and likely Go 1.1 does not build docker since net.TCPAddr struct has an additional field now for IPv6:

type TCPAddr struct {
    IP   IP
    Port int
    Zone string // IPv6 scoped addressing zone
}

Initializing the struct with named fields resolves this problem.
2013-03-21 00:11:16 -03:00
Solomon Hykes a3174fd874 Merge pull request #114 from jpetazzo/whiteboard20130319
Images & repositories, what they mean, and the protocol to push/pull them
2013-03-20 00:18:43 -07:00
Solomon Hykes ddf4c79977 Merge pull request #112 from srid/devenv
instructions to compile docker
2013-03-20 00:08:54 -07:00
Jérôme Petazzoni acd51ecea8 add pseudo-spec of images, repositories, push, and pull operations 2013-03-19 20:35:14 -07:00
Sridhar Ratnakumar 4389574aff instructions to compile docker 2013-03-19 20:17:32 -07:00
Solomon Hykes ff2ae90764 Merge pull request #110 from synack/master
Add linux-image-extra instructions to README
2013-03-19 18:46:28 -07:00
Jeremy Grosser 2508b5cef9 Update README.md 2013-03-19 18:45:11 -07:00
Solomon Hykes b1acd0a7b0 Merge pull request #106 from kencochrane/users
change registry address to https from http
2013-03-19 17:42:29 -07:00
Ken Cochrane 8be58d3a7f change registry address to https from http 2013-03-19 16:03:17 -07:00
Solomon Hykes c5051ea0ea Merge pull request #102 from fkautz/master
Some minor cleanup of cleanup in Makefile
2013-03-19 10:07:21 -07:00
Solomon Hykes 3c1db4ca43 Ported test for image deletion 2013-03-18 17:57:18 -07:00
Solomon Hykes 33c2f07fc7 Bumped version to 0.0.3 2013-03-18 00:35:48 -07:00
Solomon Hykes 33f6a0aaf5 docker/graph: a store for filesystem images and the graph of their relationships 2013-03-18 00:15:35 -07:00
Solomon Hykes 1480bff3a9 Contributing to Docker 2013-03-17 19:32:06 -07:00
Solomon Hykes ac7fa37be3 Moved Ubuntu install to the top 2013-03-17 19:10:47 -07:00
Solomon Hykes 065eca9d4e Docker: the Linux container runtime 2013-03-17 19:09:51 -07:00
Frederick F. Kautz IV 6316b99556 Adding clean to beginning of all for cleaner builds. 2013-03-17 11:59:59 -07:00
Frederick F. Kautz IV bb9ce6b287 Adding bin to clean 2013-03-17 11:54:05 -07:00
Frederick F. Kautz IV a3ca3e9218 Makefile cleanup renamed to clean to match standard conventions. 2013-03-17 11:53:37 -07:00
Solomon Hykes a030c1bd24 Removed out-of-date examples directory (see README and the wiki for examples) 2013-03-16 18:36:52 -07:00
Solomon Hykes 4a1c40364c Removed redundant file used by debian packaging 2013-03-16 18:35:43 -07:00
Solomon Hykes 4015f8dd34 Merge pull request #101 from silas/examples
Fix docker run typo
2013-03-16 18:32:26 -07:00
Silas Sewell 16f132b156 Fix docker run typo 2013-03-16 16:16:13 -04:00
Solomon Hykes b400d78b19 Merge pull request #100 from silas/readme
Fix coffee typo
2013-03-16 12:35:43 -07:00
Silas Sewell e190c27d10 Fix coffee typo 2013-03-16 15:19:58 -04:00
Solomon Hykes da47420af6 Removed unnecessary step in the README 2013-03-16 11:39:49 -07:00
Solomon Hykes b55e461122 Merge pull request #84 from kencochrane/users
added docker login command to login to docker registry
2013-03-16 02:14:07 -07:00
Ken Cochrane c4640689af added better error message 2013-03-15 15:04:36 -07:00
Ken Cochrane 27ad71e025 fixed missing varible, error: 2013-03-15 14:48:42 -07:00
Ken Cochrane 0a35db8fd0 added more debugging/ error catching 2013-03-15 14:41:55 -07:00
Solomon Hykes c1c60a2835 Merge branch 'vagrant11-providers' of ssh://github.com/chooper/docker 2013-03-15 14:25:42 -07:00
Solomon Hykes ad29305630 Merged branch packaging 2013-03-15 14:20:02 -07:00
Solomon Hykes bb5b7897a4 Merged branch 79-rmi_regexp-feature 2013-03-15 14:08:02 -07:00
Solomon Hykes 5d569a8741 Merge branch 'packaging' 2013-03-15 13:45:08 -07:00
Ken Cochrane 878ae25980 made sure password was required, fixed docker help issue with login prompt 2013-03-15 07:49:27 -07:00
creack b2cf5041cd Change the errors.New() with fmt.Errof 2013-03-15 03:58:43 -07:00
Guillaume J. Charmes 29210802dd Merge pull request #95 from dotcloud/93-test_restore_fail-fix
Make sure that Deregister really returns an error instead of just displaying it
2013-03-15 03:10:27 -07:00
creack 54b44e3705 Make sure that Deregister really returns an error instead of just displaying it 2013-03-15 03:07:33 -07:00
Guillaume J. Charmes 9ff6dd767a Allow ping within a container. Issue #91
Allow the net_raw capability
2013-03-15 02:37:02 -07:00
creack 137af244ee Add the health check to mount_test 2013-03-15 02:33:37 -07:00
creack 030a33aa23 Implement more extensive tests on the image deletion 2013-03-15 02:22:50 -07:00
creack 2839a59018 Add a test to make sure we are root before starting the tests on docker package 2013-03-15 02:03:41 -07:00
creack 82188b9c2c Issue #92 Run go test on fs package as non-root 2013-03-15 02:01:48 -07:00
creack 4d80958b01 Add entries to the gitignore 2013-03-15 01:28:09 -07:00
creack cb7819cbc5 Correct the help 2013-03-15 00:47:02 -07:00
Daniel Mizyrycki 0e0d76b7ac packaging; issue #30: Add tests to Makefile 2013-03-14 23:13:31 -07:00
creack eab39dc3fa Add local build and tests to makefile 2013-03-14 23:13:31 -07:00
Daniel Mizyrycki 47a5a51d39 packaging; issue #30: Adjust package metadata 2013-03-14 23:13:31 -07:00
Daniel Mizyrycki 76bd475648 packaging; issue #30: Improved dependencies 2013-03-14 23:13:31 -07:00
Solomon Hykes 9598b28933 Moved debian-specific files to ./deb, minor fixes to Makefile 2013-03-14 23:13:31 -07:00
Solomon Hykes d615496c4c Gradual improvement of Makefile 2013-03-14 23:13:31 -07:00
Daniel Mizyrycki 3b9c97a5d5 packaging; issue #30: Add ubuntu deb packaging 2013-03-14 23:13:31 -07:00
Charles Hooper 7cc0a07524 Fix *other* typo in README 2013-03-15 04:29:10 +00:00
Charles Hooper 98a4d38eb4 Fix typo in README 2013-03-15 04:26:59 +00:00
Charles Hooper 8c83484bf2 Add AWS support for running Docker on AWS 2013-03-15 04:22:07 +00:00
Ken Cochrane 7ec6a311f8 Removed the extra newline char from the messages 2013-03-14 20:23:45 -07:00
Ken Cochrane d94a5b7d05 only show status message if there is one to show 2013-03-14 20:21:03 -07:00
Ken Cochrane 9b94d89b06 added more message changes 2013-03-14 19:43:42 -07:00
Ken Cochrane f1cf5074f5 cleaned up the code a little 2013-03-14 18:43:02 -07:00
Ken Cochrane 18519f12ae merge from master 2013-03-14 18:23:45 -07:00
creack c0b9afbf01 Add image removal unit tests 2013-03-14 18:07:33 -07:00
Ken Cochrane 5e79c4394a changed scanf's with fscanf's, so it works better for remote 2013-03-14 17:53:10 -07:00
Ken Cochrane be20f3c518 added ability to login/register to the docker registry, via the docker login command 2013-03-14 17:43:59 -07:00
Solomon Hykes c65c1738b5 Merge remote-tracking branch 'origin/65-autodownload_unittest_image' 2013-03-14 12:07:46 -07:00
Guillaume J. Charmes 7188dcd96d Merge pull request #78 from dotcloud/77-undeleted_mountpoint-fix
Fix undeleted mountpoint on destroy
2013-03-14 10:09:00 -07:00
creack 3cd34f1039 Issue #79, add regexp to the CmdRmi command 2013-03-14 09:27:06 -07:00
Guillaume J. Charmes fcc0af9f5b Fix undeleted mountpoint on destroy
Issue #77, Now mountpoints are always deleted even when not currently mounted.
2013-03-14 04:06:57 -07:00
creack de753d5a90 issue #65 automatically download busybox for unittests 2013-03-14 02:43:16 -07:00
creack e5e66716df Move commands into docker 2013-03-14 02:43:16 -07:00
Solomon Hykes b97f9e8148 Removed web console feature for now - let's focus on the core before adding bells and whistles 2013-03-13 22:13:38 -07:00
Solomon Hykes cc18df61b9 Bumped version to 0.0.2 2013-03-13 22:12:24 -07:00
Solomon Hykes 681e452832 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-13 21:50:25 -07:00
Solomon Hykes a444327ab6 Fixed a bug which causes 'docker import' to fail silently when bsdtar is not installed 2013-03-13 21:50:15 -07:00
Solomon Hykes 722d4c92c3 Merge pull request #74 from jpetazzo/contrib-install-sh
Update get.docker.io install script for single-binary
2013-03-13 21:30:45 -07:00
Solomon Hykes 27512332d0 Merge pull request #73 from jpetazzo/contrib-make-busybox-image
Add contrib/ directory, README, and script to create a basic busybox image
2013-03-13 21:30:22 -07:00
Solomon Hykes 0b5e223b4e Moved debian-specific files to ./deb, minor fixes to Makefile 2013-03-13 21:22:30 -07:00
Solomon Hykes 78ef1ba32f Gradual improvement of Makefile 2013-03-13 21:11:05 -07:00
jpetazzo e81d7132fa Update get.docker.io install script for single-binary 2013-03-14 03:29:56 +00:00
jpetazzo c74408d7b8 Add contrib/ directory, README, and script to create a basic busybox image 2013-03-14 03:16:42 +00:00
jpetazzo 71c997dc83 Add contrib/ directory, README, and script to create a basic busybox image 2013-03-14 03:13:00 +00:00
Solomon Hykes a1712ea6d3 Merge pull request #72 from chooper/master
Create /var/lib/docker so new installs don't fail
2013-03-13 19:51:12 -07:00
Solomon Hykes a216712f3c 'docker images' lists images in reverse creation order 2013-03-13 19:09:19 -07:00
Charles Hooper 2b8c79d74c Merge remote-tracking branch 'upstream/master' 2013-03-14 01:49:46 +00:00
Charles Hooper 06553a756b Create docker directories *before* allocating a LayerStore 2013-03-14 01:48:50 +00:00
Solomon Hykes c78cbbd002 Changed image mirror to http://get.docker.io/images 2013-03-13 18:37:53 -07:00
Charles Hooper 3686feaccc Minor formatting changes to ProgressReader. Newlines when complete 2013-03-14 01:37:47 +00:00
Solomon Hykes d6c3d02205 gofmt 2013-03-13 18:37:00 -07:00
Daniel Mizyrycki 09d96656a0 packaging; issue #30: Add ubuntu deb packaging 2013-03-13 17:08:04 -07:00
Andy Rothfusz e614690f07 spelling fix 2013-03-13 16:06:57 -07:00
Solomon Hykes 3a6c2e48f9 Merge pull request #61 from synack/master
Add a makefile to make life easier
2013-03-13 15:44:22 -07:00
Solomon Hykes 0f952a7dbb Removed deprecated docker/image module 2013-03-13 15:36:22 -07:00
Solomon Hykes 1b34630b8c Cleaned up fs.LayerStore.AddLayer() 2013-03-13 14:20:07 -07:00
Solomon Hykes 68e173ad50 Merge branch store_register_refactor 2013-03-13 14:09:04 -07:00
Solomon Hykes 8f81feb1f0 Merge branch 'pull-missing' of ssh://github.com/chooper/docker 2013-03-13 13:50:47 -07:00
Solomon Hykes ce20fbfff6 Improved output of 'docker inspect' 2013-03-13 13:48:00 -07:00
Ken Cochrane f0a65207ab changed the fs.store.Register and fs.store.Create, so that it is a little cleaner, and easier to reuse. Also added a unit test 2013-03-13 13:35:34 -07:00
Ken Cochrane fde01381d5 puppet fixes for recent vagrant changes 2013-03-13 13:31:23 -07:00
Ken Cochrane d479efc01e updated Vagrant to support new single binary, and exposing the vagrant shared folder, and setting some ENV variables 2013-03-13 13:30:13 -07:00
Solomon Hykes f3d826447d Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-13 13:24:16 -07:00
Solomon Hykes f5f26a510f 'docker inspect' supports pinned versions again (eg. 'docker inspect PATH:revision') 2013-03-13 13:23:59 -07:00
Guillaume J. Charmes aaaf56e62f Merge pull request #64 from dotcloud/32-aufs_delete_fix
32 aufs delete fix
2013-03-13 13:04:55 -07:00
Guillaume J. Charmes 804abddec1 Add fixme for the change detection 2013-03-13 13:03:29 -07:00
Charles Hooper 8c2ff9374c Merge branch 'master' into pull-missing 2013-03-13 19:51:08 +00:00
Solomon Hykes 89245360e8 Merged branch 28-standalone 2013-03-13 12:23:37 -07:00
Solomon Hykes 8d5f683dc4 Fixed formatting in README 2013-03-13 12:00:13 -07:00
Solomon Hykes d614e91b62 Added usage exmaples to the README 2013-03-13 11:58:15 -07:00
Solomon Hykes baf6988d87 Updated README 2013-03-13 11:46:09 -07:00
Charles Hooper fae8284b16 Merge branch 'master' into pull-missing
Conflicts:
	image/image.go
	server/server.go
2013-03-13 18:33:48 +00:00
Solomon Hykes 895e145e61 README: removed superfluous install step 2013-03-13 11:28:52 -07:00
Solomon Hykes 41e0c74fd0 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-03-13 11:27:23 -07:00
Solomon Hykes d54ff35f02 Moved download binaries to get.docker.io 2013-03-13 11:27:06 -07:00
shin- c3622a963d Re-enabled docker rmi 2013-03-13 11:14:37 -07:00
creack 77272bea9c Merge branch 'master' into 32-aufs_delete_fix 2013-03-13 01:18:55 -07:00
creack 7cc512c7c0 Fix issue #32, aufs now take into consideration deleted files 2013-03-13 01:17:03 -07:00
Solomon Hykes 745edc49cd Merge dockerd into docker. 'docker -d' runs in daemon mode. For all other commands, docker auto-detects whether to run standalone or to remote-control the daemon 2013-03-13 00:29:40 -07:00
Solomon Hykes 86854ffbc5 Merged master 2013-03-12 21:53:34 -07:00
Solomon Hykes 070bc0bb6d Merged version option by @kencochrane 2013-03-12 20:59:47 -07:00
Ken Cochrane e20a74d247 fixed formatting issue 2013-03-12 17:34:15 -07:00
Charles Hooper b0265e0a38 Remove Curl function from future 2013-03-12 23:06:07 +00:00
Charles Hooper b5c1cd7991 Only update download/untar progress every 1%. Related to #49 2013-03-12 23:02:50 +00:00
Charles Hooper 2feefb4375 Fix "no such image" bug in docker run, introduced last commit. Ref #49,#50 2013-03-12 22:13:21 +00:00
Charles Hooper 1bfd827701 Add native Go downloading functionality with progress bar. Ref #49, #50 2013-03-12 22:08:10 +00:00
Solomon Hykes d2cba75d5f Removed interactive mode ('docker -i'). Cool UI experiment but seems more trouble than it's worth 2013-03-12 15:05:41 -07:00
Charles Hooper 49554f47f6 Add Download method for native Go downloading (to replace curl). Catch 404s.
Ref: #49, #50
2013-03-12 20:50:11 +00:00
creack 453d49573c Put back the github.com path for the import 2013-03-12 11:59:27 -07:00
Charles Hooper 8e0986caec Error gracefully when an image is not found on pull. Addresses #50 and comments from #49 2013-03-12 05:49:57 +00:00
Charles Hooper b8219b5275 Don't allow images with colons in name and reject pegging versions on pull/import. Addresses #49 and #52 2013-03-12 04:31:49 +00:00
Charles Hooper 63edf8a4a1 Use ioutil.NopCloser instead of opening /dev/null for ReadCloser in CmdRun. Related to #31 2013-03-12 03:18:34 +00:00
Charles Hooper f6d64738d0 Pull missing images on run. Addresses #31.
chooper@chimay:~/projects/docker/bin$ ./docker images
	NAME                ID                  CREATED             PARENT
	chooper@chimay:~/projects/docker/bin$ ./docker run -a base echo "hello world"
	Downloading from http://s3.amazonaws.com/docker.io/images/base
	Unpacking to base
	######################################################################## 100.0%
	base:e9cb4ad9173245ac
	hello world
	chooper@chimay:~/projects/docker/bin$ ./docker run -a base echo "hello world"
	hello world
	chooper@chimay:~/projects/docker/bin$ ./docker run -a nosuchimage echo "hello world"
	Downloading from http://s3.amazonaws.com/docker.io/images/nosuchimage
	Unpacking to nosuchimage
	######################################################################## 100.0%
	Error: Error downloading image: nosuchimage
	chooper@chimay:~/projects/docker/bin$
2013-03-12 02:58:39 +00:00
170 changed files with 20855 additions and 4120 deletions
+13 -2
View File
@@ -1,6 +1,17 @@
.vagrant
.vagrant*
bin
docker/docker
dockerd/dockerd
.*.swp
a.out
*.orig
build_src
command-line-arguments.test
.flymake*
docker.test
auth/auth.test
.idea
.DS_Store
docs/_build
docs/_static
docs/_templates
.gopath/
+16
View File
@@ -0,0 +1,16 @@
# Generate AUTHORS: git log --all --format='%aN <%aE>' | sort -uf | grep -v vagrant-ubuntu-12
<charles.hooper@dotcloud.com> <chooper@plumata.com>
<daniel.mizyrycki@dotcloud.com> <daniel@dotcloud.com>
<daniel.mizyrycki@dotcloud.com> <mzdaniel@glidelink.net>
Guillaume J. Charmes <guillaume.charmes@dotcloud.com> creack <charmes.guillaume@gmail.com>
<guillaume.charmes@dotcloud.com> <guillaume@dotcloud.com>
<kencochrane@gmail.com> <KenCochrane@gmail.com>
<sridharr@activestate.com> <github@srid.name>
Thatcher Peskens <thatcher@dotcloud.com> dhrp <thatcher@dotcloud.com>
Thatcher Peskens <thatcher@dotcloud.com> dhrp <thatcher@gmx.net>
Jérôme Petazzoni <jerome.petazzoni@dotcloud.com> jpetazzo <jerome.petazzoni@dotcloud.com>
Jérôme Petazzoni <jerome.petazzoni@dotcloud.com> <jp@enix.org>
Joffrey F <joffrey@dotcloud.com>
<joffrey@dotcloud.com> <f.joffrey@gmail.com>
Tim Terhorst <mynamewastaken+git@gmail.com>
Andy Smith <github@anarkystic.com>
+38
View File
@@ -0,0 +1,38 @@
Andrea Luzzardi <aluzzardi@gmail.com>
Andy Rothfusz <github@metaliveblog.com>
Andy Smith <github@anarkystic.com>
Antony Messerli <amesserl@rackspace.com>
Brian McCallister <brianm@skife.org>
Caleb Spare <cespare@gmail.com>
Charles Hooper <charles.hooper@dotcloud.com>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com>
Daniel Robinson <gottagetmac@gmail.com>
Dominik Honnef <dominik@honnef.co>
Don Spaulding <donspauldingii@gmail.com>
ezbercih <cem.ezberci@gmail.com>
Frederick F. Kautz IV <fkautz@alumni.cmu.edu>
Guillaume J. Charmes <guillaume.charmes@dotcloud.com>
Hunter Blanks <hunter@twilio.com>
Jeff Lindsay <progrium@gmail.com>
Jeremy Grosser <jeremy@synack.me>
Joffrey F <joffrey@dotcloud.com>
John Costa <john.costa@gmail.com>
Jonathan Rudenberg <jonathan@titanous.com>
Julien Barbier <write0@gmail.com>
Jérôme Petazzoni <jerome.petazzoni@dotcloud.com>
Ken Cochrane <kencochrane@gmail.com>
Kevin J. Lynagh <kevin@keminglabs.com>
Louis Opter <kalessin@kalessin.fr>
Mikhail Sobolev <mss@mawhrin.net>
Nelson Chen <crazysim@gmail.com>
Niall O'Higgins <niallo@unworkable.org>
Piotr Bogdan <ppbogdan@gmail.com>
Sam Alba <sam.alba@gmail.com>
Shawn Siefkas <shawn.siefkas@meredith.com>
Silas Sewell <silas@sewell.org>
Solomon Hykes <solomon@dotcloud.com>
Sridhar Ratnakumar <sridharr@activestate.com>
Thatcher Peskens <thatcher@dotcloud.com>
Tim Terhorst <mynamewastaken+git@gmail.com>
Troy Howard <thoward37@gmail.com>
Vivek Agarwal <me@vivek.im>
+93
View File
@@ -0,0 +1,93 @@
# Contributing to Docker
Want to hack on Docker? Awesome! There are instructions to get you
started on the website: http://docker.io/gettingstarted.html
They are probably not perfect, please let us know if anything feels
wrong or incomplete.
## Contribution guidelines
### Pull requests are always welcome
We are always thrilled to receive pull requests, and do our best to
process them as fast as possible. Not sure if that typo is worth a pull
request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be
discouraged! If there's a problem with the implementation, hopefully you
received feedback on what to improve.
We're trying very hard to keep Docker lean and focused. We don't want it
to do everything for everybody. This means that we might decide against
incorporating a new feature. However, there might be a way to implement
that feature *on top of* docker.
### Discuss your design on the mailing list
We recommend discussing your plans [on the mailing
list](https://groups.google.com/forum/?fromgroups#!forum/docker-club)
before starting to code - especially for more ambitious contributions.
This gives other contributors a chance to point you in the right
direction, give feedback on your design, and maybe point out if someone
else is working on the same thing.
### Create issues...
Any significant improvement should be documented as [a github
issue](https://github.com/dotcloud/docker/issues) before anybody
starts working on it.
### ...but check for existing issues first!
Please take a moment to check that an issue doesn't already exist
documenting your bug report or improvement proposal. If it does, it
never hurts to add a quick "+1" or "I have this problem too". This will
help prioritize the most common problems and requests.
### Conventions
Fork the repo and make changes on your fork in a feature branch:
- If it's a bugfix branch, name it XXX-something where XXX is the number of the
issue
- If it's a feature branch, create an enhancement issue to announce your
intentions, and name it XXX-something where XXX is the number of the issue.
Submit unit tests for your changes. Go has a great test framework built in; use
it! Take a look at existing tests for inspiration. Run the full test suite on
your branch before submitting a pull request.
Make sure you include relevant updates or additions to documentation when
creating or modifying features.
Write clean code. Universally formatted code promotes ease of writing, reading,
and maintenance. Always run `go fmt` before committing your changes. Most
editors have plugins that do this automatically, and there's also a git
pre-commit hook:
```
curl -o .git/hooks/pre-commit https://raw.github.com/edsrzf/gofmt-git-hook/master/fmt-check && chmod +x .git/hooks/pre-commit
```
Pull requests descriptions should be as clear as possible and include a
reference to all the issues that they address.
Code review comments may be added to your pull request. Discuss, then make the
suggested modifications and push additional commits to your feature branch. Be
sure to post a comment after pushing. The new commits will show up in the pull
request automatically, but the reviewers will not be notified unless you
comment.
Before the pull request is merged, make sure that you squash your commits into
logical units of work using `git rebase -i` and `git push -f`. After every
commit the test suite should be passing. Include documentation changes in the
same commit so that a revert would remove all traces of the feature or fix.
Commits that fix or close an issue should include a reference like `Closes #XXX`
or `Fixes #XXX`, which will automatically close the issue when merged.
Add your name to the AUTHORS file, but make sure the list is sorted and your
name and email address match your git configuration. The AUTHORS file is
regenerated occasionally from the git commit history, so a mismatch may result
in your changes being overwritten.
+44 -16
View File
@@ -1,23 +1,51 @@
GOPATH := $(PWD)/env
BUILDPATH := $(PWD)/build
DOCKER_PACKAGE := github.com/dotcloud/docker
all: docker.o dockerd.o
BUILD_DIR := $(CURDIR)/.gopath
env:
mkdir -p ${BUILDPATH} ${GOPATH}/src/github.com/dotcloud/
ln -s $(PWD) ${GOPATH}/src/github.com/dotcloud/docker
GOPATH ?= $(BUILD_DIR)
export GOPATH
deps:
GOPATH=${GOPATH} go get github.com/kr/pty
GOPATH=${GOPATH} go get github.com/mattn/go-sqlite3
GOPATH=${GOPATH} go get github.com/shykes/gorp
GO_OPTIONS ?=
ifeq ($(VERBOSE), 1)
GO_OPTIONS += -v
endif
GIT_COMMIT = $(shell git rev-parse --short HEAD)
GIT_STATUS = $(shell test -n "`git status --porcelain`" && echo "+CHANGES")
BUILD_OPTIONS = -ldflags "-X main.GIT_COMMIT $(GIT_COMMIT)$(GIT_STATUS)"
SRC_DIR := $(GOPATH)/src
DOCKER_DIR := $(SRC_DIR)/$(DOCKER_PACKAGE)
DOCKER_MAIN := $(DOCKER_DIR)/docker
DOCKER_BIN_RELATIVE := bin/docker
DOCKER_BIN := $(CURDIR)/$(DOCKER_BIN_RELATIVE)
.PHONY: all clean test
all: $(DOCKER_BIN)
$(DOCKER_BIN): $(DOCKER_DIR)
@mkdir -p $(dir $@)
@(cd $(DOCKER_MAIN); go get $(GO_OPTIONS); go build $(GO_OPTIONS) $(BUILD_OPTIONS) -o $@)
@echo $(DOCKER_BIN_RELATIVE) is created.
$(DOCKER_DIR):
@mkdir -p $(dir $@)
@ln -sf $(CURDIR)/ $@
clean:
go clean
rm -rf env build
@rm -rf $(dir $(DOCKER_BIN))
ifeq ($(GOPATH), $(BUILD_DIR))
@rm -rf $(BUILD_DIR)
else ifneq ($(DOCKER_DIR), $(realpath $(DOCKER_DIR)))
@rm -f $(DOCKER_DIR)
endif
docker.o: env deps
GOPATH=${GOPATH} go build -o ${BUILDPATH}/docker docker/docker.go
test: all
@(cd $(DOCKER_DIR); sudo -E go test $(GO_OPTIONS))
dockerd.o: env deps
GOPATH=${GOPATH} go build -o ${BUILDPATH}/dockerd dockerd/dockerd.go
fmt:
@gofmt -s -l -w .
+181 -30
View File
@@ -1,17 +1,17 @@
Docker is a process manager with superpowers
============================================
Docker: the Linux container runtime
===================================
It encapsulates heterogeneous payloads in Standard Containers, and runs them on any server with strong guarantees of isolation and repeatability.
Docker complements LXC with a high-level API which operates at the process level. It runs unix processes with strong guarantees of isolation and repeatability across servers.
Is is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
Docker is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
<img src="http://bricks.argz.com/bricksfiles/lego/07000/7823/012.jpg"/>
![Docker L](docs/sources/static_files/lego_docker.jpg "Docker")
* *Heterogeneous payloads*: any combination of binaries, libraries, configuration files, scripts, virtualenvs, jars, gems, tarballs, you name it. No more juggling between domain-specific tools. Docker can deploy and run them all.
* *Any server*: docker can run on any x64 machine with a modern linux kernel - whether it's a laptop, a bare metal server or a VM. This makes it perfect for multi-cloud deployments.
* *Isolation*: docker isolates processes from each other and from the underlying host, using lightweight containers.
* *Isolation*: docker isolates processes from each other and from the underlying host, using lightweight containers.
* *Repeatability*: because containers are isolated in their own filesystem, they behave the same regardless of where, when, and alongside what they run.
@@ -25,13 +25,13 @@ Notable features
* Network isolation: each process container runs in its own network namespace, with a virtual interface and IP address of its own.
* Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremeley fast, memory-cheap and disk-cheap.
* Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremely fast, memory-cheap and disk-cheap.
* Logging: the standard streams (stdout/stderr/stdin) of each process container is collected and logged for real-time or batch retrieval.
* Logging: the standard streams (stdout/stderr/stdin) of each process container are collected and logged for real-time or batch retrieval.
* Change management: changes to a container's filesystem can be committed into a new image and re-used to create more containers. No templating or manual configuration required.
* Interactive shell: docker can allocate a pseudo-tty and attach to the standard input of any container, for example to run a throaway interactive shell.
* Interactive shell: docker can allocate a pseudo-tty and attach to the standard input of any container, for example to run a throwaway interactive shell.
@@ -50,11 +50,64 @@ Under the hood, Docker is built on the following components:
* [lxc](http://lxc.sourceforge.net/), a set of convenience scripts to simplify the creation of linux containers.
Setup instructions
Install instructions
==================
Requirements
------------
Building from source
--------------------
1. Make sure you have a [Go language](http://golang.org) compiler.
On a Debian/wheezy or Ubuntu 12.10 install the package:
```bash
$ sudo apt-get install golang-go
```
2. Execute ``make``
This command will install all necessary dependencies and build the
executable that you can find in ``bin/docker``
3. Should you like to see what's happening, run ``make`` with ``VERBOSE=1`` parameter:
```bash
$ make VERBOSE=1
```
Installing on Ubuntu 12.04 and 12.10
------------------------------------
1. Install dependencies:
```bash
sudo apt-get install lxc wget bsdtar curl
sudo apt-get install linux-image-extra-`uname -r`
```
The `linux-image-extra` package is needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.
2. Install the latest docker binary:
```bash
wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz
tar -xf docker-master.tgz
```
3. Run your first container!
```bash
cd docker-master
sudo ./docker pull base
sudo ./docker run -i -t base /bin/bash
```
Consider adding docker to your `PATH` for simplicity.
Installing on other Linux distributions
---------------------------------------
Right now, the officially supported distributions are:
@@ -63,34 +116,132 @@ Right now, the officially supported distributions are:
Docker probably works on other distributions featuring a recent kernel, the AUFS patch, and up-to-date lxc. However this has not been tested.
Some streamlined (but possibly outdated) installation paths' are available from the website: http://docker.io/documentation/
Installation
---------------
1. Set up your host of choice on a physical / virtual machine
2. Assume root identity on your newly installed environment (`sudo -s`)
3. Type the following commands:
Usage examples
==============
apt-get update
apt-get install lxc wget bsdtar curl
Running an interactive shell
----------------------------
4. Download the latest docker binaries: `wget http://docker.io.s3.amazonaws.com/builds/$(uname -s)/$(uname -m)/docker-master.tgz` ([Or get the Linux/x86_64 binaries here](http://docker.io.s3.amazonaws.com/builds/Linux/x86_64/docker-master.tgz) )
5. Extract the contents of the tar file `tar -xf docker-master.tar.gz`
6. Launch the docker daemon in the background `./dockerd &`
7. Download a base image `./docker pull base`
8. Run your first container! `./docker run -i -a -t base /bin/bash`
9. Start exploring `./docker --help`
```bash
# Download a base image
docker pull base
Consider adding docker and dockerd to your `PATH` for simplicity.
# Run an interactive shell in the base image,
# allocate a tty, attach stdin and stdout
docker run -i -t base /bin/bash
```
Starting a long-running worker process
--------------------------------------
```bash
# Run docker in daemon mode
(docker -d || echo "Docker daemon already running") &
# Start a very useful long-running process
JOB=$(docker run -d base /bin/sh -c "while true; do echo Hello world; sleep 1; done")
# Collect the output of the job so far
docker logs $JOB
# Kill the job
docker kill $JOB
```
Listing all running containers
------------------------------
```bash
docker ps
```
Share your own image!
---------------------
```bash
docker pull base
CONTAINER=$(docker run -d base apt-get install -y curl)
docker commit -m "Installed curl" $CONTAINER $USER/betterbase
docker push $USER/betterbase
```
Expose a service on a TCP port
------------------------------
```bash
# Expose port 4444 of this container, and tell netcat to listen on it
JOB=$(docker run -d -p 4444 base /bin/nc -l -p 4444)
# Which public port is NATed to my container?
PORT=$(docker port $JOB 4444)
# Connect to the public port via the host's public address
echo hello world | nc $(hostname) $PORT
# Verify that the network connection worked
echo "Daemon received: $(docker logs $JOB)"
```
Contributing to Docker
======================
Want to hack on Docker? Awesome! There are instructions to get you started on the website: http://docs.docker.io/en/latest/contributing/contributing/
They are probably not perfect, please let us know if anything feels wrong or incomplete.
Note
----
We also keep the documentation in this repository. The website documentation is generated using sphinx using these sources.
Please find it under docs/sources/ and read more about it https://github.com/dotcloud/docker/master/docs/README.md
Please feel free to fix / update the documentation and send us pull requests. More tutorials are also welcome.
Setting up a dev environment
----------------------------
Instructions that have been verified to work on Ubuntu 12.10,
```bash
sudo apt-get -y install lxc wget bsdtar curl golang git
export GOPATH=~/go/
export PATH=$GOPATH/bin:$PATH
mkdir -p $GOPATH/src/github.com/dotcloud
cd $GOPATH/src/github.com/dotcloud
git clone git@github.com:dotcloud/docker.git
cd docker
go get -v github.com/dotcloud/docker/...
go install -v github.com/dotcloud/docker/...
```
Then run the docker daemon,
```bash
sudo $GOPATH/bin/docker -d
```
Run the `go install` command (above) to recompile docker.
What is a Standard Container?
-----------------------------
=============================
Docker defines a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependency, regardless of the underlying machine and the contents of the container.
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependencies, regardless of the underlying machine and the contents of the container.
The spec for Standard Containers is currently work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
The spec for Standard Containers is currently a work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
A great analogy for this is the shipping container. Just like Standard Containers are a fundamental unit of software delivery, shipping containers (http://bricks.argz.com/ins/7823-1/12) are a fundamental unit of physical delivery.
@@ -101,7 +252,7 @@ Just like shipping containers, Standard Containers define a set of STANDARD OPER
### 2. CONTENT-AGNOSTIC
Just like shipping containers, Standard Containers are CONTENT-AGNOSTIC: all standard operations have the same effect regardless of the contents. A shipping container will be stacked in exactly the same way whether it contains Vietnamese powder coffe or spare Maserati parts. Similarly, Standard Containers are started or uploaded in the same way whether they contain a postgres database, a php application with its dependencies and application server, or Java build artifacts.
Just like shipping containers, Standard Containers are CONTENT-AGNOSTIC: all standard operations have the same effect regardless of the contents. A shipping container will be stacked in exactly the same way whether it contains Vietnamese powder coffee or spare Maserati parts. Similarly, Standard Containers are started or uploaded in the same way whether they contain a postgres database, a php application with its dependencies and application server, or Java build artifacts.
### 3. INFRASTRUCTURE-AGNOSTIC
Vendored
+43 -86
View File
@@ -1,100 +1,57 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant::Config.run do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.
# Every Vagrant virtual environment requires a box to build off of.
def v10(config)
config.vm.box = "quantal64_3.5.0-25"
# The url from where the 'config.vm.box' box will be fetched if it
# doesn't already exist on the user's system.
config.vm.box_url = "http://get.docker.io/vbox/ubuntu/12.10/quantal64_3.5.0-25.box"
# Boot with a GUI so you can see the screen. (Default is headless)
# config.vm.boot_mode = :gui
config.vm.share_folder "v-data", "/opt/go/src/github.com/dotcloud/docker", File.dirname(__FILE__)
# Assign this VM to a host-only network IP, allowing you to access it
# via the IP. Host-only networks can talk to the host machine as well as
# any other machines on the same network, but cannot be accessed (through this
# network interface) by any external networks.
# config.vm.network :hostonly, "192.168.33.10"
# Ensure puppet is installed on the instance
config.vm.provision :shell, :inline => "apt-get -qq update; apt-get install -y puppet"
# Assign this VM to a bridged network, allowing you to connect directly to a
# network using the host's network device. This makes the VM appear as another
# physical device on your network.
# config.vm.network :bridged
# Forward a port from the guest to the host, which allows for outside
# computers to access the VM, whereas host only networking does not.
# config.vm.forward_port 80, 8080
# Share an additional folder to the guest VM. The first argument is
# an identifier, the second is the path on the guest to mount the
# folder, and the third is the path on the host to the actual folder.
# config.vm.share_folder "v-data", "/vagrant_data", "../data"
# Enable provisioning with Puppet stand alone. Puppet manifests
# are contained in a directory path relative to this Vagrantfile.
# You will need to create the manifests directory and a manifest in
# the file quantal64.pp in the manifests_path directory.
#
# An example Puppet manifest to provision the message of the day:
#
# # group { "puppet":
# # ensure => "present",
# # }
# #
# # File { owner => 0, group => 0, mode => 0644 }
# #
# # file { '/etc/motd':
# # content => "Welcome to your Vagrant-built virtual machine!
# # Managed by Puppet.\n"
# # }
#
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "quantal64.pp"
puppet.module_path = "puppet/modules"
end
# Enable provisioning with chef solo, specifying a cookbooks path, roles
# path, and data_bags path (all relative to this Vagrantfile), and adding
# some recipes and/or roles.
#
# config.vm.provision :chef_solo do |chef|
# chef.cookbooks_path = "../my-recipes/cookbooks"
# chef.roles_path = "../my-recipes/roles"
# chef.data_bags_path = "../my-recipes/data_bags"
# chef.add_recipe "mysql"
# chef.add_role "web"
#
# # You may also specify custom JSON attributes:
# chef.json = { :mysql_password => "foo" }
# end
# Enable provisioning with chef server, specifying the chef server URL,
# and the path to the validation key (relative to this Vagrantfile).
#
# The Opscode Platform uses HTTPS. Substitute your organization for
# ORGNAME in the URL and validation key.
#
# If you have your own Chef Server, use the appropriate URL, which may be
# HTTP instead of HTTPS depending on your configuration. Also change the
# validation key to validation.pem.
#
# config.vm.provision :chef_client do |chef|
# chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
# chef.validation_key_path = "ORGNAME-validator.pem"
# end
#
# If you're using the Opscode platform, your validator client is
# ORGNAME-validator, replacing ORGNAME with your organization name.
#
# IF you have your own Chef Server, the default validation client name is
# chef-validator, unless you changed the configuration.
#
# chef.validation_client_name = "ORGNAME-validator"
end
Vagrant::VERSION < "1.1.0" and Vagrant::Config.run do |config|
v10(config)
end
Vagrant::VERSION >= "1.1.0" and Vagrant.configure("1") do |config|
v10(config)
end
Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
config.vm.provider :aws do |aws|
config.vm.box = "dummy"
config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
aws.access_key_id = ENV["AWS_ACCESS_KEY_ID"]
aws.secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
aws.keypair_name = ENV["AWS_KEYPAIR_NAME"]
aws.ssh_private_key_path = ENV["AWS_SSH_PRIVKEY"]
aws.region = "us-east-1"
aws.ami = "ami-ae9806c7"
aws.ssh_username = "ubuntu"
aws.instance_type = "t1.micro"
end
config.vm.provider :rackspace do |rs|
config.vm.box = "dummy"
config.vm.box_url = "https://github.com/mitchellh/vagrant-rackspace/raw/master/dummy.box"
config.ssh.private_key_path = ENV["RS_PRIVATE_KEY"]
rs.username = ENV["RS_USERNAME"]
rs.api_key = ENV["RS_API_KEY"]
rs.public_key_path = ENV["RS_PUBLIC_KEY"]
rs.flavor = /512MB/
rs.image = /Ubuntu/
end
config.vm.provider :virtualbox do |vb|
config.vm.box = "quantal64_3.5.0-25"
config.vm.box_url = "http://get.docker.io/vbox/ubuntu/12.10/quantal64_3.5.0-25.box"
end
end
+21 -6
View File
@@ -1,4 +1,4 @@
package image
package docker
import (
"errors"
@@ -7,12 +7,15 @@ import (
"os/exec"
)
type Archive io.Reader
type Compression uint32
const (
Uncompressed Compression = iota
Bzip2
Gzip
Xz
)
func (compression *Compression) Flag() string {
@@ -21,6 +24,8 @@ func (compression *Compression) Flag() string {
return "j"
case Gzip:
return "z"
case Xz:
return "J"
}
return ""
}
@@ -40,6 +45,9 @@ func Untar(archive io.Reader, path string) error {
return nil
}
// CmdStream executes a command, and returns its stdout as a stream.
// If the command fails to run or doesn't complete successfully, an error
// will be returned, including anything written on stderr.
func CmdStream(cmd *exec.Cmd) (io.Reader, error) {
stdout, err := cmd.StdoutPipe()
if err != nil {
@@ -50,22 +58,29 @@ func CmdStream(cmd *exec.Cmd) (io.Reader, error) {
return nil, err
}
pipeR, pipeW := io.Pipe()
errChan := make(chan []byte)
// Collect stderr, we will use it in case of an error
go func() {
errText, e := ioutil.ReadAll(stderr)
if e != nil {
errText = []byte("(...couldn't fetch stderr: " + e.Error() + ")")
}
errChan <- errText
}()
// Copy stdout to the returned pipe
go func() {
_, err := io.Copy(pipeW, stdout)
if err != nil {
pipeW.CloseWithError(err)
}
errText, e := ioutil.ReadAll(stderr)
if e != nil {
errText = []byte("(...couldn't fetch stderr: " + e.Error() + ")")
}
errText := <-errChan
if err := cmd.Wait(); err != nil {
// FIXME: can this block if stderr outputs more than the size of StderrPipe()'s buffer?
pipeW.CloseWithError(errors.New(err.Error() + ": " + string(errText)))
} else {
pipeW.Close()
}
}()
// Run the command and return the pipe
if err := cmd.Start(); err != nil {
return nil, err
}
+24 -1
View File
@@ -1,12 +1,35 @@
package image
package docker
import (
"io"
"io/ioutil"
"os"
"os/exec"
"testing"
"time"
)
func TestCmdStreamLargeStderr(t *testing.T) {
cmd := exec.Command("/bin/sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello")
out, err := CmdStream(cmd)
if err != nil {
t.Fatalf("Failed to start command: " + err.Error())
}
errCh := make(chan error)
go func() {
_, err := io.Copy(ioutil.Discard, out)
errCh <- err
}()
select {
case err := <-errCh:
if err != nil {
t.Fatalf("Command should not have failed (err=%s...)", err.Error()[:100])
}
case <-time.After(5 * time.Second):
t.Fatalf("Command did not complete in 5 seconds; probable deadlock")
}
}
func TestCmdStreamBad(t *testing.T) {
badCmd := exec.Command("/bin/sh", "-c", "echo hello; echo >&2 error couldn\\'t reverse the phase pulser; exit 1")
out, err := CmdStream(badCmd)
+168
View File
@@ -0,0 +1,168 @@
package auth
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
)
// Where we store the config file
const CONFIGFILE = ".dockercfg"
// the registry server we want to login against
const REGISTRY_SERVER = "https://registry.docker.io"
type AuthConfig struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
rootPath string `json:-`
}
func NewAuthConfig(username, password, email, rootPath string) *AuthConfig {
return &AuthConfig{
Username: username,
Password: password,
Email: email,
rootPath: rootPath,
}
}
// create a base64 encoded auth string to store in config
func EncodeAuth(authConfig *AuthConfig) string {
authStr := authConfig.Username + ":" + authConfig.Password
msg := []byte(authStr)
encoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))
base64.StdEncoding.Encode(encoded, msg)
return string(encoded)
}
// decode the auth string
func DecodeAuth(authStr string) (*AuthConfig, error) {
decLen := base64.StdEncoding.DecodedLen(len(authStr))
decoded := make([]byte, decLen)
authByte := []byte(authStr)
n, err := base64.StdEncoding.Decode(decoded, authByte)
if err != nil {
return nil, err
}
if n > decLen {
return nil, fmt.Errorf("Something went wrong decoding auth config")
}
arr := strings.Split(string(decoded), ":")
if len(arr) != 2 {
return nil, fmt.Errorf("Invalid auth configuration file")
}
password := strings.Trim(arr[1], "\x00")
return &AuthConfig{Username: arr[0], Password: password}, nil
}
// load up the auth config information and return values
// FIXME: use the internal golang config parser
func LoadConfig(rootPath string) (*AuthConfig, error) {
confFile := path.Join(rootPath, CONFIGFILE)
if _, err := os.Stat(confFile); err != nil {
return &AuthConfig{}, fmt.Errorf("The Auth config file is missing")
}
b, err := ioutil.ReadFile(confFile)
if err != nil {
return nil, err
}
arr := strings.Split(string(b), "\n")
origAuth := strings.Split(arr[0], " = ")
origEmail := strings.Split(arr[1], " = ")
authConfig, err := DecodeAuth(origAuth[1])
if err != nil {
return nil, err
}
authConfig.Email = origEmail[1]
authConfig.rootPath = rootPath
return authConfig, nil
}
// save the auth config
func saveConfig(rootPath, authStr string, email string) error {
lines := "auth = " + authStr + "\n" + "email = " + email + "\n"
b := []byte(lines)
err := ioutil.WriteFile(path.Join(rootPath, CONFIGFILE), b, 0600)
if err != nil {
return err
}
return nil
}
// try to register/login to the registry server
func Login(authConfig *AuthConfig) (string, error) {
storeConfig := false
reqStatusCode := 0
var status string
var errMsg string
var reqBody []byte
jsonBody, err := json.Marshal(authConfig)
if err != nil {
errMsg = fmt.Sprintf("Config Error: %s", err)
return "", errors.New(errMsg)
}
// using `bytes.NewReader(jsonBody)` here causes the server to respond with a 411 status.
b := strings.NewReader(string(jsonBody))
req1, err := http.Post(REGISTRY_SERVER+"/v1/users", "application/json; charset=utf-8", b)
if err != nil {
errMsg = fmt.Sprintf("Server Error: %s", err)
return "", errors.New(errMsg)
}
reqStatusCode = req1.StatusCode
defer req1.Body.Close()
reqBody, err = ioutil.ReadAll(req1.Body)
if err != nil {
errMsg = fmt.Sprintf("Server Error: [%#v] %s", reqStatusCode, err)
return "", errors.New(errMsg)
}
if reqStatusCode == 201 {
status = "Account Created\n"
storeConfig = true
} else if reqStatusCode == 400 {
// FIXME: This should be 'exists', not 'exist'. Need to change on the server first.
if string(reqBody) == "Username or email already exist" {
client := &http.Client{}
req, err := http.NewRequest("GET", REGISTRY_SERVER+"/v1/users", nil)
req.SetBasicAuth(authConfig.Username, authConfig.Password)
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
if resp.StatusCode == 200 {
status = "Login Succeeded\n"
storeConfig = true
} else {
status = fmt.Sprintf("Login: %s", body)
return "", errors.New(status)
}
} else {
status = fmt.Sprintf("Registration: %s", reqBody)
return "", errors.New(status)
}
} else {
status = fmt.Sprintf("[%s] : %s", reqStatusCode, reqBody)
return "", errors.New(status)
}
if storeConfig {
authStr := EncodeAuth(authConfig)
saveConfig(authConfig.rootPath, authStr, authConfig.Email)
}
return status, nil
}
+23
View File
@@ -0,0 +1,23 @@
package auth
import (
"testing"
)
func TestEncodeAuth(t *testing.T) {
newAuthConfig := &AuthConfig{Username: "ken", Password: "test", Email: "test@example.com"}
authStr := EncodeAuth(newAuthConfig)
decAuthConfig, err := DecodeAuth(authStr)
if err != nil {
t.Fatal(err)
}
if newAuthConfig.Username != decAuthConfig.Username {
t.Fatal("Encode Username doesn't match decoded Username")
}
if newAuthConfig.Password != decAuthConfig.Password {
t.Fatal("Encode Password doesn't match decoded Password")
}
if authStr != "a2VuOnRlc3Q=" {
t.Fatal("AuthString encoding isn't correct.")
}
}
+4 -25
View File
@@ -1,4 +1,4 @@
package fs
package docker
import (
"fmt"
@@ -33,24 +33,15 @@ func (change *Change) String() string {
return fmt.Sprintf("%s %s", kind, change.Path)
}
func (store *Store) Changes(mp *Mountpoint) ([]Change, error) {
func Changes(layers []string, rw string) ([]Change, error) {
var changes []Change
image, err := store.Get(mp.Image)
if err != nil {
return nil, err
}
layers, err := image.layers()
if err != nil {
return nil, err
}
err = filepath.Walk(mp.Rw, func(path string, f os.FileInfo, err error) error {
err := filepath.Walk(rw, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
// Rebase path
path, err = filepath.Rel(mp.Rw, path)
path, err = filepath.Rel(rw, path)
if err != nil {
return err
}
@@ -113,15 +104,3 @@ func (store *Store) Changes(mp *Mountpoint) ([]Change, error) {
}
return changes, nil
}
// Reset removes all changes to the filesystem, reverting it to its initial state.
func (mp *Mountpoint) Reset() error {
if err := os.RemoveAll(mp.Rw); err != nil {
return err
}
// We removed the RW directory itself along with its content: let's re-create an empty one.
if err := mp.createFolders(); err != nil {
return err
}
return nil
}
-126
View File
@@ -1,126 +0,0 @@
package client
import (
"../future"
"../rcli"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"path/filepath"
)
// Run docker in "simple mode": run a single command and return.
func SimpleMode(args []string) error {
var oldState *State
var err error
if IsTerminal(0) && os.Getenv("NORAW") == "" {
oldState, err = MakeRaw(0)
if err != nil {
return err
}
defer Restore(0, oldState)
}
// FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
// CloseWrite(), which we need to cleanly signal that stdin is closed without
// closing the connection.
// See http://code.google.com/p/go/issues/detail?id=3345
conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...)
if err != nil {
return err
}
receive_stdout := future.Go(func() error {
_, err := io.Copy(os.Stdout, conn)
return err
})
send_stdin := future.Go(func() error {
_, err := io.Copy(conn, os.Stdin)
if err := conn.CloseWrite(); err != nil {
log.Printf("Couldn't send EOF: " + err.Error())
}
return err
})
if err := <-receive_stdout; err != nil {
return err
}
if oldState != nil {
Restore(0, oldState)
}
if !IsTerminal(0) {
if err := <-send_stdin; err != nil {
return err
}
}
return nil
}
// Run docker in "interactive mode": run a bash-compatible shell capable of running docker commands.
func InteractiveMode(scripts ...string) error {
// Determine path of current docker binary
dockerPath, err := exec.LookPath(os.Args[0])
if err != nil {
return err
}
dockerPath, err = filepath.Abs(dockerPath)
if err != nil {
return err
}
// Create a temp directory
tmp, err := ioutil.TempDir("", "docker-shell")
if err != nil {
return err
}
defer os.RemoveAll(tmp)
// For each command, create an alias in temp directory
// FIXME: generate this list dynamically with introspection of some sort
// It might make sense to merge docker and dockerd to keep that introspection
// within a single binary.
for _, cmd := range []string{
"help",
"run",
"ps",
"pull",
"put",
"rm",
"kill",
"wait",
"stop",
"start",
"restart",
"logs",
"diff",
"commit",
"attach",
"info",
"tar",
"web",
"images",
"docker",
} {
if err := os.Symlink(dockerPath, path.Join(tmp, cmd)); err != nil {
return err
}
}
// Run $SHELL with PATH set to temp directory
rcfile, err := ioutil.TempFile("", "docker-shell-rc")
if err != nil {
return err
}
defer os.Remove(rcfile.Name())
io.WriteString(rcfile, "enable -n help\n")
os.Setenv("PATH", tmp+":"+os.Getenv("PATH"))
os.Setenv("PS1", "\\h docker> ")
shell := exec.Command("/bin/bash", append([]string{"--rcfile", rcfile.Name()}, scripts...)...)
shell.Stdin = os.Stdin
shell.Stdout = os.Stdout
shell.Stderr = os.Stderr
if err := shell.Run(); err != nil {
return err
}
return nil
}
-8
View File
@@ -1,8 +0,0 @@
package client
import "syscall"
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
)
-8
View File
@@ -1,8 +0,0 @@
package client
import "syscall"
const (
getTermios = syscall.TCGETS
setTermios = syscall.TCSETS
)
+953
View File
@@ -0,0 +1,953 @@
package docker
import (
"bytes"
"encoding/json"
"fmt"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/rcli"
"io"
"log"
"net/http"
"net/url"
"runtime"
"strconv"
"strings"
"text/tabwriter"
"time"
"unicode"
)
const VERSION = "0.1.3"
var GIT_COMMIT string
func (srv *Server) Name() string {
return "docker"
}
// FIXME: Stop violating DRY by repeating usage here and in Subcmd declarations
func (srv *Server) Help() string {
help := "Usage: docker COMMAND [arg...]\n\nA self-sufficient runtime for linux containers.\n\nCommands:\n"
for _, cmd := range [][]string{
{"attach", "Attach to a running container"},
{"commit", "Create a new image from a container's changes"},
{"diff", "Inspect changes on a container's filesystem"},
{"export", "Stream the contents of a container as a tar archive"},
{"history", "Show the history of an image"},
{"images", "List images"},
{"import", "Create a new filesystem image from the contents of a tarball"},
{"info", "Display system-wide information"},
{"inspect", "Return low-level information on a container"},
{"kill", "Kill a running container"},
{"login", "Register or Login to the docker registry server"},
{"logs", "Fetch the logs of a container"},
{"port", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT"},
{"ps", "List containers"},
{"pull", "Pull an image or a repository from the docker registry server"},
{"push", "Push an image or a repository to the docker registry server"},
{"restart", "Restart a running container"},
{"rm", "Remove a container"},
{"rmi", "Remove an image"},
{"run", "Run a command in a new container"},
{"start", "Start a stopped container"},
{"stop", "Stop a running container"},
{"tag", "Tag an image into a repository"},
{"version", "Show the docker version information"},
{"wait", "Block until a container stops, then print its exit code"},
} {
help += fmt.Sprintf(" %-10.10s%s\n", cmd[0], cmd[1])
}
return help
}
// 'docker login': login / register a user to registry service.
func (srv *Server) CmdLogin(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
// Read a line on raw terminal with support for simple backspace
// sequences and echo.
//
// This function is necessary because the login command must be done in a
// raw terminal for two reasons:
// - we have to read a password (without echoing it);
// - the rcli "protocol" only supports cannonical and raw modes and you
// can't tune it once the command as been started.
var readStringOnRawTerminal = func(stdin io.Reader, stdout io.Writer, echo bool) string {
char := make([]byte, 1)
buffer := make([]byte, 64)
var i = 0
for i < len(buffer) {
n, err := stdin.Read(char)
if n > 0 {
if char[0] == '\r' || char[0] == '\n' {
stdout.Write([]byte{'\n'})
break
} else if char[0] == 127 || char[0] == '\b' {
if i > 0 {
if echo {
stdout.Write([]byte{'\b', ' ', '\b'})
}
i--
}
} else if !unicode.IsSpace(rune(char[0])) &&
!unicode.IsControl(rune(char[0])) {
if echo {
stdout.Write(char)
}
buffer[i] = char[0]
i++
}
}
if err != nil {
if err != io.EOF {
fmt.Fprintf(stdout, "Read error: %v\n", err)
}
break
}
}
return string(buffer[:i])
}
var readAndEchoString = func(stdin io.Reader, stdout io.Writer) string {
return readStringOnRawTerminal(stdin, stdout, true)
}
var readString = func(stdin io.Reader, stdout io.Writer) string {
return readStringOnRawTerminal(stdin, stdout, false)
}
cmd := rcli.Subcmd(stdout, "login", "", "Register or Login to the docker registry server")
if err := cmd.Parse(args); err != nil {
return nil
}
var username string
var password string
var email string
fmt.Fprint(stdout, "Username (", srv.runtime.authConfig.Username, "): ")
username = readAndEchoString(stdin, stdout)
if username == "" {
username = srv.runtime.authConfig.Username
}
if username != srv.runtime.authConfig.Username {
fmt.Fprint(stdout, "Password: ")
password = readString(stdin, stdout)
if password == "" {
return fmt.Errorf("Error : Password Required")
}
fmt.Fprint(stdout, "Email (", srv.runtime.authConfig.Email, "): ")
email = readAndEchoString(stdin, stdout)
if email == "" {
email = srv.runtime.authConfig.Email
}
} else {
password = srv.runtime.authConfig.Password
email = srv.runtime.authConfig.Email
}
newAuthConfig := auth.NewAuthConfig(username, password, email, srv.runtime.root)
status, err := auth.Login(newAuthConfig)
if err != nil {
fmt.Fprintln(stdout, "Error:", err)
} else {
srv.runtime.authConfig = newAuthConfig
}
if status != "" {
fmt.Fprint(stdout, status)
}
return nil
}
// 'docker wait': block until a container stops
func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "wait", "[OPTIONS] NAME", "Block until a container stops, then print its exit code.")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
for _, name := range cmd.Args() {
if container := srv.runtime.Get(name); container != nil {
fmt.Fprintln(stdout, container.Wait())
} else {
return fmt.Errorf("No such container: %s", name)
}
}
return nil
}
// 'docker version': show version information
func (srv *Server) CmdVersion(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
fmt.Fprintf(stdout, "Version:%s\n", VERSION)
fmt.Fprintf(stdout, "Git Commit:%s\n", GIT_COMMIT)
return nil
}
// 'docker info': display system-wide information.
func (srv *Server) CmdInfo(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
images, _ := srv.runtime.graph.All()
var imgcount int
if images == nil {
imgcount = 0
} else {
imgcount = len(images)
}
cmd := rcli.Subcmd(stdout, "info", "", "Display system-wide information.")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() > 0 {
cmd.Usage()
return nil
}
fmt.Fprintf(stdout, "containers: %d\nversion: %s\nimages: %d\n",
len(srv.runtime.List()),
VERSION,
imgcount)
if !rcli.DEBUG_FLAG {
return nil
}
fmt.Fprintln(stdout, "debug mode enabled")
fmt.Fprintf(stdout, "fds: %d\ngoroutines: %d\n", getTotalUsedFds(), runtime.NumGoroutine())
return nil
}
func (srv *Server) CmdStop(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "stop", "[OPTIONS] NAME", "Stop a running container")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
for _, name := range cmd.Args() {
if container := srv.runtime.Get(name); container != nil {
if err := container.Stop(); err != nil {
return err
}
fmt.Fprintln(stdout, container.ShortId())
} else {
return fmt.Errorf("No such container: %s", name)
}
}
return nil
}
func (srv *Server) CmdRestart(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "restart", "[OPTIONS] NAME", "Restart a running container")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
for _, name := range cmd.Args() {
if container := srv.runtime.Get(name); container != nil {
if err := container.Restart(); err != nil {
return err
}
fmt.Fprintln(stdout, container.ShortId())
} else {
return fmt.Errorf("No such container: %s", name)
}
}
return nil
}
func (srv *Server) CmdStart(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "start", "[OPTIONS] NAME", "Start a stopped container")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
for _, name := range cmd.Args() {
if container := srv.runtime.Get(name); container != nil {
if err := container.Start(); err != nil {
return err
}
fmt.Fprintln(stdout, container.ShortId())
} else {
return fmt.Errorf("No such container: %s", name)
}
}
return nil
}
func (srv *Server) CmdInspect(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "inspect", "[OPTIONS] CONTAINER", "Return low-level information on a container")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
name := cmd.Arg(0)
var obj interface{}
if container := srv.runtime.Get(name); container != nil {
obj = container
} else if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil {
obj = image
} else {
// No output means the object does not exist
// (easier to script since stdout and stderr are not differentiated atm)
return nil
}
data, err := json.Marshal(obj)
if err != nil {
return err
}
indented := new(bytes.Buffer)
if err = json.Indent(indented, data, "", " "); err != nil {
return err
}
if _, err := io.Copy(stdout, indented); err != nil {
return err
}
stdout.Write([]byte{'\n'})
return nil
}
func (srv *Server) CmdPort(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "port", "[OPTIONS] CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() != 2 {
cmd.Usage()
return nil
}
name := cmd.Arg(0)
privatePort := cmd.Arg(1)
if container := srv.runtime.Get(name); container == nil {
return fmt.Errorf("No such container: %s", name)
} else {
if frontend, exists := container.NetworkSettings.PortMapping[privatePort]; !exists {
return fmt.Errorf("No private port '%s' allocated on %s", privatePort, name)
} else {
fmt.Fprintln(stdout, frontend)
}
}
return nil
}
// 'docker rmi NAME' removes all images with the name NAME
func (srv *Server) CmdRmi(stdin io.ReadCloser, stdout io.Writer, args ...string) (err error) {
cmd := rcli.Subcmd(stdout, "rmimage", "[OPTIONS] IMAGE", "Remove an image")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
for _, name := range cmd.Args() {
if err := srv.runtime.graph.Delete(name); err != nil {
return err
}
}
return nil
}
func (srv *Server) CmdHistory(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "history", "[OPTIONS] IMAGE", "Show the history of an image")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
image, err := srv.runtime.repositories.LookupImage(cmd.Arg(0))
if err != nil {
return err
}
w := tabwriter.NewWriter(stdout, 20, 1, 3, ' ', 0)
defer w.Flush()
fmt.Fprintln(w, "ID\tCREATED\tCREATED BY")
return image.WalkHistory(func(img *Image) error {
fmt.Fprintf(w, "%s\t%s\t%s\n",
srv.runtime.repositories.ImageName(img.ShortId()),
HumanDuration(time.Now().Sub(img.Created))+" ago",
strings.Join(img.ContainerConfig.Cmd, " "),
)
return nil
})
}
func (srv *Server) CmdRm(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "rm", "[OPTIONS] CONTAINER", "Remove a container")
if err := cmd.Parse(args); err != nil {
return nil
}
for _, name := range cmd.Args() {
container := srv.runtime.Get(name)
if container == nil {
return fmt.Errorf("No such container: %s", name)
}
if err := srv.runtime.Destroy(container); err != nil {
fmt.Fprintln(stdout, "Error destroying container "+name+": "+err.Error())
}
}
return nil
}
// 'docker kill NAME' kills a running container
func (srv *Server) CmdKill(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container")
if err := cmd.Parse(args); err != nil {
return nil
}
for _, name := range cmd.Args() {
container := srv.runtime.Get(name)
if container == nil {
return fmt.Errorf("No such container: %s", name)
}
if err := container.Kill(); err != nil {
fmt.Fprintln(stdout, "Error killing container "+name+": "+err.Error())
}
}
return nil
}
func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "import", "[OPTIONS] URL|- [REPOSITORY [TAG]]", "Create a new filesystem image from the contents of a tarball")
var archive io.Reader
var resp *http.Response
if err := cmd.Parse(args); err != nil {
return nil
}
src := cmd.Arg(0)
if src == "" {
return fmt.Errorf("Not enough arguments")
} else if src == "-" {
archive = stdin
} else {
u, err := url.Parse(src)
if err != nil {
return err
}
if u.Scheme == "" {
u.Scheme = "http"
u.Host = src
u.Path = ""
}
fmt.Fprintln(stdout, "Downloading from", u)
// Download with curl (pretty progress bar)
// If curl is not available, fallback to http.Get()
resp, err = Download(u.String(), stdout)
if err != nil {
return err
}
archive = ProgressReader(resp.Body, int(resp.ContentLength), stdout)
}
img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src)
if err != nil {
return err
}
// Optionally register the image at REPO/TAG
if repository := cmd.Arg(1); repository != "" {
tag := cmd.Arg(2) // Repository will handle an empty tag properly
if err := srv.runtime.repositories.Set(repository, tag, img.Id, true); err != nil {
return err
}
}
fmt.Fprintln(stdout, img.ShortId())
return nil
}
func (srv *Server) CmdPush(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "push", "NAME", "Push an image or a repository to the registry")
if err := cmd.Parse(args); err != nil {
return nil
}
local := cmd.Arg(0)
if local == "" {
cmd.Usage()
return nil
}
// If the login failed, abort
if srv.runtime.authConfig == nil || srv.runtime.authConfig.Username == "" {
if err := srv.CmdLogin(stdin, stdout, args...); err != nil {
return err
}
if srv.runtime.authConfig == nil || srv.runtime.authConfig.Username == "" {
return fmt.Errorf("Please login prior to push. ('docker login')")
}
}
var remote string
tmp := strings.SplitN(local, "/", 2)
if len(tmp) == 1 {
return fmt.Errorf(
"Impossible to push a \"root\" repository. Please rename your repository in <user>/<repo> (ex: %s/%s)",
srv.runtime.authConfig.Username, local)
} else {
remote = local
}
Debugf("Pushing [%s] to [%s]\n", local, remote)
// Try to get the image
// FIXME: Handle lookup
// FIXME: Also push the tags in case of ./docker push myrepo:mytag
// img, err := srv.runtime.LookupImage(cmd.Arg(0))
img, err := srv.runtime.graph.Get(local)
if err != nil {
Debugf("The push refers to a repository [%s] (len: %d)\n", local, len(srv.runtime.repositories.Repositories[local]))
// If it fails, try to get the repository
if localRepo, exists := srv.runtime.repositories.Repositories[local]; exists {
if err := srv.runtime.graph.PushRepository(stdout, remote, localRepo, srv.runtime.authConfig); err != nil {
return err
}
return nil
}
return err
}
err = srv.runtime.graph.PushImage(stdout, img, srv.runtime.authConfig)
if err != nil {
return err
}
return nil
}
func (srv *Server) CmdPull(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "pull", "NAME", "Pull an image or a repository from the registry")
if err := cmd.Parse(args); err != nil {
return nil
}
remote := cmd.Arg(0)
if remote == "" {
cmd.Usage()
return nil
}
// FIXME: CmdPull should be a wrapper around Runtime.Pull()
if srv.runtime.graph.LookupRemoteImage(remote, srv.runtime.authConfig) {
if err := srv.runtime.graph.PullImage(stdout, remote, srv.runtime.authConfig); err != nil {
return err
}
return nil
}
// FIXME: Allow pull repo:tag
if err := srv.runtime.graph.PullRepository(stdout, remote, "", srv.runtime.repositories, srv.runtime.authConfig); err != nil {
return err
}
return nil
}
func (srv *Server) CmdImages(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "images", "[OPTIONS] [NAME]", "List images")
//limit := cmd.Int("l", 0, "Only show the N most recent versions of each image")
quiet := cmd.Bool("q", false, "only show numeric IDs")
flAll := cmd.Bool("a", false, "show all images")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() > 1 {
cmd.Usage()
return nil
}
var nameFilter string
if cmd.NArg() == 1 {
nameFilter = cmd.Arg(0)
}
w := tabwriter.NewWriter(stdout, 20, 1, 3, ' ', 0)
if !*quiet {
fmt.Fprintln(w, "REPOSITORY\tTAG\tID\tCREATED\tPARENT")
}
var allImages map[string]*Image
var err error
if *flAll {
allImages, err = srv.runtime.graph.Map()
} else {
allImages, err = srv.runtime.graph.Heads()
}
if err != nil {
return err
}
for name, repository := range srv.runtime.repositories.Repositories {
if nameFilter != "" && name != nameFilter {
continue
}
for tag, id := range repository {
image, err := srv.runtime.graph.Get(id)
if err != nil {
log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err)
continue
}
delete(allImages, id)
if !*quiet {
for idx, field := range []string{
/* REPOSITORY */ name,
/* TAG */ tag,
/* ID */ TruncateId(id),
/* CREATED */ HumanDuration(time.Now().Sub(image.Created)) + " ago",
/* PARENT */ srv.runtime.repositories.ImageName(image.Parent),
} {
if idx == 0 {
w.Write([]byte(field))
} else {
w.Write([]byte("\t" + field))
}
}
w.Write([]byte{'\n'})
} else {
stdout.Write([]byte(image.ShortId() + "\n"))
}
}
}
// Display images which aren't part of a
if nameFilter == "" {
for id, image := range allImages {
if !*quiet {
for idx, field := range []string{
/* REPOSITORY */ "<none>",
/* TAG */ "<none>",
/* ID */ TruncateId(id),
/* CREATED */ HumanDuration(time.Now().Sub(image.Created)) + " ago",
/* PARENT */ srv.runtime.repositories.ImageName(image.Parent),
} {
if idx == 0 {
w.Write([]byte(field))
} else {
w.Write([]byte("\t" + field))
}
}
w.Write([]byte{'\n'})
} else {
stdout.Write([]byte(image.ShortId() + "\n"))
}
}
}
if !*quiet {
w.Flush()
}
return nil
}
func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout,
"ps", "[OPTIONS]", "List containers")
quiet := cmd.Bool("q", false, "Only display numeric IDs")
flAll := cmd.Bool("a", false, "Show all containers. Only running containers are shown by default.")
flFull := cmd.Bool("notrunc", false, "Don't truncate output")
if err := cmd.Parse(args); err != nil {
return nil
}
w := tabwriter.NewWriter(stdout, 12, 1, 3, ' ', 0)
if !*quiet {
fmt.Fprintln(w, "ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tCOMMENT")
}
for _, container := range srv.runtime.List() {
if !container.State.Running && !*flAll {
continue
}
if !*quiet {
command := fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
if !*flFull {
command = Trunc(command, 20)
}
for idx, field := range []string{
/* ID */ container.ShortId(),
/* IMAGE */ srv.runtime.repositories.ImageName(container.Image),
/* COMMAND */ command,
/* CREATED */ HumanDuration(time.Now().Sub(container.Created)) + " ago",
/* STATUS */ container.State.String(),
/* COMMENT */ "",
} {
if idx == 0 {
w.Write([]byte(field))
} else {
w.Write([]byte("\t" + field))
}
}
w.Write([]byte{'\n'})
} else {
stdout.Write([]byte(container.ShortId() + "\n"))
}
}
if !*quiet {
w.Flush()
}
return nil
}
func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout,
"commit", "[OPTIONS] CONTAINER [REPOSITORY [TAG]]",
"Create a new image from a container's changes")
flComment := cmd.String("m", "", "Commit message")
if err := cmd.Parse(args); err != nil {
return nil
}
containerName, repository, tag := cmd.Arg(0), cmd.Arg(1), cmd.Arg(2)
if containerName == "" {
cmd.Usage()
return nil
}
img, err := srv.runtime.Commit(containerName, repository, tag, *flComment)
if err != nil {
return err
}
fmt.Fprintln(stdout, img.ShortId())
return nil
}
func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout,
"export", "CONTAINER",
"Export the contents of a filesystem as a tar archive")
if err := cmd.Parse(args); err != nil {
return nil
}
name := cmd.Arg(0)
if container := srv.runtime.Get(name); container != nil {
data, err := container.Export()
if err != nil {
return err
}
// Stream the entire contents of the container (basically a volatile snapshot)
if _, err := io.Copy(stdout, data); err != nil {
return err
}
return nil
}
return fmt.Errorf("No such container: %s", name)
}
func (srv *Server) CmdDiff(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout,
"diff", "CONTAINER [OPTIONS]",
"Inspect changes on a container's filesystem")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 1 {
return fmt.Errorf("Not enough arguments")
}
if container := srv.runtime.Get(cmd.Arg(0)); container == nil {
return fmt.Errorf("No such container")
} else {
changes, err := container.Changes()
if err != nil {
return err
}
for _, change := range changes {
fmt.Fprintln(stdout, change.String())
}
}
return nil
}
func (srv *Server) CmdLogs(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "logs", "[OPTIONS] CONTAINER", "Fetch the logs of a container")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
name := cmd.Arg(0)
if container := srv.runtime.Get(name); container != nil {
logStdout, err := container.ReadLog("stdout")
if err != nil {
return err
}
logStderr, err := container.ReadLog("stderr")
if err != nil {
return err
}
// FIXME: Interpolate stdout and stderr instead of concatenating them
// FIXME: Differentiate stdout and stderr in the remote protocol
if _, err := io.Copy(stdout, logStdout); err != nil {
return err
}
if _, err := io.Copy(stdout, logStderr); err != nil {
return err
}
return nil
}
return fmt.Errorf("No such container: %s", cmd.Arg(0))
}
func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "attach", "CONTAINER", "Attach to a running container")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
name := cmd.Arg(0)
container := srv.runtime.Get(name)
if container == nil {
return fmt.Errorf("No such container: %s", name)
}
return <-container.Attach(stdin, nil, stdout, stdout)
}
// Ports type - Used to parse multiple -p flags
type ports []int
func (p *ports) String() string {
return fmt.Sprint(*p)
}
func (p *ports) Set(value string) error {
port, err := strconv.Atoi(value)
if err != nil {
return fmt.Errorf("Invalid port: %v", value)
}
*p = append(*p, port)
return nil
}
// ListOpts type
type ListOpts []string
func (opts *ListOpts) String() string {
return fmt.Sprint(*opts)
}
func (opts *ListOpts) Set(value string) error {
*opts = append(*opts, value)
return nil
}
// AttachOpts stores arguments to 'docker run -a', eg. which streams to attach to
type AttachOpts map[string]bool
func NewAttachOpts() AttachOpts {
return make(AttachOpts)
}
func (opts AttachOpts) String() string {
// Cast to underlying map type to avoid infinite recursion
return fmt.Sprintf("%v", map[string]bool(opts))
}
func (opts AttachOpts) Set(val string) error {
if val != "stdin" && val != "stdout" && val != "stderr" {
return fmt.Errorf("Unsupported stream name: %s", val)
}
opts[val] = true
return nil
}
func (opts AttachOpts) Get(val string) bool {
if res, exists := opts[val]; exists {
return res
}
return false
}
func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "tag", "[OPTIONS] IMAGE REPOSITORY [TAG]", "Tag an image into a repository")
force := cmd.Bool("f", false, "Force")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 2 {
cmd.Usage()
return nil
}
return srv.runtime.repositories.Set(cmd.Arg(1), cmd.Arg(2), cmd.Arg(0), *force)
}
func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
config, err := ParseRun(args, stdout)
if err != nil {
return err
}
if config.Image == "" {
fmt.Fprintln(stdout, "Error: Image not specified")
return fmt.Errorf("Image not specified")
}
if len(config.Cmd) == 0 {
fmt.Fprintln(stdout, "Error: Command not specified")
return fmt.Errorf("Command not specified")
}
// Create new container
container, err := srv.runtime.Create(config)
if err != nil {
// If container not found, try to pull it
if srv.runtime.graph.IsNotExist(err) {
fmt.Fprintf(stdout, "Image %s not found, trying to pull it from registry.\n", config.Image)
if err = srv.CmdPull(stdin, stdout, config.Image); err != nil {
return err
}
if container, err = srv.runtime.Create(config); err != nil {
return err
}
} else {
return err
}
}
var (
cStdin io.ReadCloser
cStdout, cStderr io.Writer
)
if config.AttachStdin {
r, w := io.Pipe()
go func() {
defer w.Close()
defer Debugf("Closing buffered stdin pipe")
io.Copy(w, stdin)
}()
cStdin = r
}
if config.AttachStdout {
cStdout = stdout
}
if config.AttachStderr {
cStderr = stdout // FIXME: rcli can't differentiate stdout from stderr
}
attachErr := container.Attach(cStdin, stdin, cStdout, cStderr)
Debugf("Starting\n")
if err := container.Start(); err != nil {
return err
}
if cStdout == nil && cStderr == nil {
fmt.Fprintln(stdout, container.ShortId())
}
Debugf("Waiting for attach to return\n")
<-attachErr
// Expecting I/O pipe error, discarding
return nil
}
func NewServer() (*Server, error) {
if runtime.GOARCH != "amd64" {
log.Fatalf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
}
runtime, err := NewRuntime()
if err != nil {
return nil, err
}
srv := &Server{
runtime: runtime,
}
return srv, nil
}
type Server struct {
runtime *Runtime
}
+302
View File
@@ -0,0 +1,302 @@
package docker
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"strings"
"testing"
"time"
)
func closeWrap(args ...io.Closer) error {
e := false
ret := fmt.Errorf("Error closing elements")
for _, c := range args {
if err := c.Close(); err != nil {
e = true
ret = fmt.Errorf("%s\n%s", ret, err)
}
}
if e {
return ret
}
return nil
}
func setTimeout(t *testing.T, msg string, d time.Duration, f func()) {
c := make(chan bool)
// Make sure we are not too long
go func() {
time.Sleep(d)
c <- true
}()
go func() {
f()
c <- false
}()
if <-c {
t.Fatal(msg)
}
}
func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error {
for i := 0; i < count; i++ {
if _, err := w.Write([]byte(input)); err != nil {
return err
}
o, err := bufio.NewReader(r).ReadString('\n')
if err != nil {
return err
}
if strings.Trim(o, " \r\n") != output {
return fmt.Errorf("Unexpected output. Expected [%s], received [%s]", output, o)
}
}
return nil
}
// TestRunHostname checks that 'docker run -h' correctly sets a custom hostname
func TestRunHostname(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
var stdin, stdout bytes.Buffer
setTimeout(t, "CmdRun timed out", 2*time.Second, func() {
if err := srv.CmdRun(ioutil.NopCloser(&stdin), &nopWriteCloser{&stdout}, "-h", "foobar", GetTestImage(runtime).Id, "hostname"); err != nil {
t.Fatal(err)
}
})
if output := string(stdout.Bytes()); output != "foobar\n" {
t.Fatalf("'hostname' should display '%s', not '%s'", "foobar\n", output)
}
}
func TestRunExit(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
stdin, stdinPipe := io.Pipe()
stdout, stdoutPipe := io.Pipe()
c1 := make(chan struct{})
go func() {
srv.CmdRun(stdin, stdoutPipe, "-i", GetTestImage(runtime).Id, "/bin/cat")
close(c1)
}()
setTimeout(t, "Read/Write assertion timed out", 2*time.Second, func() {
if err := assertPipe("hello\n", "hello", stdout, stdinPipe, 15); err != nil {
t.Fatal(err)
}
})
container := runtime.List()[0]
// Closing /bin/cat stdin, expect it to exit
p, err := container.StdinPipe()
if err != nil {
t.Fatal(err)
}
if err := p.Close(); err != nil {
t.Fatal(err)
}
// as the process exited, CmdRun must finish and unblock. Wait for it
setTimeout(t, "Waiting for CmdRun timed out", 2*time.Second, func() {
<-c1
})
// Make sure that the client has been disconnected
setTimeout(t, "The client should have been disconnected once the remote process exited.", 2*time.Second, func() {
// Expecting pipe i/o error, just check that read does not block
stdin.Read([]byte{})
})
// Cleanup pipes
if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
t.Fatal(err)
}
}
// Expected behaviour: the process dies when the client disconnects
func TestRunDisconnect(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
stdin, stdinPipe := io.Pipe()
stdout, stdoutPipe := io.Pipe()
c1 := make(chan struct{})
go func() {
// We're simulating a disconnect so the return value doesn't matter. What matters is the
// fact that CmdRun returns.
srv.CmdRun(stdin, stdoutPipe, "-i", GetTestImage(runtime).Id, "/bin/cat")
close(c1)
}()
setTimeout(t, "Read/Write assertion timed out", 2*time.Second, func() {
if err := assertPipe("hello\n", "hello", stdout, stdinPipe, 15); err != nil {
t.Fatal(err)
}
})
// Close pipes (simulate disconnect)
if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
t.Fatal(err)
}
// as the pipes are close, we expect the process to die,
// therefore CmdRun to unblock. Wait for CmdRun
setTimeout(t, "Waiting for CmdRun timed out", 2*time.Second, func() {
<-c1
})
// Client disconnect after run -i should cause stdin to be closed, which should
// cause /bin/cat to exit.
setTimeout(t, "Waiting for /bin/cat to exit timed out", 2*time.Second, func() {
container := runtime.List()[0]
container.Wait()
if container.State.Running {
t.Fatalf("/bin/cat is still running after closing stdin")
}
})
}
// TestAttachStdin checks attaching to stdin without stdout and stderr.
// 'docker run -i -a stdin' should sends the client's stdin to the command,
// then detach from it and print the container id.
func TestAttachStdin(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
stdinR, stdinW := io.Pipe()
var stdout bytes.Buffer
ch := make(chan struct{})
go func() {
srv.CmdRun(stdinR, &stdout, "-i", "-a", "stdin", GetTestImage(runtime).Id, "sh", "-c", "echo hello; cat")
close(ch)
}()
// Send input to the command, close stdin, wait for CmdRun to return
setTimeout(t, "Read/Write timed out", 2*time.Second, func() {
if _, err := stdinW.Write([]byte("hi there\n")); err != nil {
t.Fatal(err)
}
stdinW.Close()
<-ch
})
// Check output
cmdOutput := string(stdout.Bytes())
container := runtime.List()[0]
if cmdOutput != container.ShortId()+"\n" {
t.Fatalf("Wrong output: should be '%s', not '%s'\n", container.ShortId()+"\n", cmdOutput)
}
setTimeout(t, "Waiting for command to exit timed out", 2*time.Second, func() {
container.Wait()
})
// Check logs
if cmdLogs, err := container.ReadLog("stdout"); err != nil {
t.Fatal(err)
} else {
if output, err := ioutil.ReadAll(cmdLogs); err != nil {
t.Fatal(err)
} else {
expectedLog := "hello\nhi there\n"
if string(output) != expectedLog {
t.Fatalf("Unexpected logs: should be '%s', not '%s'\n", expectedLog, output)
}
}
}
}
// Expected behaviour, the process stays alive when the client disconnects
func TestAttachDisconnect(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
container, err := runtime.Create(
&Config{
Image: GetTestImage(runtime).Id,
Memory: 33554432,
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
// Start the process
if err := container.Start(); err != nil {
t.Fatal(err)
}
stdin, stdinPipe := io.Pipe()
stdout, stdoutPipe := io.Pipe()
// Attach to it
c1 := make(chan struct{})
go func() {
// We're simulating a disconnect so the return value doesn't matter. What matters is the
// fact that CmdAttach returns.
srv.CmdAttach(stdin, stdoutPipe, container.Id)
close(c1)
}()
setTimeout(t, "First read/write assertion timed out", 2*time.Second, func() {
if err := assertPipe("hello\n", "hello", stdout, stdinPipe, 15); err != nil {
t.Fatal(err)
}
})
// Close pipes (client disconnects)
if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
t.Fatal(err)
}
// Wait for attach to finish, the client disconnected, therefore, Attach finished his job
setTimeout(t, "Waiting for CmdAttach timed out", 2*time.Second, func() {
<-c1
})
// We closed stdin, expect /bin/cat to still be running
// Wait a little bit to make sure container.monitor() did his thing
err = container.WaitTimeout(500 * time.Millisecond)
if err == nil || !container.State.Running {
t.Fatalf("/bin/cat is not running after closing stdin")
}
// Try to avoid the timeoout in destroy. Best effort, don't check error
cStdin, _ := container.StdinPipe()
cStdin.Close()
}
+421 -225
View File
@@ -1,9 +1,9 @@
package docker
import (
"./fs"
"encoding/json"
"errors"
"fmt"
"github.com/dotcloud/docker/rcli"
"github.com/kr/pty"
"io"
"io/ioutil"
@@ -16,50 +16,119 @@ import (
"time"
)
var sysInitPath string
func init() {
sysInitPath = SelfPath()
}
type Container struct {
Id string
Root string
root string
Id string
Created time.Time
Path string
Args []string
Config *Config
Mountpoint *fs.Mountpoint
State *State
Image string
Config *Config
State State
Image string
network *NetworkInterface
networkManager *NetworkManager
NetworkSettings *NetworkSettings
SysInitPath string
lxcConfigPath string
cmd *exec.Cmd
stdout *writeBroadcaster
stderr *writeBroadcaster
stdin io.ReadCloser
stdinPipe io.WriteCloser
SysInitPath string
cmd *exec.Cmd
stdout *writeBroadcaster
stderr *writeBroadcaster
stdin io.ReadCloser
stdinPipe io.WriteCloser
stdoutLog *os.File
stderrLog *os.File
ptyStdinMaster io.Closer
ptyStdoutMaster io.Closer
ptyStderrMaster io.Closer
runtime *Runtime
}
type Config struct {
Hostname string
User string
Memory int64 // Memory limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap
Ports []int
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
OpenStdin bool // Open stdin
Hostname string
User string
Memory int64 // Memory limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap
AttachStdin bool
AttachStdout bool
AttachStderr bool
PortSpecs []string
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
OpenStdin bool // Open stdin
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
Env []string
Cmd []string
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
}
func ParseRun(args []string, stdout io.Writer) (*Config, error) {
cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
if len(args) > 0 && args[0] != "--help" {
cmd.SetOutput(ioutil.Discard)
}
flHostname := cmd.String("h", "", "Container host name")
flUser := cmd.String("u", "", "Username or UID")
flDetach := cmd.Bool("d", false, "Detached mode: leave the container running in the background")
flAttach := NewAttachOpts()
cmd.Var(flAttach, "a", "Attach to stdin, stdout or stderr.")
flStdin := cmd.Bool("i", false, "Keep stdin open even if not attached")
flTty := cmd.Bool("t", false, "Allocate a pseudo-tty")
flMemory := cmd.Int64("m", 0, "Memory limit (in bytes)")
var flPorts ListOpts
cmd.Var(&flPorts, "p", "Expose a container's port to the host (use 'docker port' to see the actual mapping)")
var flEnv ListOpts
cmd.Var(&flEnv, "e", "Set environment variables")
if err := cmd.Parse(args); err != nil {
return nil, err
}
if *flDetach && len(flAttach) > 0 {
return nil, fmt.Errorf("Conflicting options: -a and -d")
}
// If neither -d or -a are set, attach to everything by default
if len(flAttach) == 0 && !*flDetach {
if !*flDetach {
flAttach.Set("stdout")
flAttach.Set("stderr")
if *flStdin {
flAttach.Set("stdin")
}
}
}
parsedArgs := cmd.Args()
runCmd := []string{}
image := ""
if len(parsedArgs) >= 1 {
image = cmd.Arg(0)
}
if len(parsedArgs) > 1 {
runCmd = parsedArgs[1:]
}
config := &Config{
Hostname: *flHostname,
PortSpecs: flPorts,
User: *flUser,
Tty: *flTty,
OpenStdin: *flStdin,
Memory: *flMemory,
AttachStdin: flAttach.Get("stdin"),
AttachStdout: flAttach.Get("stdout"),
AttachStderr: flAttach.Get("stderr"),
Env: flEnv,
Cmd: runCmd,
Image: image,
}
// When allocating stdin in attached mode, close stdin at client disconnect
if config.OpenStdin && config.AttachStdin {
config.StdinOnce = true
}
return config, nil
}
type NetworkSettings struct {
@@ -69,106 +138,6 @@ type NetworkSettings struct {
PortMapping map[string]string
}
func createContainer(id string, root string, command string, args []string, image *fs.Image, config *Config, netManager *NetworkManager) (*Container, error) {
mountpoint, err := image.Mountpoint(path.Join(root, "rootfs"), path.Join(root, "rw"))
if err != nil {
return nil, err
}
container := &Container{
Id: id,
Root: root,
Created: time.Now(),
Path: command,
Args: args,
Config: config,
Image: image.Id,
Mountpoint: mountpoint,
State: newState(),
networkManager: netManager,
NetworkSettings: &NetworkSettings{},
SysInitPath: sysInitPath,
lxcConfigPath: path.Join(root, "config.lxc"),
stdout: newWriteBroadcaster(),
stderr: newWriteBroadcaster(),
}
if err := os.Mkdir(root, 0700); err != nil {
return nil, err
}
// Setup logging of stdout and stderr to disk
if stdoutLog, err := os.OpenFile(path.Join(container.Root, id+"-stdout.log"), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600); err != nil {
return nil, err
} else {
container.stdoutLog = stdoutLog
}
if stderrLog, err := os.OpenFile(path.Join(container.Root, id+"-stderr.log"), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600); err != nil {
return nil, err
} else {
container.stderrLog = stderrLog
}
if container.Config.OpenStdin {
container.stdin, container.stdinPipe = io.Pipe()
} else {
container.stdinPipe = NopWriteCloser(ioutil.Discard) // Silently drop stdin
}
container.stdout.AddWriter(NopWriteCloser(container.stdoutLog))
container.stderr.AddWriter(NopWriteCloser(container.stderrLog))
if err := container.save(); err != nil {
return nil, err
}
return container, nil
}
func loadContainer(store *fs.Store, containerPath string, netManager *NetworkManager) (*Container, error) {
data, err := ioutil.ReadFile(path.Join(containerPath, "config.json"))
if err != nil {
return nil, err
}
mountpoint, err := store.FetchMountpoint(
path.Join(containerPath, "rootfs"),
path.Join(containerPath, "rw"),
)
if err != nil {
return nil, err
} else if mountpoint == nil {
return nil, errors.New("Couldn't load container: unregistered mountpoint.")
}
container := &Container{
stdout: newWriteBroadcaster(),
stderr: newWriteBroadcaster(),
lxcConfigPath: path.Join(containerPath, "config.lxc"),
networkManager: netManager,
NetworkSettings: &NetworkSettings{},
Mountpoint: mountpoint,
}
// Load container settings
if err := json.Unmarshal(data, container); err != nil {
return nil, err
}
// Setup logging of stdout and stderr to disk
if stdoutLog, err := os.OpenFile(path.Join(container.Root, container.Id+"-stdout.log"), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600); err != nil {
return nil, err
} else {
container.stdoutLog = stdoutLog
}
if stderrLog, err := os.OpenFile(path.Join(container.Root, container.Id+"-stderr.log"), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600); err != nil {
return nil, err
} else {
container.stderrLog = stderrLog
}
container.stdout.AddWriter(NopWriteCloser(container.stdoutLog))
container.stderr.AddWriter(NopWriteCloser(container.stderrLog))
if container.Config.OpenStdin {
container.stdin, container.stdinPipe = io.Pipe()
} else {
container.stdinPipe = NopWriteCloser(ioutil.Discard) // Silently drop stdin
}
container.State = newState()
return container, nil
}
func (container *Container) Cmd() *exec.Cmd {
return container.cmd
}
@@ -177,64 +146,32 @@ func (container *Container) When() time.Time {
return container.Created
}
func (container *Container) loadUserData() (map[string]string, error) {
jsonData, err := ioutil.ReadFile(path.Join(container.Root, "userdata.json"))
if err != nil {
if os.IsNotExist(err) {
return make(map[string]string), nil
}
return nil, err
}
data := make(map[string]string)
if err := json.Unmarshal(jsonData, &data); err != nil {
return nil, err
}
return data, nil
}
func (container *Container) saveUserData(data map[string]string) error {
jsonData, err := json.Marshal(data)
func (container *Container) FromDisk() error {
data, err := ioutil.ReadFile(container.jsonPath())
if err != nil {
return err
}
return ioutil.WriteFile(path.Join(container.Root, "userdata.json"), jsonData, 0700)
}
func (container *Container) SetUserData(key, value string) error {
data, err := container.loadUserData()
if err != nil {
// Load container settings
if err := json.Unmarshal(data, container); err != nil {
return err
}
data[key] = value
return container.saveUserData(data)
return nil
}
func (container *Container) GetUserData(key string) string {
data, err := container.loadUserData()
if err != nil {
return ""
}
if value, exists := data[key]; exists {
return value
}
return ""
}
func (container *Container) save() (err error) {
func (container *Container) ToDisk() (err error) {
data, err := json.Marshal(container)
if err != nil {
return
}
return ioutil.WriteFile(path.Join(container.Root, "config.json"), data, 0666)
return ioutil.WriteFile(container.jsonPath(), data, 0666)
}
func (container *Container) generateLXCConfig() error {
fo, err := os.Create(container.lxcConfigPath)
fo, err := os.Create(container.lxcConfigPath())
if err != nil {
return err
}
defer fo.Close()
if err := LxcTemplateCompiled.Execute(fo, container); err != nil {
return err
}
@@ -242,52 +179,62 @@ func (container *Container) generateLXCConfig() error {
}
func (container *Container) startPty() error {
stdout_master, stdout_slave, err := pty.Open()
stdoutMaster, stdoutSlave, err := pty.Open()
if err != nil {
return err
}
container.cmd.Stdout = stdout_slave
container.ptyStdoutMaster = stdoutMaster
container.cmd.Stdout = stdoutSlave
stderr_master, stderr_slave, err := pty.Open()
stderrMaster, stderrSlave, err := pty.Open()
if err != nil {
return err
}
container.cmd.Stderr = stderr_slave
container.ptyStderrMaster = stderrMaster
container.cmd.Stderr = stderrSlave
// Copy the PTYs to our broadcasters
go func() {
defer container.stdout.Close()
io.Copy(container.stdout, stdout_master)
defer container.stdout.CloseWriters()
Debugf("[startPty] Begin of stdout pipe")
io.Copy(container.stdout, stdoutMaster)
Debugf("[startPty] End of stdout pipe")
}()
go func() {
defer container.stderr.Close()
io.Copy(container.stderr, stderr_master)
defer container.stderr.CloseWriters()
Debugf("[startPty] Begin of stderr pipe")
io.Copy(container.stderr, stderrMaster)
Debugf("[startPty] End of stderr pipe")
}()
// stdin
var stdin_slave io.ReadCloser
var stdinSlave io.ReadCloser
if container.Config.OpenStdin {
stdin_master, stdin_slave, err := pty.Open()
var stdinMaster io.WriteCloser
stdinMaster, stdinSlave, err = pty.Open()
if err != nil {
return err
}
container.cmd.Stdin = stdin_slave
container.ptyStdinMaster = stdinMaster
container.cmd.Stdin = stdinSlave
// FIXME: The following appears to be broken.
// "cannot set terminal process group (-1): Inappropriate ioctl for device"
// container.cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true}
go func() {
defer container.stdin.Close()
io.Copy(stdin_master, container.stdin)
Debugf("[startPty] Begin of stdin pipe")
io.Copy(stdinMaster, container.stdin)
Debugf("[startPty] End of stdin pipe")
}()
}
if err := container.cmd.Start(); err != nil {
return err
}
stdout_slave.Close()
stderr_slave.Close()
if stdin_slave != nil {
stdin_slave.Close()
stdoutSlave.Close()
stderrSlave.Close()
if stdinSlave != nil {
stdinSlave.Close()
}
return nil
}
@@ -302,14 +249,125 @@ func (container *Container) start() error {
}
go func() {
defer stdin.Close()
Debugf("Begin of stdin pipe [start]")
io.Copy(stdin, container.stdin)
Debugf("End of stdin pipe [start]")
}()
}
return container.cmd.Start()
}
func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, stdout io.Writer, stderr io.Writer) chan error {
var cStdout, cStderr io.ReadCloser
var nJobs int
errors := make(chan error, 3)
if stdin != nil && container.Config.OpenStdin {
nJobs += 1
if cStdin, err := container.StdinPipe(); err != nil {
errors <- err
} else {
go func() {
Debugf("[start] attach stdin\n")
defer Debugf("[end] attach stdin\n")
// No matter what, when stdin is closed (io.Copy unblock), close stdout and stderr
if cStdout != nil {
defer cStdout.Close()
}
if cStderr != nil {
defer cStderr.Close()
}
if container.Config.StdinOnce {
defer cStdin.Close()
}
_, err := io.Copy(cStdin, stdin)
if err != nil {
Debugf("[error] attach stdin: %s\n", err)
}
// Discard error, expecting pipe error
errors <- nil
}()
}
}
if stdout != nil {
nJobs += 1
if p, err := container.StdoutPipe(); err != nil {
errors <- err
} else {
cStdout = p
go func() {
Debugf("[start] attach stdout\n")
defer Debugf("[end] attach stdout\n")
// If we are in StdinOnce mode, then close stdin
if container.Config.StdinOnce {
if stdin != nil {
defer stdin.Close()
}
if stdinCloser != nil {
defer stdinCloser.Close()
}
}
_, err := io.Copy(stdout, cStdout)
if err != nil {
Debugf("[error] attach stdout: %s\n", err)
}
errors <- err
}()
}
}
if stderr != nil {
nJobs += 1
if p, err := container.StderrPipe(); err != nil {
errors <- err
} else {
cStderr = p
go func() {
Debugf("[start] attach stderr\n")
defer Debugf("[end] attach stderr\n")
// If we are in StdinOnce mode, then close stdin
if container.Config.StdinOnce {
if stdin != nil {
defer stdin.Close()
}
if stdinCloser != nil {
defer stdinCloser.Close()
}
}
_, err := io.Copy(stderr, cStderr)
if err != nil {
Debugf("[error] attach stderr: %s\n", err)
}
errors <- err
}()
}
}
return Go(func() error {
if cStdout != nil {
defer cStdout.Close()
}
if cStderr != nil {
defer cStderr.Close()
}
// FIXME: how do clean up the stdin goroutine without the unwanted side effect
// of closing the passed stdin? Add an intermediary io.Pipe?
for i := 0; i < nJobs; i += 1 {
Debugf("Waiting for job %d/%d\n", i+1, nJobs)
if err := <-errors; err != nil {
Debugf("Job %d returned error %s. Aborting all jobs\n", i+1, err)
return err
}
Debugf("Job %d completed successfully\n", i+1)
}
Debugf("All jobs completed successfully\n")
return nil
})
}
func (container *Container) Start() error {
if err := container.Mountpoint.EnsureMounted(); err != nil {
if container.State.Running {
return fmt.Errorf("The container %s is already running.", container.Id)
}
if err := container.EnsureMounted(); err != nil {
return err
}
if err := container.allocateNetwork(); err != nil {
@@ -320,7 +378,7 @@ func (container *Container) Start() error {
}
params := []string{
"-n", container.Id,
"-f", container.lxcConfigPath,
"-f", container.lxcConfigPath(),
"--",
"/sbin/init",
}
@@ -337,10 +395,31 @@ func (container *Container) Start() error {
params = append(params, "--", container.Path)
params = append(params, container.Args...)
container.cmd = exec.Command("/usr/bin/lxc-start", params...)
container.cmd = exec.Command("lxc-start", params...)
// Setup environment
container.cmd.Env = append(
[]string{
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
},
container.Config.Env...,
)
// Setup logging of stdout and stderr to disk
if err := container.runtime.LogToDisk(container.stdout, container.logPath("stdout")); err != nil {
return err
}
if err := container.runtime.LogToDisk(container.stderr, container.logPath("stderr")); err != nil {
return err
}
var err error
if container.Config.Tty {
container.cmd.Env = append(
[]string{"TERM=xterm"},
container.cmd.Env...,
)
err = container.startPty()
} else {
err = container.start()
@@ -348,8 +427,10 @@ func (container *Container) Start() error {
if err != nil {
return err
}
// FIXME: save state on disk *first*, then converge
// this way disk state is used as a journal, eg. we can restore after crash etc.
container.State.setRunning(container.cmd.Process.Pid)
container.save()
container.ToDisk()
go container.monitor()
return nil
}
@@ -389,40 +470,24 @@ func (container *Container) StdoutPipe() (io.ReadCloser, error) {
return newBufReader(reader), nil
}
func (container *Container) StdoutLog() io.Reader {
r, err := os.Open(container.stdoutLog.Name())
if err != nil {
return nil
}
return r
}
func (container *Container) StderrPipe() (io.ReadCloser, error) {
reader, writer := io.Pipe()
container.stderr.AddWriter(writer)
return newBufReader(reader), nil
}
func (container *Container) StderrLog() io.Reader {
r, err := os.Open(container.stderrLog.Name())
if err != nil {
return nil
}
return r
}
func (container *Container) allocateNetwork() error {
iface, err := container.networkManager.Allocate()
iface, err := container.runtime.networkManager.Allocate()
if err != nil {
return err
}
container.NetworkSettings.PortMapping = make(map[string]string)
for _, port := range container.Config.Ports {
if extPort, err := iface.AllocatePort(port); err != nil {
for _, spec := range container.Config.PortSpecs {
if nat, err := iface.AllocatePort(spec); err != nil {
iface.Release()
return err
} else {
container.NetworkSettings.PortMapping[strconv.Itoa(port)] = strconv.Itoa(extPort)
container.NetworkSettings.PortMapping[strconv.Itoa(nat.Backend)] = strconv.Itoa(nat.Frontend)
}
}
container.network = iface
@@ -432,25 +497,54 @@ func (container *Container) allocateNetwork() error {
return nil
}
func (container *Container) releaseNetwork() error {
err := container.network.Release()
func (container *Container) releaseNetwork() {
container.network.Release()
container.network = nil
container.NetworkSettings = &NetworkSettings{}
return err
}
func (container *Container) monitor() {
// Wait for the program to exit
container.cmd.Wait()
Debugf("Waiting for process")
if err := container.cmd.Wait(); err != nil {
// Discard the error as any signals or non 0 returns will generate an error
Debugf("%s: Process: %s", container.Id, err)
}
Debugf("Process finished")
exitCode := container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
// Cleanup
if err := container.releaseNetwork(); err != nil {
log.Printf("%v: Failed to release network: %v", container.Id, err)
container.releaseNetwork()
if container.Config.OpenStdin {
if err := container.stdin.Close(); err != nil {
Debugf("%s: Error close stdin: %s", container.Id, err)
}
}
container.stdout.Close()
container.stderr.Close()
if err := container.Mountpoint.Umount(); err != nil {
if err := container.stdout.CloseWriters(); err != nil {
Debugf("%s: Error close stdout: %s", container.Id, err)
}
if err := container.stderr.CloseWriters(); err != nil {
Debugf("%s: Error close stderr: %s", container.Id, err)
}
if container.ptyStdinMaster != nil {
if err := container.ptyStdinMaster.Close(); err != nil {
Debugf("%s: Error close pty stdin master: %s", container.Id, err)
}
}
if container.ptyStdoutMaster != nil {
if err := container.ptyStdoutMaster.Close(); err != nil {
Debugf("%s: Error close pty stdout master: %s", container.Id, err)
}
}
if container.ptyStderrMaster != nil {
if err := container.ptyStderrMaster.Close(); err != nil {
Debugf("%s: Error close pty stderr master: %s", container.Id, err)
}
}
if err := container.Unmount(); err != nil {
log.Printf("%v: Failed to umount filesystem: %v", container.Id, err)
}
@@ -461,10 +555,21 @@ func (container *Container) monitor() {
// Report status back
container.State.setStopped(exitCode)
container.save()
if err := container.ToDisk(); err != nil {
// FIXME: there is a race condition here which causes this to fail during the unit tests.
// If another goroutine was waiting for Wait() to return before removing the container's root
// from the filesystem... At this point it may already have done so.
// This is because State.setStopped() has already been called, and has caused Wait()
// to return.
// FIXME: why are we serializing running state to disk in the first place?
//log.Printf("%s: Failed to dump configuration to the disk: %s", container.Id, err)
}
}
func (container *Container) kill() error {
if container.cmd == nil {
return nil
}
if err := container.cmd.Process.Kill(); err != nil {
return err
}
@@ -486,9 +591,9 @@ func (container *Container) Stop() error {
}
// 1. Send a SIGTERM
if output, err := exec.Command("/usr/bin/lxc-kill", "-n", container.Id, "15").CombinedOutput(); err != nil {
log.Printf(string(output))
log.Printf("Failed to send SIGTERM to the process, force killing")
if output, err := exec.Command("lxc-kill", "-n", container.Id, "15").CombinedOutput(); err != nil {
log.Print(string(output))
log.Print("Failed to send SIGTERM to the process, force killing")
if err := container.Kill(); err != nil {
return err
}
@@ -523,6 +628,17 @@ func (container *Container) Wait() int {
return container.State.ExitCode
}
func (container *Container) ExportRw() (Archive, error) {
return Tar(container.rwPath(), Uncompressed)
}
func (container *Container) Export() (Archive, error) {
if err := container.EnsureMounted(); err != nil {
return nil, err
}
return Tar(container.RootfsPath(), Uncompressed)
}
func (container *Container) WaitTimeout(timeout time.Duration) error {
done := make(chan bool)
go func() {
@@ -532,9 +648,89 @@ func (container *Container) WaitTimeout(timeout time.Duration) error {
select {
case <-time.After(timeout):
return errors.New("Timed Out")
return fmt.Errorf("Timed Out")
case <-done:
return nil
}
panic("unreachable")
}
func (container *Container) EnsureMounted() error {
if mounted, err := container.Mounted(); err != nil {
return err
} else if mounted {
return nil
}
return container.Mount()
}
func (container *Container) Mount() error {
image, err := container.GetImage()
if err != nil {
return err
}
return image.Mount(container.RootfsPath(), container.rwPath())
}
func (container *Container) Changes() ([]Change, error) {
image, err := container.GetImage()
if err != nil {
return nil, err
}
return image.Changes(container.rwPath())
}
func (container *Container) GetImage() (*Image, error) {
if container.runtime == nil {
return nil, fmt.Errorf("Can't get image of unregistered container")
}
return container.runtime.graph.Get(container.Image)
}
func (container *Container) Mounted() (bool, error) {
return Mounted(container.RootfsPath())
}
func (container *Container) Unmount() error {
return Unmount(container.RootfsPath())
}
// ShortId returns a shorthand version of the container's id for convenience.
// A collision with other container shorthands is very unlikely, but possible.
// In case of a collision a lookup with Runtime.Get() will fail, and the caller
// will need to use a langer prefix, or the full-length container Id.
func (container *Container) ShortId() string {
return TruncateId(container.Id)
}
func (container *Container) logPath(name string) string {
return path.Join(container.root, fmt.Sprintf("%s-%s.log", container.Id, name))
}
func (container *Container) ReadLog(name string) (io.Reader, error) {
return os.Open(container.logPath(name))
}
func (container *Container) jsonPath() string {
return path.Join(container.root, "config.json")
}
func (container *Container) lxcConfigPath() string {
return path.Join(container.root, "config.lxc")
}
// This method must be exported to be used from the lxc template
func (container *Container) RootfsPath() string {
return path.Join(container.root, "rootfs")
}
func (container *Container) rwPath() string {
return path.Join(container.root, "rw")
}
func validateId(id string) error {
if id == "" {
return fmt.Errorf("Invalid empty id")
}
return nil
}
+444 -252
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
The `contrib` directory contains scripts, images, and other helpful things
which are not part of the core docker distribution. Please note that they
could be out of date, since they do not receive the same attention as the
rest of the repository.
+2 -2
View File
@@ -38,14 +38,14 @@ fi
echo "Downloading docker binary and uncompressing into /usr/local/bin..."
curl -s http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz |
tar -C /usr/local/bin --strip-components=1 -zxf- \
docker-master/docker docker-master/dockerd
docker-master/docker
if [ -f /etc/init/dockerd.conf ]
then
echo "Upstart script already exists."
else
echo "Creating /etc/init/dockerd.conf..."
echo "exec /usr/local/bin/dockerd" > /etc/init/dockerd.conf
echo "exec /usr/local/bin/docker -d" > /etc/init/dockerd.conf
fi
echo "Starting dockerd..."
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
# Generate a very minimal filesystem based on busybox-static,
# and load it into the local docker under the name "busybox".
BUSYBOX=$(which busybox)
[ "$BUSYBOX" ] || {
echo "Sorry, I could not locate busybox."
echo "Try 'apt-get install busybox-static'?"
exit 1
}
set -e
ROOTFS=/tmp/rootfs-busybox-$$-$RANDOM
mkdir $ROOTFS
cd $ROOTFS
mkdir bin etc dev dev/pts lib proc sys tmp
touch etc/resolv.conf
cp /etc/nsswitch.conf etc/nsswitch.conf
echo root:x:0:0:root:/:/bin/sh > etc/passwd
echo root:x:0: > etc/group
ln -s lib lib64
ln -s bin sbin
cp $BUSYBOX bin
for X in $(busybox --list)
do
ln -s busybox bin/$X
done
rm bin/init
ln bin/busybox bin/init
cp /lib/x86_64-linux-gnu/lib{pthread,c,dl,nsl,nss_*}.so.* lib
cp /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 lib
for X in console null ptmx random stdin stdout stderr tty urandom zero
do
cp -a /dev/$X dev
done
tar -cf- . | docker import - busybox
docker run -i -u root busybox /bin/echo Success.
+1
View File
@@ -0,0 +1 @@
../Makefile
+73
View File
@@ -0,0 +1,73 @@
PKG_NAME=dotcloud-docker
PKG_ARCH=amd64
PKG_VERSION=1
ROOT_PATH:=$(PWD)
BUILD_PATH=build # Do not change, decided by dpkg-buildpackage
BUILD_SRC=build_src
GITHUB_PATH=src/github.com/dotcloud/docker
INSDIR=usr/bin
SOURCE_PACKAGE=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
DEB_PACKAGE=$(PKG_NAME)_$(PKG_VERSION)_$(PKG_ARCH).deb
EXTRA_GO_PKG=./auth
TMPDIR=$(shell mktemp -d -t XXXXXX)
# Build a debian source package
all: clean build_in_deb
build_in_deb:
echo "GOPATH = " $(ROOT_PATH)
mkdir bin
cd $(GITHUB_PATH)/docker; GOPATH=$(ROOT_PATH) go build -o $(ROOT_PATH)/bin/docker
# DESTDIR provided by Debian packaging
install:
# Call this from a go environment (as packaged for deb source package)
mkdir -p $(DESTDIR)/$(INSDIR)
mkdir -p $(DESTDIR)/etc/init
install -m 0755 bin/docker $(DESTDIR)/$(INSDIR)
install -o root -m 0755 etc/docker.upstart $(DESTDIR)/etc/init/docker.conf
$(BUILD_SRC): clean
# Copy ourselves into $BUILD_SRC to comply with unusual golang constraints
tar --exclude=*.tar.gz --exclude=checkout.tgz -f checkout.tgz -cz *
mkdir -p $(BUILD_SRC)/$(GITHUB_PATH)
tar -f checkout.tgz -C $(BUILD_SRC)/$(GITHUB_PATH) -xz
cd $(BUILD_SRC)/$(GITHUB_PATH)/docker; GOPATH=$(ROOT_PATH)/$(BUILD_SRC) go get -d
for d in `find $(BUILD_SRC) -name '.git*'`; do rm -rf $$d; done
# Populate source build with debian stuff
cp -R -L ./deb/* $(BUILD_SRC)
$(SOURCE_PACKAGE): $(BUILD_SRC)
rm -f $(SOURCE_PACKAGE)
# Create the debian source package
tar -f $(SOURCE_PACKAGE) -C ${ROOT_PATH}/${BUILD_SRC} -cz .
# Build deb package fetching go dependencies and cleaning up git repositories
deb: $(DEB_PACKAGE)
$(DEB_PACKAGE): $(SOURCE_PACKAGE)
# dpkg-buildpackage looks for source package tarball in ../
cd $(BUILD_SRC); dpkg-buildpackage
rm -rf $(BUILD_PATH) debian/$(PKG_NAME)* debian/files
debsrc: $(SOURCE_PACKAGE)
# Build local sources
#$(PKG_NAME): build_local
build_local:
-@mkdir -p bin
cd docker && go build -o ../bin/docker
gotest:
@echo "\033[36m[Testing]\033[00m docker..."
@sudo -E GOPATH=$(ROOT_PATH)/$(BUILD_SRC) go test -v . $(EXTRA_GO_PKG) && \
echo -n "\033[32m[OK]\033[00m" || \
echo -n "\033[31m[FAIL]\033[00m"; \
echo " docker"
@sudo rm -rf /tmp/docker-*
clean:
rm -rf $(BUILD_PATH) debian/$(PKG_NAME)* debian/files $(BUILD_SRC) checkout.tgz bin
+1
View File
@@ -0,0 +1 @@
../README.md
+5
View File
@@ -0,0 +1,5 @@
dotcloud-docker (1) precise; urgency=low
* Initial release
-- dotCloud <ops@dotcloud.com> Mon, 14 Mar 2013 04:43:21 -0700
+1
View File
@@ -0,0 +1 @@
8
+20
View File
@@ -0,0 +1,20 @@
Source: dotcloud-docker
Section: misc
Priority: extra
Homepage: https://github.com/dotcloud/docker
Maintainer: Daniel Mizyrycki <daniel@dotcloud.com>
Build-Depends: debhelper (>= 8.0.0), git, golang
Vcs-Git: https://github.com/dotcloud/docker.git
Standards-Version: 3.9.2
Package: dotcloud-docker
Architecture: amd64
Provides: dotcloud-docker
Depends: lxc, wget, bsdtar, curl
Conflicts: docker
Description: A process manager with superpowers
It encapsulates heterogeneous payloads in Standard Containers, and runs
them on any server with strong guarantees of isolation and repeatability.
Is is a great building block for automating distributed systems:
large-scale web deployments, database clusters, continuous deployment
systems, private PaaS, service-oriented architectures, etc.
+209
View File
@@ -0,0 +1,209 @@
Format: http://dep.debian.net/deps/dep5
Upstream-Name: dotcloud-docker
Source: https://github.com/dotcloud/docker
Files: *
Copyright: 2012 DotCloud Inc (opensource@dotcloud.com)
License: Apache License Version 2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2012 DotCloud Inc (opensource@dotcloud.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+1
View File
@@ -0,0 +1 @@
README.md
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
+1
View File
@@ -0,0 +1 @@
3.0 (quilt)
+10
View File
@@ -0,0 +1,10 @@
description "Run docker"
start on runlevel [2345]
stop on starting rc RUNLEVEL=[016]
respawn
script
test -f /etc/default/locale && . /etc/default/locale || true
LANG=$LANG LC_ALL=$LANG /usr/bin/docker -d
end script
+10
View File
@@ -0,0 +1,10 @@
description "Run docker"
start on runlevel [2345]
stop on starting rc RUNLEVEL=[016]
respawn
script
test -f /etc/default/locale && . /etc/default/locale || true
LANG=$LANG LC_ALL=$LANG /usr/bin/docker -d
end script
-160
View File
@@ -1,160 +0,0 @@
package docker
import (
"./fs"
"container/list"
"fmt"
"io/ioutil"
"log"
"os"
"path"
"sort"
)
type Docker struct {
root string
repository string
containers *list.List
networkManager *NetworkManager
Store *fs.Store
}
func (docker *Docker) List() []*Container {
containers := new(History)
for e := docker.containers.Front(); e != nil; e = e.Next() {
containers.Add(e.Value.(*Container))
}
return *containers
}
func (docker *Docker) getContainerElement(id string) *list.Element {
for e := docker.containers.Front(); e != nil; e = e.Next() {
container := e.Value.(*Container)
if container.Id == id {
return e
}
}
return nil
}
func (docker *Docker) Get(id string) *Container {
e := docker.getContainerElement(id)
if e == nil {
return nil
}
return e.Value.(*Container)
}
func (docker *Docker) Exists(id string) bool {
return docker.Get(id) != nil
}
func (docker *Docker) Create(id string, command string, args []string, image *fs.Image, config *Config) (*Container, error) {
if docker.Exists(id) {
return nil, fmt.Errorf("Container %v already exists", id)
}
root := path.Join(docker.repository, id)
container, err := createContainer(id, root, command, args, image, config, docker.networkManager)
if err != nil {
return nil, err
}
docker.containers.PushBack(container)
return container, nil
}
func (docker *Docker) Destroy(container *Container) error {
element := docker.getContainerElement(container.Id)
if element == nil {
return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.Id)
}
if err := container.Stop(); err != nil {
return err
}
if container.Mountpoint.Mounted() {
if err := container.Mountpoint.Umount(); err != nil {
log.Printf("Unable to umount container %v: %v", container.Id, err)
}
if err := container.Mountpoint.Deregister(); err != nil {
log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
}
}
if err := os.RemoveAll(container.Root); err != nil {
log.Printf("Unable to remove filesystem for %v: %v", container.Id, err)
}
docker.containers.Remove(element)
return nil
}
func (docker *Docker) restore() error {
dir, err := ioutil.ReadDir(docker.repository)
if err != nil {
return err
}
for _, v := range dir {
container, err := loadContainer(docker.Store, path.Join(docker.repository, v.Name()), docker.networkManager)
if err != nil {
log.Printf("Failed to load container %v: %v", v.Name(), err)
continue
}
docker.containers.PushBack(container)
}
return nil
}
func New() (*Docker, error) {
return NewFromDirectory("/var/lib/docker")
}
func NewFromDirectory(root string) (*Docker, error) {
store, err := fs.New(path.Join(root, "images"))
if err != nil {
return nil, err
}
netManager, err := newNetworkManager(networkBridgeIface)
if err != nil {
return nil, err
}
docker := &Docker{
root: root,
repository: path.Join(root, "containers"),
containers: list.New(),
Store: store,
networkManager: netManager,
}
if err := os.MkdirAll(docker.repository, 0700); err != nil && !os.IsExist(err) {
return nil, err
}
if err := docker.restore(); err != nil {
return nil, err
}
return docker, nil
}
type History []*Container
func (history *History) Len() int {
return len(*history)
}
func (history *History) Less(i, j int) bool {
containers := *history
return containers[j].When().Before(containers[i].When())
}
func (history *History) Swap(i, j int) {
containers := *history
tmp := containers[i]
containers[i] = containers[j]
containers[j] = tmp
}
func (history *History) Add(container *Container) {
*history = append(*history, container)
sort.Sort(history)
}
+94 -14
View File
@@ -1,29 +1,109 @@
package main
import (
"../client"
"flag"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/term"
"io"
"log"
"os"
"path"
"os/signal"
)
var GIT_COMMIT string
func main() {
if cmd := path.Base(os.Args[0]); cmd == "docker" {
fl_shell := flag.Bool("i", false, "Interactive mode")
flag.Parse()
if *fl_shell {
if err := client.InteractiveMode(flag.Args()...); err != nil {
log.Fatal(err)
}
} else {
if err := client.SimpleMode(os.Args[1:]); err != nil {
log.Fatal(err)
}
if docker.SelfPath() == "/sbin/init" {
// Running in init mode
docker.SysInit()
return
}
// FIXME: Switch d and D ? (to be more sshd like)
flDaemon := flag.Bool("d", false, "Daemon mode")
flDebug := flag.Bool("D", false, "Debug mode")
flag.Parse()
if *flDebug {
os.Setenv("DEBUG", "1")
}
docker.GIT_COMMIT = GIT_COMMIT
if *flDaemon {
if flag.NArg() != 0 {
flag.Usage()
return
}
if err := daemon(); err != nil {
log.Fatal(err)
}
} else {
if err := client.SimpleMode(append([]string{cmd}, os.Args[1:]...)); err != nil {
if err := runCommand(flag.Args()); err != nil {
log.Fatal(err)
}
}
}
func daemon() error {
service, err := docker.NewServer()
if err != nil {
return err
}
return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
}
func runCommand(args []string) error {
var oldState *term.State
var err error
if term.IsTerminal(int(os.Stdin.Fd())) && os.Getenv("NORAW") == "" {
oldState, err = term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
return err
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for _ = range c {
term.Restore(int(os.Stdin.Fd()), oldState)
log.Printf("\nSIGINT received\n")
os.Exit(0)
}
}()
}
// FIXME: we want to use unix sockets here, but net.UnixConn doesn't expose
// CloseWrite(), which we need to cleanly signal that stdin is closed without
// closing the connection.
// See http://code.google.com/p/go/issues/detail?id=3345
if conn, err := rcli.Call("tcp", "127.0.0.1:4242", args...); err == nil {
receiveStdout := docker.Go(func() error {
_, err := io.Copy(os.Stdout, conn)
return err
})
sendStdin := docker.Go(func() error {
_, err := io.Copy(conn, os.Stdin)
if err := conn.CloseWrite(); err != nil {
log.Printf("Couldn't send EOF: " + err.Error())
}
return err
})
if err := <-receiveStdout; err != nil {
return err
}
if !term.IsTerminal(int(os.Stdin.Fd())) {
if err := <-sendStdin; err != nil {
return err
}
}
} else {
service, err := docker.NewServer()
if err != nil {
return err
}
if err := rcli.LocalCall(service, os.Stdin, os.Stdout, args...); err != nil {
return err
}
}
if oldState != nil {
term.Restore(int(os.Stdin.Fd()), oldState)
}
return nil
}
-290
View File
@@ -1,290 +0,0 @@
package docker
import (
"./fs"
"io"
"io/ioutil"
"log"
"os"
"testing"
)
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
func nuke(docker *Docker) error {
return os.RemoveAll(docker.root)
}
func layerArchive(tarfile string) (io.Reader, error) {
// FIXME: need to close f somewhere
f, err := os.Open(tarfile)
if err != nil {
return nil, err
}
return f, nil
}
func init() {
// Hack to run sys init during unit testing
if SelfPath() == "/sbin/init" {
SysInit()
}
// Make sure the unit test image is there
if _, err := os.Stat(testLayerPath); err != nil {
if !os.IsNotExist(err) {
panic(err)
}
log.Fatalf("Unit test base image not found. Please fix the problem by running \"debootstrap --arch=amd64 quantal %v\"", testLayerPath)
return
}
}
func newTestDocker() (*Docker, error) {
root, err := ioutil.TempDir("", "docker-test")
if err != nil {
return nil, err
}
docker, err := NewFromDirectory(root)
if err != nil {
return nil, err
}
if layer, err := layerArchive(testLayerPath); err != nil {
panic(err)
} else {
_, err = docker.Store.Create(layer, nil, "docker-ut", "unit tests")
if err != nil {
panic(err)
}
}
return docker, nil
}
func GetTestImage(docker *Docker) *fs.Image {
imgs, err := docker.Store.Images()
if err != nil {
panic(err)
} else if len(imgs) < 1 {
panic("GASP")
}
return imgs[0]
}
func TestCreate(t *testing.T) {
docker, err := newTestDocker()
if err != nil {
t.Fatal(err)
}
defer nuke(docker)
// Make sure we start we 0 containers
if len(docker.List()) != 0 {
t.Errorf("Expected 0 containers, %v found", len(docker.List()))
}
container, err := docker.Create(
"test_create",
"ls",
[]string{"-al"},
GetTestImage(docker),
&Config{},
)
if err != nil {
t.Fatal(err)
}
defer func() {
if err := docker.Destroy(container); err != nil {
t.Error(err)
}
}()
// Make sure we can find the newly created container with List()
if len(docker.List()) != 1 {
t.Errorf("Expected 1 container, %v found", len(docker.List()))
}
// Make sure the container List() returns is the right one
if docker.List()[0].Id != "test_create" {
t.Errorf("Unexpected container %v returned by List", docker.List()[0])
}
// Make sure we can get the container with Get()
if docker.Get("test_create") == nil {
t.Errorf("Unable to get newly created container")
}
// Make sure it is the right container
if docker.Get("test_create") != container {
t.Errorf("Get() returned the wrong container")
}
// Make sure Exists returns it as existing
if !docker.Exists("test_create") {
t.Errorf("Exists() returned false for a newly created container")
}
}
func TestDestroy(t *testing.T) {
docker, err := newTestDocker()
if err != nil {
t.Fatal(err)
}
defer nuke(docker)
container, err := docker.Create(
"test_destroy",
"ls",
[]string{"-al"},
GetTestImage(docker),
&Config{},
)
if err != nil {
t.Fatal(err)
}
// Destroy
if err := docker.Destroy(container); err != nil {
t.Error(err)
}
// Make sure docker.Exists() behaves correctly
if docker.Exists("test_destroy") {
t.Errorf("Exists() returned true")
}
// Make sure docker.List() doesn't list the destroyed container
if len(docker.List()) != 0 {
t.Errorf("Expected 0 container, %v found", len(docker.List()))
}
// Make sure docker.Get() refuses to return the unexisting container
if docker.Get("test_destroy") != nil {
t.Errorf("Unable to get newly created container")
}
// Make sure the container root directory does not exist anymore
_, err = os.Stat(container.Root)
if err == nil || !os.IsNotExist(err) {
t.Errorf("Container root directory still exists after destroy")
}
// Test double destroy
if err := docker.Destroy(container); err == nil {
// It should have failed
t.Errorf("Double destroy did not fail")
}
}
func TestGet(t *testing.T) {
docker, err := newTestDocker()
if err != nil {
t.Fatal(err)
}
defer nuke(docker)
container1, err := docker.Create(
"test1",
"ls",
[]string{"-al"},
GetTestImage(docker),
&Config{},
)
if err != nil {
t.Fatal(err)
}
defer docker.Destroy(container1)
container2, err := docker.Create(
"test2",
"ls",
[]string{"-al"},
GetTestImage(docker),
&Config{},
)
if err != nil {
t.Fatal(err)
}
defer docker.Destroy(container2)
container3, err := docker.Create(
"test3",
"ls",
[]string{"-al"},
GetTestImage(docker),
&Config{},
)
if err != nil {
t.Fatal(err)
}
defer docker.Destroy(container3)
if docker.Get("test1") != container1 {
t.Errorf("Get(test1) returned %v while expecting %v", docker.Get("test1"), container1)
}
if docker.Get("test2") != container2 {
t.Errorf("Get(test2) returned %v while expecting %v", docker.Get("test2"), container2)
}
if docker.Get("test3") != container3 {
t.Errorf("Get(test3) returned %v while expecting %v", docker.Get("test3"), container3)
}
}
func TestRestore(t *testing.T) {
root, err := ioutil.TempDir("", "docker-test")
if err != nil {
t.Fatal(err)
}
docker1, err := NewFromDirectory(root)
if err != nil {
t.Fatal(err)
}
defer nuke(docker1)
if layer, err := layerArchive(testLayerPath); err != nil {
panic(err)
} else {
_, err = docker1.Store.Create(layer, nil, "docker-ut", "unit tests")
if err != nil {
panic(err)
}
}
// Create a container with one instance of docker
container1, err := docker1.Create(
"restore_test",
"ls",
[]string{"-al"},
GetTestImage(docker1),
&Config{},
)
if err != nil {
t.Fatal(err)
}
defer docker1.Destroy(container1)
if len(docker1.List()) != 1 {
t.Errorf("Expected 1 container, %v found", len(docker1.List()))
}
if err := container1.Run(); err != nil {
t.Fatal(err)
}
// Here are are simulating a docker restart - that is, reloading all containers
// from scratch
docker2, err := NewFromDirectory(root)
if err != nil {
t.Fatal(err)
}
defer nuke(docker2)
if len(docker2.List()) != 1 {
t.Errorf("Expected 1 container, %v found", len(docker2.List()))
}
container2 := docker2.Get("restore_test")
if container2 == nil {
t.Fatal("Unable to Get container")
}
if err := container2.Run(); err != nil {
t.Fatal(err)
}
}
-24
View File
@@ -1,24 +0,0 @@
package main
import (
".."
"../server"
"flag"
"log"
)
func main() {
if docker.SelfPath() == "/sbin/init" {
// Running in init mode
docker.SysInit()
return
}
flag.Parse()
d, err := server.New()
if err != nil {
log.Fatal(err)
}
if err := d.ListenAndServe(); err != nil {
log.Fatal(err)
}
}
File diff suppressed because one or more lines are too long
+184
View File
@@ -0,0 +1,184 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) sources
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
# @echo " html to make standalone HTML files"
# @echo " dirhtml to make HTML files named index.html in directories"
# @echo " singlehtml to make a single large HTML file"
# @echo " pickle to make pickle files"
# @echo " json to make JSON files"
# @echo " htmlhelp to make HTML files and a HTML help project"
# @echo " qthelp to make HTML files and a qthelp project"
# @echo " devhelp to make HTML files and a Devhelp project"
# @echo " epub to make an epub"
# @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
# @echo " latexpdf to make LaTeX files and run them through pdflatex"
# @echo " text to make text files"
# @echo " man to make manual pages"
# @echo " texinfo to make Texinfo files"
# @echo " info to make Texinfo files and run them through makeinfo"
# @echo " gettext to make PO message catalogs"
# @echo " changes to make an overview of all changed/added/deprecated items"
# @echo " linkcheck to check all external links for integrity"
# @echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " docs to build the docs and copy the static files to the outputdir"
@echo " publish to publish the app to dotcloud"
clean:
-rm -rf $(BUILDDIR)/*
docs:
-rm -rf $(BUILDDIR)/*
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/html
cp sources/index.html $(BUILDDIR)/html/
cp -r sources/gettingstarted $(BUILDDIR)/html/
cp sources/dotcloud.yml $(BUILDDIR)/html/
cp sources/CNAME $(BUILDDIR)/html/
cp sources/.nojekyll $(BUILDDIR)/html/
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
connect:
@echo pushing changes to staging site
@cd _build/html/ ; \
@dotcloud list ; \
dotcloud connect dockerwebsite
push:
@cd _build/html/ ; \
dotcloud push
github-deploy: docs
rm -fr github-deploy
git clone ssh://git@github.com/dotcloud/docker github-deploy
cd github-deploy && git checkout -f gh-pages && git rm -r * && rsync -avH ../_build/html/ ./ && touch .nojekyll && echo "docker.io" > CNAME && git add * && git commit -m "Updating docs"
$(VERSIONS):
@echo "Hello world"
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Docker.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Docker.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Docker"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Docker"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
+42
View File
@@ -0,0 +1,42 @@
Docker documentation and website
================================
Documentation
-------------
This is your definite place to contribute to the docker documentation. The documentation is generated from the
.rst files under sources.
The folder also contains the other files to create the http://docker.io website, but you can generally ignore
most of those.
Installation
------------
* Work in your own fork of the code, we accept pull requests.
* Install sphinx: ``pip install sphinx``
* If pip is not available you can probably install it using your favorite package manager as **python-pip**
Usage
-----
* change the .rst files with your favorite editor to your liking
* run *make docs* to clean up old files and generate new ones
* your static website can now be found in the _build dir
* to preview what you have generated, cd into _build/html and then run 'python -m SimpleHTTPServer 8000'
Working using github's file editor
----------------------------------
Alternatively, for small changes and typo's you might want to use github's built in file editor. It allows
you to preview your changes right online. Just be carefull not to create many commits.
Images
------
When you need to add images, try to make them as small as possible (e.g. as gif).
Notes
-----
* The index.html and gettingstarted.html files are copied from the source dir to the output dir without modification.
So changes to those pages should be made directly in html
* For the template the css is compiled from less. When changes are needed they can be compiled using
lessc ``lessc main.less`` or watched using watch-lessc ``watch-lessc -i main.less -o main.css``
View File
+1
View File
@@ -0,0 +1 @@
docker.io
+100
View File
@@ -0,0 +1,100 @@
:title: Base commands
:description: Common usage and commands
:keywords: Examples, Usage
The basics
=============
Starting Docker
---------------
If you have used one of the quick install paths', Docker may have been installed with upstart, Ubuntu's
system for starting processes at boot time. You should be able to run ``docker help`` and get output.
If you get ``docker: command not found`` or something like ``/var/lib/docker/repositories: permission denied``
you will need to specify the path to it and manually start it.
.. code-block:: bash
# Run docker in daemon mode
sudo <path to>/docker -d &
Running an interactive shell
----------------------------
.. code-block:: bash
# Download a base image
docker pull base
# Run an interactive shell in the base image,
# allocate a tty, attach stdin and stdout
docker run -i -t base /bin/bash
Starting a long-running worker process
--------------------------------------
.. code-block:: bash
# Start a very useful long-running process
JOB=$(docker run -d base /bin/sh -c "while true; do echo Hello world; sleep 1; done")
# Collect the output of the job so far
docker logs $JOB
# Kill the job
docker kill $JOB
Listing all running containers
------------------------------
.. code-block:: bash
docker ps
Expose a service on a TCP port
------------------------------
.. code-block:: bash
# Expose port 4444 of this container, and tell netcat to listen on it
JOB=$(docker run -d -p 4444 base /bin/nc -l -p 4444)
# Which public port is NATed to my container?
PORT=$(docker port $JOB 4444)
# Connect to the public port via the host's public address
# Please note that because of how routing works connecting to localhost or 127.0.0.1 $PORT will not work.
echo hello world | nc $(hostname) $PORT
# Verify that the network connection worked
echo "Daemon received: $(docker logs $JOB)"
Committing (saving) an image
-----------------------------
Save your containers state to a container image, so the state can be re-used.
When you commit your container only the differences between the image the container was created from
and the current state of the container will be stored (as a diff). See which images you already have
using ``docker images``
.. code-block:: bash
# Commit your container to a new named image
docker commit <container_id> <some_name>
# List your containers
docker images
You now have a image state from which you can create new instances.
Read more about :ref:`working_with_the_repository` or continue to the complete :ref:`cli`
+53
View File
@@ -0,0 +1,53 @@
:title: Command Line Interface
:description: Docker's CLI command description and usage
:keywords: Docker, Docker documentation, CLI, command line
.. _cli:
Command Line Interface
======================
Docker Usage
~~~~~~~~~~~~
To list available commands, either run ``docker`` with no parameters or execute
``docker help``::
$ docker
Usage: docker COMMAND [arg...]
A self-sufficient runtime for linux containers.
...
Available Commands
~~~~~~~~~~~~~~~~~~
.. toctree::
:maxdepth: 1
command/attach
command/commit
command/diff
command/export
command/history
command/images
command/import
command/info
command/inspect
command/kill
command/login
command/logs
command/port
command/ps
command/pull
command/push
command/restart
command/rm
command/rmi
command/run
command/start
command/stop
command/tag
command/version
command/wait
@@ -0,0 +1,9 @@
===========================================
``attach`` -- Attach to a running container
===========================================
::
Usage: docker attach CONTAINER
Attach to a running container
@@ -0,0 +1,11 @@
===========================================================
``commit`` -- Create a new image from a container's changes
===========================================================
::
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY [TAG]]
Create a new image from a container's changes
-m="": Commit message
@@ -0,0 +1,9 @@
=======================================================
``diff`` -- Inspect changes on a container's filesystem
=======================================================
::
Usage: docker diff CONTAINER [OPTIONS]
Inspect changes on a container's filesystem
@@ -0,0 +1,9 @@
=================================================================
``export`` -- Stream the contents of a container as a tar archive
=================================================================
::
Usage: docker export CONTAINER
Export the contents of a filesystem as a tar archive
@@ -0,0 +1,9 @@
===========================================
``history`` -- Show the history of an image
===========================================
::
Usage: docker history [OPTIONS] IMAGE
Show the history of an image
@@ -0,0 +1,12 @@
=========================
``images`` -- List images
=========================
::
Usage: docker images [OPTIONS] [NAME]
List images
-a=false: show all images
-q=false: only show numeric IDs
@@ -0,0 +1,9 @@
==========================================================================
``import`` -- Create a new filesystem image from the contents of a tarball
==========================================================================
::
Usage: docker import [OPTIONS] URL|- [REPOSITORY [TAG]]
Create a new filesystem image from the contents of a tarball
@@ -0,0 +1,9 @@
===========================================
``info`` -- Display system-wide information
===========================================
::
Usage: docker info
Display system-wide information.
@@ -0,0 +1,9 @@
==========================================================
``inspect`` -- Return low-level information on a container
==========================================================
::
Usage: docker inspect [OPTIONS] CONTAINER
Return low-level information on a container
@@ -0,0 +1,9 @@
====================================
``kill`` -- Kill a running container
====================================
::
Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
Kill a running container
@@ -0,0 +1,9 @@
============================================================
``login`` -- Register or Login to the docker registry server
============================================================
::
Usage: docker login
Register or Login to the docker registry server
@@ -0,0 +1,9 @@
=========================================
``logs`` -- Fetch the logs of a container
=========================================
::
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
@@ -0,0 +1,9 @@
=========================================================================
``port`` -- Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
=========================================================================
::
Usage: docker port [OPTIONS] CONTAINER PRIVATE_PORT
Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
+13
View File
@@ -0,0 +1,13 @@
=========================
``ps`` -- List containers
=========================
::
Usage: docker ps [OPTIONS]
List containers
-a=false: Show all containers. Only running containers are shown by default.
-notrunc=false: Don't truncate output
-q=false: Only display numeric IDs
@@ -0,0 +1,9 @@
=========================================================================
``pull`` -- Pull an image or a repository from the docker registry server
=========================================================================
::
Usage: docker pull NAME
Pull an image or a repository from the registry
@@ -0,0 +1,9 @@
=======================================================================
``push`` -- Push an image or a repository to the docker registry server
=======================================================================
::
Usage: docker push NAME
Push an image or a repository to the registry
@@ -0,0 +1,9 @@
==========================================
``restart`` -- Restart a running container
==========================================
::
Usage: docker restart [OPTIONS] NAME
Restart a running container
+9
View File
@@ -0,0 +1,9 @@
============================
``rm`` -- Remove a container
============================
::
Usage: docker rm [OPTIONS] CONTAINER
Remove a container
+9
View File
@@ -0,0 +1,9 @@
==========================
``rmi`` -- Remove an image
==========================
::
Usage: docker rmimage [OPTIONS] IMAGE
Remove an image
+19
View File
@@ -0,0 +1,19 @@
===========================================
``run`` -- Run a command in a new container
===========================================
::
Usage: docker run [OPTIONS] IMAGE COMMAND [ARG...]
Run a command in a new container
-a=map[]: Attach to stdin, stdout or stderr.
-d=false: Detached mode: leave the container running in the background
-e=[]: Set environment variables
-h="": Container host name
-i=false: Keep stdin open even if not attached
-m=0: Memory limit (in bytes)
-p=[]: Map a network port to the container
-t=false: Allocate a pseudo-tty
-u="": Username or UID
@@ -0,0 +1,9 @@
======================================
``start`` -- Start a stopped container
======================================
::
Usage: docker start [OPTIONS] NAME
Start a stopped container
@@ -0,0 +1,9 @@
====================================
``stop`` -- Stop a running container
====================================
::
Usage: docker stop [OPTIONS] NAME
Stop a running container
+11
View File
@@ -0,0 +1,11 @@
=========================================
``tag`` -- Tag an image into a repository
=========================================
::
Usage: docker tag [OPTIONS] IMAGE REPOSITORY [TAG]
Tag an image into a repository
-f=false: Force
@@ -0,0 +1,3 @@
==================================================
``version`` -- Show the docker version information
==================================================
@@ -0,0 +1,9 @@
===================================================================
``wait`` -- Block until a container stops, then print its exit code
===================================================================
::
Usage: docker wait [OPTIONS] NAME
Block until a container stops, then print its exit code.
+16
View File
@@ -0,0 +1,16 @@
:title: docker documentation
:description: -- todo: change me
:keywords: todo: change me
Commands
========
Contents:
.. toctree::
:maxdepth: 2
basics
workingwithrepository
cli
@@ -0,0 +1,42 @@
.. _working_with_the_repository:
Working with the repository
============================
Connecting to the repository
----------------------------
You create a user on the central docker repository by running
.. code-block:: bash
docker login
If your username does not exist it will prompt you to also enter a password and your e-mail address. It will then
automatically log you in.
Committing a container to a named image
---------------------------------------
In order to commit to the repository it is required to have committed your container to an image with your namespace.
.. code-block:: bash
# for example docker commit $CONTAINER_ID dhrp/kickassapp
docker commit <container_id> <your username>/<some_name>
Pushing a container to the repository
-----------------------------------------
In order to push an image to the repository you need to have committed your container to a named image (see above)
Now you can commit this image to the repository
.. code-block:: bash
# for example docker push dhrp/kickassapp
docker push <image-name>
+25
View File
@@ -0,0 +1,25 @@
:title: Building blocks
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
Building blocks
===============
.. _images:
Images
------
An original container image. These are stored on disk and are comparable with what you normally expect from a stoppped virtual machine image. Images are stored (and retrieved from) repository
Images are stored on your local file system under /var/lib/docker/images
.. _containers:
Containers
----------
A container is a local version of an image. It can be running or stopped, The equivalent would be a virtual machine instance.
Containers are stored on your local file system under /var/lib/docker/containers
+128
View File
@@ -0,0 +1,128 @@
:title: Introduction
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
:note: This version of the introduction is temporary, just to make sure we don't break the links from the website when the documentation is updated
Introduction
============
Docker - The Linux container runtime
------------------------------------
Docker complements LXC with a high-level API which operates at the process level. It runs unix processes with strong guarantees of isolation and repeatability across servers.
Docker is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
- **Heterogeneous payloads** Any combination of binaries, libraries, configuration files, scripts, virtualenvs, jars, gems, tarballs, you name it. No more juggling between domain-specific tools. Docker can deploy and run them all.
- **Any server** Docker can run on any x64 machine with a modern linux kernel - whether it's a laptop, a bare metal server or a VM. This makes it perfect for multi-cloud deployments.
- **Isolation** docker isolates processes from each other and from the underlying host, using lightweight containers.
- **Repeatability** Because containers are isolated in their own filesystem, they behave the same regardless of where, when, and alongside what they run.
What is a Standard Container?
-----------------------------
Docker defines a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependency, regardless of the underlying machine and the contents of the container.
The spec for Standard Containers is currently work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
A great analogy for this is the shipping container. Just like Standard Containers are a fundamental unit of software delivery, shipping containers (http://bricks.argz.com/ins/7823-1/12) are a fundamental unit of physical delivery.
Standard operations
~~~~~~~~~~~~~~~~~~~
Just like shipping containers, Standard Containers define a set of STANDARD OPERATIONS. Shipping containers can be lifted, stacked, locked, loaded, unloaded and labelled. Similarly, standard containers can be started, stopped, copied, snapshotted, downloaded, uploaded and tagged.
Content-agnostic
~~~~~~~~~~~~~~~~~~~
Just like shipping containers, Standard Containers are CONTENT-AGNOSTIC: all standard operations have the same effect regardless of the contents. A shipping container will be stacked in exactly the same way whether it contains Vietnamese powder coffee or spare Maserati parts. Similarly, Standard Containers are started or uploaded in the same way whether they contain a postgres database, a php application with its dependencies and application server, or Java build artifacts.
Infrastructure-agnostic
~~~~~~~~~~~~~~~~~~~~~~~~~~
Both types of containers are INFRASTRUCTURE-AGNOSTIC: they can be transported to thousands of facilities around the world, and manipulated by a wide variety of equipment. A shipping container can be packed in a factory in Ukraine, transported by truck to the nearest routing center, stacked onto a train, loaded into a German boat by an Australian-built crane, stored in a warehouse at a US facility, etc. Similarly, a standard container can be bundled on my laptop, uploaded to S3, downloaded, run and snapshotted by a build server at Equinix in Virginia, uploaded to 10 staging servers in a home-made Openstack cluster, then sent to 30 production instances across 3 EC2 regions.
Designed for automation
~~~~~~~~~~~~~~~~~~~~~~~~~~
Because they offer the same standard operations regardless of content and infrastructure, Standard Containers, just like their physical counterpart, are extremely well-suited for automation. In fact, you could say automation is their secret weapon.
Many things that once required time-consuming and error-prone human effort can now be programmed. Before shipping containers, a bag of powder coffee was hauled, dragged, dropped, rolled and stacked by 10 different people in 10 different locations by the time it reached its destination. 1 out of 50 disappeared. 1 out of 20 was damaged. The process was slow, inefficient and cost a fortune - and was entirely different depending on the facility and the type of goods.
Similarly, before Standard Containers, by the time a software component ran in production, it had been individually built, configured, bundled, documented, patched, vendored, templated, tweaked and instrumented by 10 different people on 10 different computers. Builds failed, libraries conflicted, mirrors crashed, post-it notes were lost, logs were misplaced, cluster updates were half-broken. The process was slow, inefficient and cost a fortune - and was entirely different depending on the language and infrastructure provider.
Industrial-grade delivery
~~~~~~~~~~~~~~~~~~~~~~~~~~
There are 17 million shipping containers in existence, packed with every physical good imaginable. Every single one of them can be loaded on the same boats, by the same cranes, in the same facilities, and sent anywhere in the World with incredible efficiency. It is embarrassing to think that a 30 ton shipment of coffee can safely travel half-way across the World in *less time* than it takes a software team to deliver its code from one datacenter to another sitting 10 miles away.
With Standard Containers we can put an end to that embarrassment, by making INDUSTRIAL-GRADE DELIVERY of software a reality.
Standard Container Specification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(TODO)
Image format
~~~~~~~~~~~~
Standard operations
~~~~~~~~~~~~~~~~~~~
- Copy
- Run
- Stop
- Wait
- Commit
- Attach standard streams
- List filesystem changes
- ...
Execution environment
~~~~~~~~~~~~~~~~~~~~~
Root filesystem
^^^^^^^^^^^^^^^
Environment variables
^^^^^^^^^^^^^^^^^^^^^
Process arguments
^^^^^^^^^^^^^^^^^
Networking
^^^^^^^^^^
Process namespacing
^^^^^^^^^^^^^^^^^^^
Resource limits
^^^^^^^^^^^^^^^
Process monitoring
^^^^^^^^^^^^^^^^^^
Logging
^^^^^^^
Signals
^^^^^^^
Pseudo-terminal allocation
^^^^^^^^^^^^^^^^^^^^^^^^^^
Security
^^^^^^^^
+17
View File
@@ -0,0 +1,17 @@
:title: docker documentation
:description: -- todo: change me
:keywords: todo: change me
Concepts
========
Contents:
.. toctree::
:maxdepth: 1
introduction
buildingblocks
+127
View File
@@ -0,0 +1,127 @@
:title: Introduction
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
Introduction
============
Docker - The Linux container runtime
------------------------------------
Docker complements LXC with a high-level API which operates at the process level. It runs unix processes with strong guarantees of isolation and repeatability across servers.
Docker is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
- **Heterogeneous payloads** Any combination of binaries, libraries, configuration files, scripts, virtualenvs, jars, gems, tarballs, you name it. No more juggling between domain-specific tools. Docker can deploy and run them all.
- **Any server** Docker can run on any x64 machine with a modern linux kernel - whether it's a laptop, a bare metal server or a VM. This makes it perfect for multi-cloud deployments.
- **Isolation** docker isolates processes from each other and from the underlying host, using lightweight containers.
- **Repeatability** Because containers are isolated in their own filesystem, they behave the same regardless of where, when, and alongside what they run.
.. image:: http://www.docker.io/_static/lego_docker.jpg
What is a Standard Container?
-----------------------------
Docker defines a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependency, regardless of the underlying machine and the contents of the container.
The spec for Standard Containers is currently work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
A great analogy for this is the shipping container. Just like Standard Containers are a fundamental unit of software delivery, shipping containers (http://bricks.argz.com/ins/7823-1/12) are a fundamental unit of physical delivery.
Standard operations
~~~~~~~~~~~~~~~~~~~
Just like shipping containers, Standard Containers define a set of STANDARD OPERATIONS. Shipping containers can be lifted, stacked, locked, loaded, unloaded and labelled. Similarly, standard containers can be started, stopped, copied, snapshotted, downloaded, uploaded and tagged.
Content-agnostic
~~~~~~~~~~~~~~~~~~~
Just like shipping containers, Standard Containers are CONTENT-AGNOSTIC: all standard operations have the same effect regardless of the contents. A shipping container will be stacked in exactly the same way whether it contains Vietnamese powder coffee or spare Maserati parts. Similarly, Standard Containers are started or uploaded in the same way whether they contain a postgres database, a php application with its dependencies and application server, or Java build artifacts.
Infrastructure-agnostic
~~~~~~~~~~~~~~~~~~~~~~~~~~
Both types of containers are INFRASTRUCTURE-AGNOSTIC: they can be transported to thousands of facilities around the world, and manipulated by a wide variety of equipment. A shipping container can be packed in a factory in Ukraine, transported by truck to the nearest routing center, stacked onto a train, loaded into a German boat by an Australian-built crane, stored in a warehouse at a US facility, etc. Similarly, a standard container can be bundled on my laptop, uploaded to S3, downloaded, run and snapshotted by a build server at Equinix in Virginia, uploaded to 10 staging servers in a home-made Openstack cluster, then sent to 30 production instances across 3 EC2 regions.
Designed for automation
~~~~~~~~~~~~~~~~~~~~~~~~~~
Because they offer the same standard operations regardless of content and infrastructure, Standard Containers, just like their physical counterpart, are extremely well-suited for automation. In fact, you could say automation is their secret weapon.
Many things that once required time-consuming and error-prone human effort can now be programmed. Before shipping containers, a bag of powder coffee was hauled, dragged, dropped, rolled and stacked by 10 different people in 10 different locations by the time it reached its destination. 1 out of 50 disappeared. 1 out of 20 was damaged. The process was slow, inefficient and cost a fortune - and was entirely different depending on the facility and the type of goods.
Similarly, before Standard Containers, by the time a software component ran in production, it had been individually built, configured, bundled, documented, patched, vendored, templated, tweaked and instrumented by 10 different people on 10 different computers. Builds failed, libraries conflicted, mirrors crashed, post-it notes were lost, logs were misplaced, cluster updates were half-broken. The process was slow, inefficient and cost a fortune - and was entirely different depending on the language and infrastructure provider.
Industrial-grade delivery
~~~~~~~~~~~~~~~~~~~~~~~~~~
There are 17 million shipping containers in existence, packed with every physical good imaginable. Every single one of them can be loaded on the same boats, by the same cranes, in the same facilities, and sent anywhere in the World with incredible efficiency. It is embarrassing to think that a 30 ton shipment of coffee can safely travel half-way across the World in *less time* than it takes a software team to deliver its code from one datacenter to another sitting 10 miles away.
With Standard Containers we can put an end to that embarrassment, by making INDUSTRIAL-GRADE DELIVERY of software a reality.
Standard Container Specification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(TODO)
Image format
~~~~~~~~~~~~
Standard operations
~~~~~~~~~~~~~~~~~~~
- Copy
- Run
- Stop
- Wait
- Commit
- Attach standard streams
- List filesystem changes
- ...
Execution environment
~~~~~~~~~~~~~~~~~~~~~
Root filesystem
^^^^^^^^^^^^^^^
Environment variables
^^^^^^^^^^^^^^^^^^^^^
Process arguments
^^^^^^^^^^^^^^^^^
Networking
^^^^^^^^^^
Process namespacing
^^^^^^^^^^^^^^^^^^^
Resource limits
^^^^^^^^^^^^^^^
Process monitoring
^^^^^^^^^^^^^^^^^^
Logging
^^^^^^^
Signals
^^^^^^^
Pseudo-terminal allocation
^^^^^^^^^^^^^^^^^^^^^^^^^^
Security
^^^^^^^^
+247
View File
@@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
#
# Docker documentation build configuration file, created by
# sphinx-quickstart on Tue Mar 19 12:34:07 2013.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
#disable the parmalinks on headers, I find them really annoying
html_add_permalinks = None
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Docker'
copyright = u'2013, Team Docker'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.1'
# The full version, including alpha/beta/rc tags.
release = '0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'docker'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
html_theme_path = ['../theme']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['static_files']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'Dockerdoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'Docker.tex', u'Docker Documentation',
u'Team Docker', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'docker', u'Docker Documentation',
[u'Team Docker'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'Docker', u'Docker Documentation',
u'Team Docker', 'Docker', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
+101
View File
@@ -0,0 +1,101 @@
Contributing to Docker
======================
Want to hack on Docker? Awesome! There are instructions to get you
started on the website: http://docker.io/gettingstarted.html
They are probably not perfect, please let us know if anything feels
wrong or incomplete.
Contribution guidelines
-----------------------
Pull requests are always welcome
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We are always thrilled to receive pull requests, and do our best to
process them as fast as possible. Not sure if that typo is worth a pull
request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be
discouraged! If there's a problem with the implementation, hopefully you
received feedback on what to improve.
We're trying very hard to keep Docker lean and focused. We don't want it
to do everything for everybody. This means that we might decide against
incorporating a new feature. However, there might be a way to implement
that feature *on top of* docker.
Discuss your design on the mailing list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We recommend discussing your plans `on the mailing
list <https://groups.google.com/forum/?fromgroups#!forum/docker-club>`__
before starting to code - especially for more ambitious contributions.
This gives other contributors a chance to point you in the right
direction, give feedback on your design, and maybe point out if someone
else is working on the same thing.
Create issues...
~~~~~~~~~~~~~~~~
Any significant improvement should be documented as `a github
issue <https://github.com/dotcloud/docker/issues>`__ before anybody
starts working on it.
...but check for existing issues first!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please take a moment to check that an issue doesn't already exist
documenting your bug report or improvement proposal. If it does, it
never hurts to add a quick "+1" or "I have this problem too". This will
help prioritize the most common problems and requests.
Conventions
~~~~~~~~~~~
Fork the repo and make changes on your fork in a feature branch:
- If it's a bugfix branch, name it XXX-something where XXX is the number of the
issue
- If it's a feature branch, create an enhancement issue to announce your
intentions, and name it XXX-something where XXX is the number of the issue.
Submit unit tests for your changes. Go has a great test framework built in; use
it! Take a look at existing tests for inspiration. Run the full test suite on
your branch before submitting a pull request.
Make sure you include relevant updates or additions to documentation when
creating or modifying features.
Write clean code. Universally formatted code promotes ease of writing, reading,
and maintenance. Always run ``go fmt`` before committing your changes. Most
editors have plugins that do this automatically, and there's also a git
pre-commit hook:
.. code-block:: bash
curl -o .git/hooks/pre-commit https://raw.github.com/edsrzf/gofmt-git-hook/master/fmt-check && chmod +x .git/hooks/pre-commit
Pull requests descriptions should be as clear as possible and include a
reference to all the issues that they address.
Code review comments may be added to your pull request. Discuss, then make the
suggested modifications and push additional commits to your feature branch. Be
sure to post a comment after pushing. The new commits will show up in the pull
request automatically, but the reviewers will not be notified unless you
comment.
Before the pull request is merged, make sure that you squash your commits into
logical units of work using ``git rebase -i`` and ``git push -f``. After every
commit the test suite should be passing. Include documentation changes in the
same commit so that a revert would remove all traces of the feature or fix.
Commits that fix or close an issue should include a reference like ``Closes #XXX``
or ``Fixes #XXX``, which will automatically close the issue when merged.
Add your name to the AUTHORS file, but make sure the list is sorted and your
name and email address match your git configuration. The AUTHORS file is
regenerated occasionally from the git commit history, so a mismatch may result
in your changes being overwritten.
@@ -0,0 +1,33 @@
:title: Setting up a dev environment
:description: Guides on how to contribute to docker
:keywords: Docker, documentation, developers, contributing, dev environment
Setting up a dev environment
============================
Instructions that have been verified to work on Ubuntu 12.10,
.. code-block:: bash
sudo apt-get -y install lxc wget bsdtar curl golang git
export GOPATH=~/go/
export PATH=$GOPATH/bin:$PATH
mkdir -p $GOPATH/src/github.com/dotcloud
cd $GOPATH/src/github.com/dotcloud
git clone git@github.com:dotcloud/docker.git
cd docker
go get -v github.com/dotcloud/docker/...
go install -v github.com/dotcloud/docker/...
Then run the docker daemon,
.. code-block:: bash
sudo $GOPATH/bin/docker -d
Run the ``go install`` command (above) to recompile docker.
+14
View File
@@ -0,0 +1,14 @@
:title: Contributing to Docker
:description: Guides on how to contribute to docker
:keywords: Docker, documentation, developers, contributing, dev environment
Contributing
============
.. toctree::
:maxdepth: 1
contributing
devenvironment
+2
View File
@@ -0,0 +1,2 @@
www:
type: static
+48
View File
@@ -0,0 +1,48 @@
:title: Hello world example
:description: A simple hello world example with Docker
:keywords: docker, example, hello world
.. _hello_world:
Hello World
===========
This is the most basic example available for using Docker. The example assumes you have Docker installed.
Download the base container
.. code-block:: bash
# Download a base image
docker pull base
The *base* image is a minimal *ubuntu* based container, alternatively you can select *busybox*, a bare
minimal linux system. The images are retrieved from the docker repository.
.. code-block:: bash
#run a simple echo command, that will echo hello world back to the console over standard out.
docker run base /bin/echo hello world
**Explanation:**
- **"docker run"** run a command in a new container
- **"base"** is the image we want to run the command inside of.
- **"/bin/echo"** is the command we want to run in the container
- **"hello world"** is the input for the echo command
**Video:**
See the example in action
.. raw:: html
<div style="margin-top:10px;">
<iframe width="560" height="350" src="http://ascii.io/a/2603/raw" frameborder="0"></iframe>
</div>
Continue to the :ref:`hello_world_daemon` example.
@@ -0,0 +1,81 @@
:title: Hello world daemon example
:description: A simple hello world daemon example with Docker
:keywords: docker, example, hello world, daemon
.. _hello_world_daemon:
Hello World Daemon
==================
The most boring daemon ever written.
This example assumes you have Docker installed and with the base image already imported ``docker pull base``.
We will use the base image to run a simple hello world daemon that will just print hello world to standard
out every second. It will continue to do this until we stop it.
**Steps:**
.. code-block:: bash
CONTAINER_ID=$(docker run -d base /bin/sh -c "while true; do echo hello world; sleep 1; done")
We are going to run a simple hello world daemon in a new container made from the busybox daemon.
- **"docker run -d "** run a command in a new container. We pass "-d" so it runs as a daemon.
- **"base"** is the image we want to run the command inside of.
- **"/bin/sh -c"** is the command we want to run in the container
- **"while true; do echo hello world; sleep 1; done"** is the mini script we want to run, that will just print hello world once a second until we stop it.
- **$CONTAINER_ID** the output of the run command will return a container id, we can use in future commands to see what is going on with this process.
.. code-block:: bash
docker logs $CONTAINER_ID
Check the logs make sure it is working correctly.
- **"docker logs**" This will return the logs for a container
- **$CONTAINER_ID** The Id of the container we want the logs for.
.. code-block:: bash
docker attach $CONTAINER_ID
Attach to the container to see the results in realtime.
- **"docker attach**" This will allow us to attach to a background process to see what is going on.
- **$CONTAINER_ID** The Id of the container we want to attach too.
.. code-block:: bash
docker ps
Check the process list to make sure it is running.
- **"docker ps"** this shows all running process managed by docker
.. code-block:: bash
docker stop $CONTAINER_ID
Stop the container, since we don't need it anymore.
- **"docker stop"** This stops a container
- **$CONTAINER_ID** The Id of the container we want to stop.
.. code-block:: bash
docker ps
Make sure it is really stopped.
**Video:**
See the example in action
.. raw:: html
<div style="margin-top:10px;">
<iframe width="560" height="350" src="http://ascii.io/a/2562/raw" frameborder="0"></iframe>
</div>
Continue to the :ref:`python_web_app` example.
+18
View File
@@ -0,0 +1,18 @@
:title: Docker Examples
:description: Examples on how to use Docker
:keywords: docker, hello world, examples
Examples
============
Contents:
.. toctree::
:maxdepth: 1
hello_world
hello_world_daemon
python_web_app
running_ssh_service
+68
View File
@@ -0,0 +1,68 @@
:title: Python Web app example
:description: Building your own python web app using docker
:keywords: docker, example, python, web app
.. _python_web_app:
Building a python web app
=========================
The goal of this example is to show you how you can author your own docker images using a parent image, making changes to it, and then saving the results as a new image. We will do that by making a simple hello flask web application image.
**Steps:**
.. code-block:: bash
docker pull shykes/pybuilder
We are downloading the "shykes/pybuilder" docker image
.. code-block:: bash
URL=http://github.com/shykes/helloflask/archive/master.tar.gz
We set a URL variable that points to a tarball of a simple helloflask web app
.. code-block:: bash
BUILD_JOB=$(docker run -d -t shykes/pybuilder:latest /usr/local/bin/buildapp $URL)
Inside of the "shykes/pybuilder" image there is a command called buildapp, we are running that command and passing the $URL variable from step 2 to it, and running the whole thing inside of a new container. BUILD_JOB will be set with the new container_id.
.. code-block:: bash
docker attach $BUILD_JOB
[...]
We attach to the new container to see what is going on. Ctrl-C to disconnect
.. code-block:: bash
BUILD_IMG=$(docker commit $BUILD_JOB _/builds/github.com/hykes/helloflask/master)
Save the changed we just made in the container to a new image called "_/builds/github.com/hykes/helloflask/master" and save the image id in the BUILD_IMG variable name.
.. code-block:: bash
WEB_WORKER=$(docker run -d -p 5000 $BUILD_IMG /usr/local/bin/runapp)
Use the new image we just created and create a new container with network port 5000, and return the container id and store in the WEB_WORKER variable.
.. code-block:: bash
docker logs $WEB_WORKER
* Running on http://0.0.0.0:5000/
view the logs for the new container using the WEB_WORKER variable, and if everything worked as planned you should see the line "Running on http://0.0.0.0:5000/" in the log output.
**Video:**
See the example in action
.. raw:: html
<div style="margin-top:10px;">
<iframe width="720" height="350" src="http://ascii.io/a/2573/raw" frameborder="0"></iframe>
</div>
Continue to :ref:`running_ssh_service`.
@@ -0,0 +1,32 @@
:title: Running an SSH service
:description: A screencast of installing and running an sshd service
:keywords: docker, example, package installation, networking
.. _running_ssh_service:
Create an ssh daemon service
============================
**Video:**
I've create a little screencast to show how to create a sshd service and connect to it. It is something like 11
minutes and not entirely smooth, but gives you a good idea.
.. raw:: html
<div style="margin-top:10px;">
<iframe width="800" height="400" src="http://ascii.io/a/2637/raw" frameborder="0"></iframe>
</div>
You can also get this sshd container by using
::
docker pull dhrp/sshd
The password is 'screencast'
+47
View File
@@ -0,0 +1,47 @@
FAQ
===
Most frequently asked questions.
--------------------------------
1. **How much does Docker cost?**
Docker is 100% free, it is open source, so you can use it without paying.
2. **What open source license are you using?**
We are using the Apache License Version 2.0, see it here: https://github.com/dotcloud/docker/blob/master/LICENSE
3. **Does Docker run on Mac OS X or Windows?**
Not at this time, Docker currently only runs on Linux, but you can use VirtualBox to run Docker in a virtual machine on your box, and get the best of both worlds. Check out the MacOSX_ and Windows_ intallation guides.
4. **How do containers compare to virtual machines?**
They are complementary. VMs are best used to allocate chunks of hardware resources. Containers operate at the process level, which makes them very lightweight and perfect as a unit of software delivery.
5. **Can I help by adding some questions and answers?**
Definitely! You can fork `the repo`_ and edit the documentation sources.
42. **Where can I find more answers?**
You can find more answers on:
* `IRC: docker on freenode`_
* `Github`_
* `Ask questions on Stackoverflow`_
* `Join the conversation on Twitter`_
.. _Windows: ../documentation/installation/windows.html
.. _MacOSX: ../documentation/installation/macos.html
.. _the repo: http://www.github.com/dotcloud/docker
.. _IRC\: docker on freenode: irc://chat.freenode.net#docker
.. _Github: http://www.github.com/dotcloud/docker
.. _Ask questions on Stackoverflow: http://stackoverflow.com/search?q=docker
.. _Join the conversation on Twitter: http://twitter.com/getdocker
Looking for something else to read? Checkout the :ref:`hello_world` example.
+204
View File
@@ -0,0 +1,204 @@
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Docker - the Linux container runtime</title>
<meta name="description" content="Docker encapsulates heterogeneous payloads in standard containers">
<meta name="viewport" content="width=device-width">
<!-- twitter bootstrap -->
<link rel="stylesheet" href="../_static/css/bootstrap.min.css">
<link rel="stylesheet" href="../_static/css/bootstrap-responsive.min.css">
<!-- main style file -->
<link rel="stylesheet" href="../_static/css/main.css">
<!-- vendor scripts -->
<script src="../_static/js/vendor/jquery-1.9.1.min.js" type="text/javascript" ></script>
<script src="../_static/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js" type="text/javascript" ></script>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-dotcloud">
<div class="container" style="text-align: center;">
<div style="float: right" class="pull-right">
<ul class="nav">
<li><a href="../">Introduction</a></li>
<li class="active"><a href="./">Getting started</a></li>
<li class=""><a href="http://docs.docker.io/en/latest/concepts/containers/">Documentation</a></li>
</ul>
<div class="social links" style="float: right; margin-top: 14px; margin-left: 12px">
<a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
<a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
</div>
</div>
<div style="margin-left: -12px; float: left;">
<a href="../index.html"><img style="margin-top: 12px; height: 38px" src="../_static/img/docker-letters-logo.gif"></a>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span12 titlebar"><h1 class="pageheader">GETTING STARTED</h1>
</div>
</div>
</div>
<div class="container">
<div class="alert alert-info">
<strong>Docker is still under heavy development.</strong> It should not yet be used in production. Check <a href="http://github.com/dotcloud/docker">the repo</a> for recent progress.
</div>
<div class="row">
<div class="span6">
<section class="contentblock">
<h2>
<a name="installing-on-ubuntu-1204-and-1210" class="anchor" href="#installing-on-ubuntu-1204-and-1210"><span class="mini-icon mini-icon-link"></span>
</a>Installing on Ubuntu</h2>
<ol>
<li>
<p>Install dependencies:</p>
<div class="highlight">
<pre>sudo apt-get install lxc wget bsdtar curl</pre>
<pre>sudo apt-get install linux-image-extra-<span class="sb">`</span>uname -r<span class="sb">`</span></pre></div>
<p>The <code>linux-image-extra</code> package is needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.</p>
</li>
<li>
<p>Install the latest docker binary:</p>
<div class="highlight">
<pre>wget http://get.docker.io/builds/<span class="k">$(</span>uname -s<span class="k">)</span>/<span class="k">$(</span>uname -m<span class="k">)</span>/docker-master.tgz</pre>
<pre>tar -xf docker-master.tgz</pre>
</div>
</li>
<li>
<p>Run your first container!</p>
<div class="highlight"><pre><span class="nb">cd </span>docker-master</pre>
<pre>sudo ./docker run -i -t base /bin/bash</pre>
</div>
<p>Done!</p>
<p>Consider adding docker to your <code>PATH</code> for simplicity.</p>
</li>
Continue with the <a href="http://docs.docker.io/en/latest/examples/hello_world/">Hello world</a> example.
</ol>
</section>
<section class="contentblock">
<h2>Contributing to Docker</h2>
<p>Want to hack on Docker? Awesome! We have some <a href="http://docs.docker.io/en/latest/contributing/contributing/">instructions to get you started</a>. They are probably not perfect, please let us know if anything feels wrong or incomplete.</p>
</section>
</div>
<div class="span6">
<section class="contentblock">
<h2>Quick install on other operating systems</h2>
<p><strong>For other operating systems we recommend and provide a streamlined install with virtualbox,
vagrant and an Ubuntu virtual machine.</strong></p>
<ul>
<li><a href="http://docs.docker.io/en/latest/installation/macos/">Mac OS X and other linuxes</a></li>
<li><a href="http://docs.docker.io/en/latest/installation/windows/">Windows</a></li>
</ul>
</section>
<section class="contentblock">
<h2>More resources</h2>
<ul>
<li><a href="irc://chat.freenode.net#docker">IRC: docker on freenode</a></li>
<li><a href="http://www.github.com/dotcloud/docker">Github</a></li>
<li><a href="http://stackoverflow.com/tags/docker/">Ask questions on Stackoverflow</a></li>
<li><a href="http://twitter.com/getdocker/">Join the conversation on Twitter</a></li>
</ul>
</section>
<section class="contentblock">
<div id="wufoo-z7x3p3">
Fill out my <a href="http://dotclouddocker.wufoo.com/forms/z7x3p3">online form</a>.
</div>
<script type="text/javascript">var z7x3p3;(function(d, t) {
var s = d.createElement(t), options = {
'userName':'dotclouddocker',
'formHash':'z7x3p3',
'autoResize':true,
'height':'577',
'async':true,
'header':'show'};
s.src = ('https:' == d.location.protocol ? 'https://' : 'http://') + 'wufoo.com/scripts/embed/form.js';
s.onload = s.onreadystatechange = function() {
var rs = this.readyState; if (rs) if (rs != 'complete') if (rs != 'loaded') return;
try { z7x3p3 = new WufooForm();z7x3p3.initialize(options);z7x3p3.display(); } catch (e) {}};
var scr = d.getElementsByTagName(t)[0], par = scr.parentNode; par.insertBefore(s, scr);
})(document, 'script');</script>
</section>
</div>
</div>
</div>
<div class="container">
<footer id="footer" class="footer">
<div class="row">
<div class="span12 social">
Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
</div>
</div>
<div class="row">
<div class="emptyspace" style="height: 40px">
</div>
</div>
</footer>
</div>
<!-- bootstrap javascipts -->
<script src="../_static/js/vendor/bootstrap.min.js" type="text/javascript"></script>
<!-- Google analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-6096819-11']);
_gaq.push(['_setDomainName', 'docker.io']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
+289
View File
@@ -0,0 +1,289 @@
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js" xmlns="http://www.w3.org/1999/html"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Docker - the Linux container runtime</title>
<meta name="description" content="Docker encapsulates heterogeneous payloads in standard containers">
<meta name="viewport" content="width=device-width">
<!-- twitter bootstrap -->
<link rel="stylesheet" href="_static/css/bootstrap.min.css">
<link rel="stylesheet" href="_static/css/bootstrap-responsive.min.css">
<!-- main style file -->
<link rel="stylesheet" href="_static/css/main.css">
<!-- vendor scripts -->
<script src="_static/js/vendor/jquery-1.9.1.min.js" type="text/javascript" ></script>
<script src="_static/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js" type="text/javascript" ></script>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-dotcloud">
<div class="container" style="text-align: center;">
<div class="pull-right" >
<ul class="nav">
<li class="active"><a href="./">Introduction</a></li>
<li ><a href="gettingstarted/">Getting started</a></li>
<li class=""><a href="http://docs.docker.io/en/latest/concepts/containers/">Documentation</a></li>
</ul>
<div class="social links" style="float: right; margin-top: 14px; margin-left: 12px">
<a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
<a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="text-center">
<img src="_static/img/docker-letters-logo.gif">
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span12">
<section class="contentblock header">
<div class="span6" style="margin:10px 0px 0px 30px; float: right; ">
<div class="js-video" >
<iframe width="640" height="360" src="http://www.youtube.com/embed/wW9CAH9nSLs?feature=player_detailpage&rel=0&modestbranding=1&start=11" frameborder="0" allowfullscreen></iframe>
</div>
</div>
<div style="text-align: center; padding: 50px 30px 50px 30px;">
<h1>Docker</h1>
<h2>The Linux container runtime</h2>
</div>
<div style="display: block; text-align: center; padding: 10px 30px 50px 30px;">
<p>
Docker complements LXC with a high-level API which operates at the process level.
It runs unix processes with strong guarantees of isolation and repeatability across servers.
</p>
<p>
Docker is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
</p>
</div>
<div style="display: block; text-align: center;">
<a class="btn btn-custom btn-large" href="gettingstarted/">Let's get started</a>
</div>
<br style="clear: both"/>
</section>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span3">
<section class="contentblock">
<h4>Heterogeneous payloads</h4>
<p>Any combination of binaries, libraries, configuration files, scripts, virtualenvs, jars, gems, tarballs, you name it. No more juggling between domain-specific tools. Docker can deploy and run them all.</p>
</section>
</div>
<div class="span3">
<section class="contentblock">
<h4>Any server</h4>
<p>Docker can run on any x64 machine with a modern linux kernel - whether it's a laptop, a bare metal server or a VM. This makes it perfect for multi-cloud deployments.</p>
</section>
</div>
<div class="span3">
<section class="contentblock">
<h4>Isolation</h4>
<p>docker isolates processes from each other and from the underlying host, using lightweight containers.</p>
</section>
</div>
<div class="span3">
<section class="contentblock">
<h4>Repeatability</h4>
<p>Because containers are isolated in their own filesystem, they behave the same regardless of where, when, and alongside what they run.</p>
</section>
</div>
</div>
</div>
<style>
.twitterblock {
min-height: 75px;
}
.twitterblock img {
float: left;
margin-right: 10px;
}
</style>
<div class="container">
<div class="row">
<div class="span6">
<section class="contentblock twitterblock">
<img src="https://twimg0-a.akamaihd.net/profile_images/2491994496/rbevyyq6ykp6bnoby2je_bigger.jpeg">
<em>John Willis @botchagalupe:</em> IMHO docker is to paas what chef was to Iaas 4 years ago
</section>
</div>
<div class="span6">
<section class="contentblock twitterblock">
<img src="https://twimg0-a.akamaihd.net/profile_images/3348427561/9d7f08f1e103a16c8debd169301b9944_bigger.jpeg">
<em>John Feminella @superninjarobot:</em> So, @getdocker is pure excellence. If you've ever wished for arbitrary, PaaS-agnostic, lxc/aufs Linux containers, this is your jam!
</section>
</div>
</div>
<div class="row">
<div class="span6">
<section class="contentblock twitterblock">
<img src="https://si0.twimg.com/profile_images/3408403010/4496ccdd14e9b7285eca04c31a740207_bigger.jpeg">
<em>David Romulan @destructuring:</em> I haven't had this much fun since AWS
</section>
</div>
<div class="span6">
<section class="contentblock twitterblock">
<img src="https://si0.twimg.com/profile_images/780893320/My_Avatar_bigger.jpg">
<em>Ricardo Gladwell @rgladwell:</em> wow @getdocker is either amazing or totally stupid
</section>
</div>
</div>
</div>
<!-- <p>Docker encapsulates heterogeneous payloads in <a href="#container">Standard Containers</a>, and runs them on any server with strong guarantees of isolation and repeatability.</p>
<p>It is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.</p>
-->
<div class="container">
<div class="row">
<div class="span6">
<section class="contentblock">
<!-- <img src="_static/lego_docker.jpg" width="600px" style="float:right; margin-left: 10px"> -->
<h2>Notable features</h2>
<ul>
<li>Filesystem isolation: each process container runs in a completely separate root filesystem.</li>
<li>Resource isolation: system resources like cpu and memory can be allocated differently to each process container, using cgroups.</li>
<li>Network isolation: each process container runs in its own network namespace, with a virtual interface and IP address of its own.</li>
<li>Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremeley fast, memory-cheap and disk-cheap.</li>
<li>Logging: the standard streams (stdout/stderr/stdin) of each process container is collected and logged for real-time or batch retrieval.</li>
<li>Change management: changes to a container's filesystem can be committed into a new image and re-used to create more containers. No templating or manual configuration required.</li>
<li>Interactive shell: docker can allocate a pseudo-tty and attach to the standard input of any container, for example to run a throwaway interactive shell.</li>
</ul>
<h2>Under the hood</h2>
<p>Under the hood, Docker is built on the following components:</p>
<ul>
<li>The <a href="http://blog.dotcloud.com/kernel-secrets-from-the-paas-garage-part-24-c">cgroup</a> and <a href="http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part">namespacing</a> capabilities of the Linux kernel;</li>
<li><a href="http://aufs.sourceforge.net/aufs.html">AUFS</a>, a powerful union filesystem with copy-on-write capabilities;</li>
<li>The <a href="http://golang.org">Go</a> programming language;</li>
<li><a href="http://lxc.sourceforge.net/">lxc</a>, a set of convenience scripts to simplify the creation of linux containers.</li>
</ul>
</section>
</div>
<div class="span6">
<section class="contentblock">
<div id="wufoo-z7x3p3">
Fill out my <a href="http://dotclouddocker.wufoo.com/forms/z7x3p3">online form</a>.
</div>
<script type="text/javascript">var z7x3p3;(function(d, t) {
var s = d.createElement(t), options = {
'userName':'dotclouddocker',
'formHash':'z7x3p3',
'autoResize':true,
'height':'577',
'async':true,
'header':'show'};
s.src = ('https:' == d.location.protocol ? 'https://' : 'http://') + 'wufoo.com/scripts/embed/form.js';
s.onload = s.onreadystatechange = function() {
var rs = this.readyState; if (rs) if (rs != 'complete') if (rs != 'loaded') return;
try { z7x3p3 = new WufooForm();z7x3p3.initialize(options);z7x3p3.display(); } catch (e) {}};
var scr = d.getElementsByTagName(t)[0], par = scr.parentNode; par.insertBefore(s, scr);
})(document, 'script');</script>
</section>
<section class="contentblock">
<h3 id="twitter">Twitter</h3>
<a class="twitter-timeline" href="https://twitter.com/getdocker" data-widget-id="312730839718957056">Tweets by @getdocker</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</section>
</div>
</div>
</div> <!-- end container -->
<div class="container">
<footer id="footer" class="footer">
<div class="row">
<div class="span12">
Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
</div>
</div>
<div class="row">
<div class="emptyspace" style="height: 40px">
</div>
</div>
</footer>
</div>
<!-- bootstrap javascipts -->
<script src="_static/js/vendor/bootstrap.min.js" type="text/javascript"></script>
<!-- Google analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-6096819-11']);
_gaq.push(['_setDomainName', 'docker.io']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
:title: docker documentation
:description: docker documentation
:keywords:
Documentation
=============
This documentation has the following resources:
.. toctree::
:maxdepth: 1
concepts/index
installation/index
examples/index
contributing/index
commandline/index
faq
.. image:: http://www.docker.io/_static/lego_docker.jpg
+87
View File
@@ -0,0 +1,87 @@
Amazon EC2
==========
Please note this is a community contributed installation path. The only 'official' installation is using the :ref:`ubuntu_linux` installation path. This version
may be out of date because it depends on some binaries to be updated and published
Installation
------------
Docker can now be installed on Amazon EC2 with a single vagrant command. Vagrant 1.1 or higher is required.
1. Install vagrant from http://www.vagrantup.com/ (or use your package manager)
2. Install the vagrant aws plugin
::
vagrant plugin install vagrant-aws
3. Get the docker sources, this will give you the latest Vagrantfile and puppet manifests.
::
git clone https://github.com/dotcloud/docker.git
4. Check your AWS environment.
Create a keypair specifically for EC2, give it a name and save it to your disk. *I usually store these in my ~/.ssh/ folder*.
Check that your default security group has an inbound rule to accept SSH (port 22) connections.
5. Inform Vagrant of your settings
Vagrant will read your access credentials from your environment, so we need to set them there first. Make sure
you have everything on amazon aws setup so you can (manually) deploy a new image to EC2.
::
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
export AWS_KEYPAIR_NAME=xxx
export AWS_SSH_PRIVKEY=xxx
The environment variables are:
* ``AWS_ACCESS_KEY_ID`` - The API key used to make requests to AWS
* ``AWS_SECRET_ACCESS_KEY`` - The secret key to make AWS API requests
* ``AWS_KEYPAIR_NAME`` - The name of the keypair used for this EC2 instance
* ``AWS_SSH_PRIVKEY`` - The path to the private key for the named keypair, for example ``~/.ssh/docker.pem``
You can check if they are set correctly by doing something like
::
echo $AWS_ACCESS_KEY_ID
6. Do the magic!
::
vagrant up --provider=aws
If it stalls indefinitely on ``[default] Waiting for SSH to become available...``, Double check your default security
zone on AWS includes rights to SSH (port 22) to your container.
If you have an advanced AWS setup, you might want to have a look at the https://github.com/mitchellh/vagrant-aws
7. Connect to your machine
.. code-block:: bash
vagrant ssh
8. Your first command
Now you are in the VM, run docker
.. code-block:: bash
docker
Continue with the :ref:`hello_world` example.
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Some files were not shown because too many files have changed in this diff Show More