Compare commits

...

498 Commits

Author SHA1 Message Date
Guillaume J. Charmes
822056094a Bumped version to 0.3.3 2013-05-23 12:46:14 -07:00
Daniel Mizyrycki
d17c0b8368 Packaging: Update changelog for release 0.3.3 2013-05-23 12:45:00 -07:00
Solomon Hykes
e0e385ac69 * Build: leave temporary containers untouched after a failure to help debugging 2013-05-23 11:12:54 -06:00
Solomon Hykes
66f3a96983 * Remote API: add versioning 2013-05-23 10:44:36 -06:00
Solomon Hykes
dbb7b60cfc Re-ordered and re-titled kernel requirement details to match the shortlist 2013-05-23 09:49:53 -06:00
Solomon Hykes
e77263010c Simplified and clarified kernel install instructions 2013-05-23 09:47:20 -06:00
Solomon Hykes
2cf29893b3 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-05-23 09:33:34 -06:00
Solomon Hykes
5f30453bfe Merge pull request #688 from pxlpnk/patch-1
Fixing two typos in the run help
2013-05-23 08:21:05 -07:00
Andreas Tiefenthaler
9e0427081e Fixing two typos in the run help 2013-05-23 18:09:59 +03:00
Solomon Hykes
bc3675d471 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-05-23 09:01:40 -06:00
Thatcher
422edd513a Merge pull request #683 from rogaha/doc_meta_info_update
Looks good. Thanks!  Closes #637
2013-05-22 19:09:32 -07:00
rogaha
18cb5c9314 added/modifed tittle, description and keywords
changed the title prefix to sufix + Documentation
2013-05-22 17:52:48 -07:00
Thatcher
4d80924f7c Merge pull request #681 from dhrp/680-fix-readme-image
Fix broken image on README, closes #680
2013-05-22 16:09:21 -07:00
Thatcher Peskens
f008d1107c Fix broken image on README, closes #680 2013-05-22 16:04:33 -07:00
Victor Vieux
faae7220c0 api versionning 2013-05-22 15:29:54 +00:00
Ken Cochrane
1ccc7bdd90 Merge pull request #668 from christophercurrie/patch-1
- Documentation: Fix typos in the python web app example docs.
2013-05-22 07:52:46 -07:00
Victor Vieux
52113cc443 Merge pull request #670 from dotcloud/669-wrong_content_type_create-fix
Fix content type in doc
2013-05-22 06:54:39 -07:00
Victor Vieux
949a649cc2 fix content type in doc 2013-05-22 13:49:12 +00:00
Christopher Currie
5818813183 Apparent typos in the docs. 2013-05-21 21:45:27 -06:00
Guillaume J. Charmes
e6e13d6ade Merge pull request #658 from dotcloud/builder_client_doc
Builder client doc
2013-05-20 18:14:44 -07:00
Guillaume J. Charmes
3f22842542 Remove no longer needed tests 2013-05-20 17:54:54 -07:00
Guillaume J. Charmes
218812eb3c Update docker builder doc 2013-05-20 17:52:39 -07:00
Guillaume J. Charmes
d37dea318e Merge pull request #653 from dotcloud/builder_client
* Builder: Move the Builder to the client
2013-05-20 17:50:17 -07:00
Guillaume J. Charmes
49505c599b Fix an issue trying to pull specific tag 2013-05-20 17:30:33 -07:00
Guillaume J. Charmes
f35f084059 Use pointers for the object methods 2013-05-20 16:35:28 -07:00
Guillaume J. Charmes
0d2fb29537 Merge fix 2013-05-20 16:21:35 -07:00
Guillaume J. Charmes
13e687e579 Allow multiple syntaxes for CMD 2013-05-20 16:00:51 -07:00
Guillaume J. Charmes
b06784b0dd Make docker client an interface 2013-05-20 16:00:16 -07:00
Guillaume J. Charmes
d756ae4cb3 Tag all images after pulling them 2013-05-20 15:19:05 -07:00
Guillaume J. Charmes
c6bc90d02d Isolate run() from commit 2013-05-20 15:02:32 -07:00
Guillaume J. Charmes
b51303cddc Make sure to have a command to execute upon commit 2013-05-20 13:50:50 -07:00
Guillaume J. Charmes
c2a14bb196 Add "Cmd" prefix to builder instructions 2013-05-20 12:09:15 -07:00
Guillaume J. Charmes
bebbbf914b Merge pull request #625 from dotcloud/remove-hijack
Remove hijack from api when not necessary
2013-05-20 11:27:07 -07:00
Guillaume J. Charmes
372d81c325 Merge remove-hijack 2013-05-20 11:07:34 -07:00
Guillaume J. Charmes
ae9d7a5167 Avoid cast each write for flusher 2013-05-20 10:58:35 -07:00
Guillaume J. Charmes
0bb54813d4 Merge pull request #652 from unclejack/fix-compilation-on-linux
fix compilation on linux
2013-05-20 10:55:17 -07:00
unclejack
1b007828c9 fix compilation on linux 2013-05-20 20:43:09 +03:00
Guillaume J. Charmes
98b0fd173b Make the printflfush an interface 2013-05-20 10:22:50 -07:00
Guillaume J. Charmes
2879ef4642 Merge pull request #639 from fsouza/fix-utils-darwin
utils: fix compilation on Darwin
2013-05-20 10:10:30 -07:00
Ken Cochrane
b3101beb47 Merge pull request #645 from fsouza/fix-api-docs
- Documentation: remove trunc_cmd from /containers/ps example no longer needed.
2013-05-20 07:52:22 -07:00
Ken Cochrane
580df1dfc6 Merge pull request #646 from kirang89/master
- Documentation: Fixed typos in README
2013-05-19 16:53:33 -07:00
Guillaume J. Charmes
0f312113d3 Move docker build to client 2013-05-19 10:46:24 -07:00
Kiran Gangadharan
0b785487fe Fixed typos 2013-05-19 21:04:34 +05:30
Francisco Souza
8291f8b85c docs/remote_api: remove trunc_cmd from /containers/ps example
Apparently, this parameter does not exist anymore.
2013-05-19 11:57:45 -03:00
Ken Cochrane
6471fd3825 Merge pull request #644 from philspitler/master
- Documentation: Fixed typo in remote api docs
2013-05-19 06:41:26 -07:00
Phil Spitler
ea7fdecd41 Fixed typo in remote API doc 2013-05-19 09:37:02 -03:00
Francisco Souza
2b55874584 utils: fix compilation on Darwin
Although Docker daemon does not work on Darwin, the API client will have
to work. That said, I'm fixing the compilation of the package on Darwin.
2013-05-19 00:02:42 -03:00
Ken Cochrane
66e9f155c3 Merge pull request #632 from jpetazzo/626-kernel-docs
+ Documentation: Added a section for Kernel requirements to the Docker Docs.
2013-05-18 07:53:45 -07:00
Victor Vieux
0143be42a1 add flush after each write when needed 2013-05-18 14:03:53 +00:00
Thatcher Peskens
537cce16f2 Added a "we are hiring" to the frontpage of the docker website, and fixed two broken links in the docs. 2013-05-17 19:35:46 -07:00
Jérôme Petazzoni
6301373c68 Add some details about pre-3.8 kernels 2013-05-17 18:58:00 -07:00
Jérôme Petazzoni
72360b2cdf Add information about kernel requirements
This page will be helpful for people who:
- want run run a custom kernel
- want to enable memory/swap accounting on Debian/Ubuntu
2013-05-17 18:57:56 -07:00
Ken Cochrane
45c5180516 Merge pull request #631 from garethr/puppet_usage_docs
+ Documentation: Added a section on how to use Docker with puppet.
2013-05-17 13:43:17 -07:00
Guillaume J. Charmes
ffb38ce0ad Merge pull request #633 from dotcloud/fix_insert
Fix insert
2013-05-17 10:16:03 -07:00
Victor Vieux
3703a65405 fixed insert 2013-05-17 17:09:09 +00:00
Gareth Rushgrove
55dd0afb5d add instructions for using docker with puppet 2013-05-17 17:08:37 +01:00
Guillaume J. Charmes
08121c8f6b Update Push to reflect the correct API 2013-05-16 14:33:29 -07:00
Guillaume J. Charmes
6145812444 Update tests to reflect new behavior 2013-05-16 14:33:10 -07:00
Guillaume J. Charmes
f498dd2a2b - Registry: Fix issue preventing to pull specific tag 2013-05-16 12:29:16 -07:00
Guillaume J. Charmes
f29e5dc8a1 Remove hijack from api when not necessary 2013-05-16 12:09:06 -07:00
Guillaume J. Charmes
e86fe7e5af Merge pull request #622 from dotcloud/616-support_wider_range_bool-feature
* API: Support wider range of bool parameters in the api: 1 or 0 -> 1/True/true or 0/False/false
2013-05-16 10:37:23 -07:00
Victor Vieux
0c5443571d 1 or 0 -> 1/True/true or 0/False/false 2013-05-16 13:45:29 +00:00
Thatcher
6677c7964a Merge pull request #620 from dhrp/documentation-review
Pulling the installation documentation update. Includes some timely fixes of broken links.
2013-05-15 20:12:09 -07:00
Thatcher Peskens
8454a86e97 Mostly changes to the html, moved pages, fixed links.
* Moved the introduction page to the en/latest/index.html home of the documentation and pointed all links there
* Fixed a broken link from+to homepage
* Fixed the javascript of the documentation navigation to allow expand and collapse multiple times.
* Fixed the one typo Andy pointed out
2013-05-15 20:00:20 -07:00
Guillaume J. Charmes
fef816163c Merge pull request #618 from titanous/cleanup
Misc. cleanup
2013-05-15 18:05:31 -07:00
Guillaume J. Charmes
f53ec3373d Merge pull request #604 from dotcloud/603-docker-ci
+ Buildbot: testing; issue #603: Create AWS testing buildbot instance for docker CI
2013-05-15 18:05:02 -07:00
Guillaume J. Charmes
0ad34c6cd5 Merge pull request #605 from dotcloud/251-packaging-debian
* Packaging: packaging-debian; issue #251: Update files for prerelease
2013-05-15 18:04:26 -07:00
Guillaume J. Charmes
acf1d5bf0e Merge pull request #592 from dotcloud/refactor_commands_object-feature
* Runtime: refactor commands.go into an object, will be easier for tests
2013-05-15 18:03:30 -07:00
Guillaume J. Charmes
d8bf5af79b Merge pull request #578 from dotcloud/registry-update-tests
+ Registry: Allow INDEX override
2013-05-15 18:00:13 -07:00
Guillaume J. Charmes
7cd7dcda0b Merge pull request #608 from dotcloud/split_subpackage
* Project: Split the project into sub-packages
2013-05-15 17:59:10 -07:00
Guillaume J. Charmes
1b04ccf62c Disable registry unit tests 2013-05-15 17:57:53 -07:00
Guillaume J. Charmes
10f5b6486c Update utils_test.go 2013-05-15 17:46:01 -07:00
Guillaume J. Charmes
822cf67dae Remove test file 2013-05-15 17:44:37 -07:00
Guillaume J. Charmes
f3bab52df4 Move getKernelVersion to utils package 2013-05-15 17:40:47 -07:00
Guillaume J. Charmes
10e19e4b97 Update tests to reflect new AuthConfig 2013-05-15 17:31:11 -07:00
Guillaume J. Charmes
95dd6d31a4 Move authConfig from runtime to registry 2013-05-15 17:17:33 -07:00
Thatcher Peskens
b5c1b17b50 Updated getting started on website. 2013-05-15 16:19:18 -07:00
Thatcher Peskens
2ebbd2d636 Clean up of unnecessary files. 2013-05-15 16:13:20 -07:00
Thatcher Peskens
ce35f5d899 Updated the entire installation section text, checked everything, cleaned up rackspace installation. 2013-05-15 16:11:59 -07:00
Guillaume J. Charmes
bb85ce9aff Allow to change login 2013-05-15 13:39:24 -07:00
Guillaume J. Charmes
dc9d6c1c1f Upload images only when necessary 2013-05-15 13:22:57 -07:00
Jonathan Rudenberg
aa0d40747c Remove broken, redundant struct tag 2013-05-15 16:02:24 -04:00
Jonathan Rudenberg
3a339b2bb3 Update AUTHORS 2013-05-15 15:57:21 -04:00
Jonathan Rudenberg
52ef89f9c2 Fix mistaken call to fmt.Println 2013-05-15 15:52:19 -04:00
Jonathan Rudenberg
04748a7766 Fix logic flaw in builder.mergeConfig 2013-05-15 15:51:04 -04:00
Guillaume J. Charmes
97880a223e Move httpClient within registry object 2013-05-15 19:22:08 +00:00
Guillaume J. Charmes
2f4de3867d Reenable docker push 2013-05-15 19:21:37 +00:00
Guillaume J. Charmes
398a6317a0 Remove stdout from registry 2013-05-15 18:50:52 +00:00
Guillaume J. Charmes
49b61af1f8 Refactor registry Push 2013-05-15 18:30:40 +00:00
Victor Vieux
f27415540f rename client to DockerCli to prepare the split CLI/API 2013-05-15 14:16:46 +00:00
Guillaume J. Charmes
828d1aa507 Begin to implement push with new project structure 2013-05-15 03:27:15 +00:00
Guillaume J. Charmes
e7077320ff Update tests to reflect new project structure 2013-05-15 01:52:09 +00:00
Guillaume J. Charmes
9bb3dc9843 Split registry into subpackage 2013-05-15 01:41:39 +00:00
Guillaume J. Charmes
2e69e1727b Create a subpackage for utils 2013-05-14 22:37:35 +00:00
shin-
539c876727 Make tests less verbose 2013-05-14 22:00:53 +00:00
shin-
e6324ff400 Added small doc page for DOCKER_INDEX_URL variable 2013-05-14 22:00:24 +00:00
shin-
17ad00a35e gofmt pass 2013-05-14 22:00:24 +00:00
shin-
6c7dc1de86 Repository name can not exceed 30 characters 2013-05-14 22:00:24 +00:00
shin-
20a57f15b9 Added login/account creation tests 2013-05-14 22:00:24 +00:00
shin-
54871e3683 Added test for PushRepository 2013-05-14 22:00:24 +00:00
shin-
2b620efffd Allow index server address to vary during execution 2013-05-14 22:00:24 +00:00
shin-
fc1d1d871b Find docker index URL in ENV before using default value. Unit tests for docker pull 2013-05-14 22:00:24 +00:00
Daniel Mizyrycki
341739d916 packaging-debian; issue #251: Update files for prerelease 2013-05-14 03:28:59 -07:00
Daniel Mizyrycki
085ee6fcc4 testing; issue #603: Create AWS testing buildbot instance for docker CI 2013-05-13 23:10:00 -07:00
Guillaume J. Charmes
d586662ce5 Merge pull request #598 from unclejack/build-docker-with-go1.1
* Dockerbuilder - build docker using Go 1.1
2013-05-13 15:20:13 -07:00
unclejack
48fcde8193 build docker using Go 1.1 2013-05-14 01:10:24 +03:00
Guillaume J. Charmes
ccc4fae30a Merge pull request #586 from tbikeev/master
* Vagrant: AWS region and ami name can now be set as ENV variables.
2013-05-13 14:06:48 -07:00
Ken Cochrane
01cecfe2f3 Merge pull request #588 from kencochrane/rackspace-docs
+ Documentation: Added install instructions for RackSpace cloud using Ubuntu 12.04, 12.10, 13.04 and fixed a few minor issues with the ubuntu install docs.
2013-05-13 14:06:15 -07:00
Guillaume J. Charmes
3491957e35 Merge pull request #597 from dotcloud/589-volumes_crash-fix
- Runtime: Make sure that the layer exists prior to store it
2013-05-13 13:09:03 -07:00
Guillaume J. Charmes
be9dd7b85f Make sure that the layer exists prior to store it 2013-05-13 13:08:16 -07:00
Guillaume J. Charmes
edc7c092d9 Merge pull request #551 from jpetazzo/471-cpu-limit
+ Runtime: implement "-c" option to allocate a number of CPU shares to a container
2013-05-13 11:59:09 -07:00
Ken Cochrane
90b4e097cf Merge pull request #581 from dhrp/actually_rebased_docs
* Documentation - rearranged the documentation so that it is easier to manage and use.
2013-05-13 11:47:26 -07:00
Thatcher Peskens
4551fbd700 Merge remote-tracking branch 'dotcloud/master' into clean-reshuffle 2013-05-13 11:44:52 -07:00
Guillaume J. Charmes
37b80325d0 Merge pull request #593 from dotcloud/579-move_display_options_to_client-feature
* Api: Move display options to client
2013-05-13 11:40:46 -07:00
Victor Vieux
4fb89027e6 add host 2013-05-13 20:34:09 +02:00
Thatcher Peskens
6390d25010 Moved docker-remote-api doc to api section 2013-05-13 11:21:28 -07:00
Thatcher Peskens
097531d853 Merge remote-tracking branch 'dotcloud/master' into clean-reshuffle 2013-05-13 11:12:19 -07:00
Guillaume J. Charmes
02d255457a Merge pull request #591 from dotcloud/590_error_message-fix
Fix error message in export
2013-05-13 10:58:05 -07:00
Guillaume J. Charmes
38bc134db3 Merge pull request #587 from zimbatm/fix/readme-build-example
Fixes the README build example to make it work
2013-05-13 10:50:51 -07:00
Guillaume J. Charmes
9023db5c5d Merge pull request #595 from dotcloud/typo_error-fix
Small fix about the error in push
2013-05-13 10:46:38 -07:00
Guillaume J. Charmes
824ad4274a Change t.Skip to t.Log in tests for go1.0.3 compatibility 2013-05-13 10:45:50 -07:00
Victor Vieux
182842e3c3 fix error push 2013-05-13 19:19:27 +02:00
Victor Vieux
e82ff22fae add -notrunc on docker images 2013-05-13 12:26:18 +02:00
Victor Vieux
1990c49a62 removed only_ids and trunc_cmd from the api 2013-05-13 12:18:55 +02:00
Victor Vieux
761731215f refactor commands.go into an object, will be easier for tests 2013-05-13 11:48:27 +02:00
Victor Vieux
8b31d30601 fix error message in export 2013-05-13 11:39:24 +02:00
Ken Cochrane
87038311fc fixed the git clone url, it was the read-write one that required ssh access to the docker account, changed to the read only version 2013-05-12 21:46:35 -04:00
Ken Cochrane
f074e983bd updated the rackspace docs to have more information, and fixed a couple of mistakes 2013-05-12 13:12:44 -04:00
Ken Cochrane
823bc74935 Added install instructions for RackSpace cloud using Ubuntu 12.04, 12.10, 13.04 2013-05-11 19:03:41 -04:00
Jonas Pfenniger
a47d8799b1 Fixes the README build example to make it work 2013-05-11 23:50:06 +01:00
Ken Cochrane
908e4797a6 Merge pull request #584 from boffbowsh/builder-documentation
* Documentation: Updated Docker builder docs to clean up format and add new information and examples
2013-05-11 12:39:44 -07:00
Paul Bowsher
9416574569 Make examples bash-highlighted
Remove DOCKER-VERSION, easier to maintain
Add example of multiple FROM steps
2013-05-11 18:34:26 +01:00
Thomas Bikeev
9cfcfbae52 Made AWS region and ami to be configurable through the ENV variables. 2013-05-11 19:27:42 +02:00
Guillaume J. Charmes
dfbea4ad9f Merge pull request #582 from dotcloud/refactor_api_file
* Api: refactor api.go file to ease the streaming
2013-05-10 15:26:32 -07:00
Guillaume J. Charmes
1cce8572e2 Merge branch 'refactor_api_file' of github.com:dotcloud/docker into refactor_api_file 2013-05-10 15:24:25 -07:00
Guillaume J. Charmes
b99446831f Update api_test.go to reflect new api.go 2013-05-10 15:24:07 -07:00
Victor Vieux
f7beba3acc add writeJson 2013-05-10 15:10:15 -07:00
Victor Vieux
7cc082347f refactor api.go 2013-05-10 15:10:15 -07:00
Paul Bowsher
a98eafaf58 Expand upon Builder documentation and tidy
Standardizes on uppercase for instructions, gives 
example usage.
Wrap at 80 columns
2013-05-10 22:49:42 +01:00
Jérôme Petazzoni
6f3e868a7b Merge branch 'master' of github.com:dotcloud/docker into 471-cpu-limit 2013-05-10 14:44:50 -07:00
Guillaume J. Charmes
d7adeb8a45 Merge pull request #583 from dotcloud/api-tests-1
* Api: Improve remote api unit tests
2013-05-10 14:34:02 -07:00
Guillaume J. Charmes
052a15ace9 - Registry: Fix the checksums file path 2013-05-10 14:25:45 -07:00
Guillaume J. Charmes
ae80c37054 Small fix within TestGetImagesJson 2013-05-10 13:58:21 -07:00
Guillaume J. Charmes
5bec9275c0 Improve remote api unit tests 2013-05-10 12:28:07 -07:00
Thatcher Peskens
8946b75a0b Updated commands index to show better title.
Small syntax fix in couchDB
2013-05-10 12:25:02 -07:00
Victor Vieux
67cdfc0c83 add writeJson 2013-05-10 21:11:59 +02:00
Thatcher Peskens
7557af19d8 Major rearrange of the documentation. 2013-05-10 12:00:12 -07:00
Victor Vieux
d270501de2 Merge pull request #575 from odk-/notrunc-container-id
full container.Id display when notrunc is used
2013-05-10 11:35:20 -07:00
Victor Vieux
dbc899130c refactor api.go 2013-05-10 20:20:49 +02:00
Victor Vieux
17c1704f4a fix run 2013-05-10 17:00:26 +02:00
Victor Vieux
53a8229ce7 fix tests in api_test.go 2013-05-10 16:49:47 +02:00
odk-
82313b1de9 full container.Id display when notrunc is used 2013-05-10 10:18:01 +02:00
Guillaume J. Charmes
1c5e9f8a88 Merge pull request #571 from dotcloud/569-run_after_rmi-fix
fix run after rmi
2013-05-09 23:02:36 -07:00
Guillaume J. Charmes
fae63aa42e Merge pull request #567 from dotcloud/516-xorg-ppa
+ Vagrant: packaging-ubuntu; issue #516: Add xorg kernel to Vagrantfile for stable ubuntu LTS docker distro
2013-05-09 23:01:48 -07:00
Guillaume J. Charmes
26bfeb1d67 Merge pull request #432 from dotcloud/remote-api
+ Remote API: Implement the remote API.
2013-05-09 22:43:47 -07:00
Guillaume J. Charmes
9897e78e32 Update the doc for remote-api 2013-05-09 22:29:12 -07:00
Guillaume J. Charmes
1941c79195 make commands use the correct routes 2013-05-09 22:28:52 -07:00
Guillaume J. Charmes
15ae314cbb Mock Hijack and Implement Unit test for Attach 2013-05-09 21:55:08 -07:00
Guillaume J. Charmes
310fec4819 More unit tests for remote api 2013-05-09 21:54:43 -07:00
Guillaume J. Charmes
28fd289b44 Reduce the Destroy timeout from 10 to 3 seconds 2013-05-09 21:53:59 -07:00
Guillaume J. Charmes
483c942520 Fix typos whithin unit tests 2013-05-09 21:53:28 -07:00
Guillaume J. Charmes
eeaea4e873 Update the routes within commands.go 2013-05-09 20:19:21 -07:00
Guillaume J. Charmes
24816a8b80 Add/improve unit tests 2013-05-09 20:13:52 -07:00
Guillaume J. Charmes
0c6380cc32 Rename "v" in "removeVolume" 2013-05-09 19:19:55 -07:00
Guillaume J. Charmes
2a303dab85 Add unit tests 2013-05-09 19:19:24 -07:00
Guillaume J. Charmes
ede0793d94 Add unit tests for remote api 2013-05-09 17:51:27 -07:00
Guillaume J. Charmes
152ebeea43 Change API route for containers/ and images/ in order to avoid conflict 2013-05-09 17:50:56 -07:00
Guillaume J. Charmes
ff67da9c86 Add the variable maps to the Api functions 2013-05-09 16:28:47 -07:00
Victor Vieux
add73641e6 fixed private caller 2013-05-10 01:23:50 +02:00
Victor Vieux
9af5d9c527 Merge branch 'remote-api' of https://github.com/dotcloud/docker into remote-api 2013-05-10 01:20:33 +02:00
Victor Vieux
3115c5a225 private tests api fixed 2013-05-10 01:20:07 +02:00
Guillaume J. Charmes
7e8b413bcf Implement the some unit tests without listenandserve 2013-05-09 16:20:06 -07:00
Guillaume J. Charmes
b2b59ddb10 Remove ListenAndServe from unit tests 2013-05-09 15:47:06 -07:00
Victor Vieux
c423a790d6 fixed issue with viz 2013-05-09 23:52:12 +02:00
Guillaume J. Charmes
074a566164 Small fix in graph_test.go 2013-05-09 14:48:10 -07:00
Victor Vieux
93dc2c331e removed hijack in export 2013-05-09 23:28:03 +02:00
Victor Vieux
0ecf5e245d removed hijack on viz 2013-05-09 23:10:26 +02:00
Guillaume J. Charmes
e289308dff Bumped version to 0.3.2 2013-05-09 13:51:32 -07:00
Guillaume J. Charmes
8fb8a08ff2 Merge pull request #568 from dotcloud/improve_checksum-2
* Runtime: Store the actual archive on commit
* Registry: Improve the checksum process
- Registry: Fix error 400 on push
2013-05-09 13:25:15 -07:00
Guillaume J. Charmes
30f009150f Fix error code message upon error on push 2013-05-09 13:24:00 -07:00
Victor Vieux
0862183c86 fix status code and error detection 2013-05-09 21:42:29 +02:00
Guillaume J. Charmes
0410397704 Update basics.rst 2013-05-09 13:05:18 -06:00
Victor Vieux
0bcc5d3bee re-add previously deleted doc files 2013-05-09 20:36:08 +02:00
Victor Vieux
b5831eda1e merge master 2013-05-09 20:32:53 +02:00
Victor Vieux
7c7619ecf8 display warning on the server in debug in version don't match 2013-05-09 20:24:49 +02:00
Guillaume J. Charmes
3cbf5670c5 Send the images in correct order 2013-05-09 11:12:37 -07:00
Victor Vieux
0a5d86d7be fix run after rmi 2013-05-09 18:57:47 +02:00
Victor Vieux
4576e11121 fix attach and remove cli doc 2013-05-09 17:54:41 +02:00
Guillaume J. Charmes
55cf05835b Remove the pushImageRec and use iteration instead 2013-05-08 23:29:02 -07:00
Guillaume J. Charmes
c7a7983fcb Improve the checksum process 2013-05-08 22:45:40 -07:00
Guillaume J. Charmes
44b33b44aa Factorize the checksums functions 2013-05-08 22:37:33 -07:00
Guillaume J. Charmes
463658dc8f Refactor PushRepository to fix error 400 and to increase processing speed 2013-05-08 22:06:23 -07:00
Guillaume J. Charmes
80f4b0df75 * Registry: Use the size to have a good progress bar while pushing
* Registry: Use the actual archive if it exists in order to speed up the push
+ Registry: Remove the archive if it exists after the push
2013-05-08 19:36:12 -07:00
Daniel Mizyrycki
73321f27f4 packaging-ubuntu; issue #516: Add xorg kernel to Vagrantfile for stable ubuntu LTS docker distro 2013-05-08 19:36:06 -07:00
Guillaume J. Charmes
aaaf3f0726 Store the actual archive when commit 2013-05-08 19:08:11 -07:00
Victor Vieux
842cb8909e pretty print json in inspect 2013-05-09 03:46:39 +02:00
Victor Vieux
fc29f01528 bump to master 2013-05-09 02:20:16 +02:00
Thatcher
eed64e6777 Merge pull request #566 from dhrp/move-website-to-dir
Moved the static website html pages to their own folder under docs.
2013-05-08 17:13:45 -07:00
Thatcher Peskens
0f4469c2b1 Moved the static website html pages to their own folder under docs.
This should make previewing documentation easier.
Also updated the Makefile to now copy the theme dir into the _build/website/ dir. Make connect and Make push work.
2013-05-08 17:05:46 -07:00
Guillaume J. Charmes
06767fb99d Bumped version to 0.3.1 2013-05-08 16:52:47 -07:00
Guillaume J. Charmes
5098c4fc00 Display the go version inf CmdInfo in non-debug mode 2013-05-08 16:40:48 -07:00
Guillaume J. Charmes
c255976909 Merge pull request #557 from dotcloud/improve_checksum
* Registry: Improve checksum
2013-05-08 16:30:42 -07:00
Guillaume J. Charmes
0e23b4e10e Store the checksums when pulling a repository 2013-05-08 16:27:35 -07:00
Guillaume J. Charmes
d6c24092eb + Runtime: Add go version to debug infos 2013-05-08 15:35:35 -07:00
Victor Vieux
24c785bc06 fix login 2013-05-08 23:57:14 +02:00
Guillaume J. Charmes
6cafed45af Better error output upon push failure 2013-05-08 14:19:38 -07:00
Victor Vieux
1d42cbaa21 removed useless returns 2013-05-08 23:19:24 +02:00
Guillaume J. Charmes
3484781a6f Merge pull request #562 from tianon/go1.1
- Makefile: Swap "go get" for "go get -d", especially to compile on go1.1rc
2013-05-08 14:15:03 -07:00
Tianon Gravi
c4ad6b077d Swap "go get" for "go get -d", especially to compile on go1.1rc; fixes #561 2013-05-08 14:51:50 -06:00
Ken Cochrane
45b5d3027e Merge pull request #559 from dhrp/docs-table-th-fix
- Documentation: CSS fix for docker documentation to make REST API docs look better.
2013-05-08 12:18:33 -07:00
Thatcher Peskens
070b1cd541 Added a line to css to make sure th woul align left. 2013-05-08 12:13:31 -07:00
Guillaume J. Charmes
8ff1765674 Make the checksum async within commit 2013-05-08 12:01:12 -07:00
Guillaume J. Charmes
c4ebf870c8 Use make instead of new 2013-05-08 10:35:41 -07:00
Victor Vieux
bf605fcfc7 fix commit without run parameter 2013-05-08 19:21:52 +02:00
Victor Vieux
954ecac388 fix doc and empty content-type 2013-05-08 18:52:01 +02:00
Victor Vieux
4a1e0d321e change content-type and small fix in run 2013-05-08 18:36:37 +02:00
Victor Vieux
bc3fa506e9 added pagination on ps 2013-05-08 18:28:11 +02:00
Victor Vieux
075e1ebb0e remove useless port endpoint 2013-05-08 18:06:43 +02:00
Victor Vieux
60ddcaa15d changes 2 endpoints to avoid confusion, changed some parameters, fix doc, add api unit tests 2013-05-08 17:35:50 +02:00
Guillaume J. Charmes
cacc7e564a Fix non exiting client issue 2013-05-07 23:32:17 -07:00
Guillaume J. Charmes
2ac4e662f1 Small fix 2013-05-07 18:16:24 -07:00
Guillaume J. Charmes
57cfe72e8c Replace os.File with io.ReadCloser and io.Writer 2013-05-07 18:06:49 -07:00
Guillaume J. Charmes
755604a2bd Fix routes in api.go 2013-05-07 17:35:33 -07:00
Guillaume J. Charmes
891c5202ea Factorize api.go 2013-05-07 17:27:09 -07:00
Guillaume J. Charmes
ab96da8eb2 Use bool instead of string for flags 2013-05-07 16:47:43 -07:00
Guillaume J. Charmes
279db68b46 Use Fprintf instead of Fprintln 2013-05-07 16:36:49 -07:00
Guillaume J. Charmes
b56b2da5c5 Refactor api.go to use a factory with named functions 2013-05-07 16:33:12 -07:00
Victor Vieux
a0880edc63 removed useless buffered pipe in import 2013-05-07 23:56:45 +02:00
Victor Vieux
4d30a32c68 removed RAW mode on server 2013-05-07 23:15:42 +02:00
Victor Vieux
a5b765a769 remove useless wait in run 2013-05-07 22:52:58 +02:00
Victor Vieux
ac0e27699c display id on run -s stdin 2013-05-07 21:36:24 +02:00
Victor Vieux
32cbd72ebe Merge branch 'master' into remote-api 2013-05-07 21:02:32 +02:00
Victor Vieux
4079411375 fix run no parameter 2013-05-07 20:59:04 +02:00
Jérôme Petazzoni
eef8b0d406 propagate CpuShares in mergeConfig 2013-05-07 11:44:38 -07:00
Jérôme Petazzoni
af9f559f2e in the tests, use a non-default value for cpu.shares 2013-05-07 11:44:24 -07:00
Jérôme Petazzoni
e36752e033 if -c is not specified, do not set cpu.shares (instead of using the default value of 1024) 2013-05-07 11:43:45 -07:00
Victor Vieux
59a6316f5e added search 2013-05-07 20:43:31 +02:00
Guillaume J. Charmes
7b1ec9ff30 Merge pull request #539 from justone/fix-byparent
- Images: fix ByParent function
2013-05-07 11:34:59 -07:00
Guillaume J. Charmes
244e6022ec Merge pull request #550 from unclejack/handle-empty-kernel-flavor-without-dash
* Runtime: kernel version - don't show the dash if flavor is empty
2013-05-07 11:24:25 -07:00
Guillaume J. Charmes
f8dd04d567 Merge pull request #552 from dotcloud/548-no_command_panic-fix
- Builder: Check the command existance prior create and add Unit tests for the case
2013-05-07 11:19:34 -07:00
Guillaume J. Charmes
42b1ea4889 Check the command existance prior create and add Unit tests for the case 2013-05-07 11:18:13 -07:00
Jérôme Petazzoni
efd9becb78 implement "-c" option to allocate a number of CPU shares to a container 2013-05-07 11:16:30 -07:00
unclejack
d2eb2455a1 kernel version - don't show the dash if flavor is empty 2013-05-07 20:57:21 +03:00
Guillaume J. Charmes
a2b5196061 Merge pull request #543 from dotcloud/pull-official-tag-fix
- Registry: Fix pull for official images with specific tag
2013-05-07 10:56:37 -07:00
Ken Cochrane
f46ab22b7a Merge pull request #544 from DanielVF/master
- Documentation: Fixed CouchDB example page header mistake
2013-05-07 10:51:35 -07:00
Ken Cochrane
074310063d Merge pull request #535 from dhrp/website_update
* Documentation: updated www.docker.io website.
2013-05-07 10:45:29 -07:00
Guillaume J. Charmes
01575e1f67 Merge pull request #542 from dotcloud/docker-search
+ Registry: Add docker search top level command in order to search a repository
2013-05-07 10:43:19 -07:00
Victor Vieux
97fdfab446 Merge branch 'master' into remote-api 2013-05-07 19:42:36 +02:00
shin-
82513815f1 Added actual doc file 2013-05-07 10:31:55 -07:00
shin-
4df26b9ee7 Added doc page for new search command 2013-05-07 10:29:49 -07:00
Victor Vieux
10c0e99037 update to master 2013-05-07 19:23:50 +02:00
Ken Cochrane
fc2df7e634 Merge pull request #546 from shamrin/patch-3
- Documentation: fixed README formatting
2013-05-07 10:01:16 -07:00
Victor Vieux
0b6c79b303 first draft of the doc, split commit and fix some issues in spi.go 2013-05-07 17:19:41 +02:00
Alexey Shamrin
c718eb282b README: fix Markdown formatting 2013-05-07 17:57:26 +04:00
Daniel Von Fange
0a13ce9bef CouchDB example page was titled redis 2013-05-07 08:33:29 -04:00
Joffrey F
0a197f9b4f Fixes bug when pulling an official image (no user namespace) with a specified tag 2013-05-07 04:54:58 -07:00
shin-
3d25e09c3b missing comma 2013-05-07 03:54:31 -07:00
shin-
d56c5406ac Implemented command 2013-05-07 03:49:08 -07:00
Nate Jones
23c5c13014 fix ByParent 2013-05-06 21:31:59 -07:00
Guillaume J. Charmes
6ac33eb649 Merge pull request #523 from steakknife/522-docker-build
* Builder: use any whitespaces instead of tabs
2013-05-06 19:06:11 -07:00
Guillaume J. Charmes
a02ad8c896 Merge pull request #537 from dotcloud/builder-env
+ Builder: Implement ENV within docker builder
2013-05-06 18:57:15 -07:00
Guillaume J. Charmes
4c7c177e4e Add the ENV instruciton to the docker builder documentation 2013-05-06 18:54:27 -07:00
Guillaume J. Charmes
e45aef0c82 Implement ENV within docker builder 2013-05-06 18:39:56 -07:00
Guillaume J. Charmes
8472a27e80 Merge pull request #497 from justone/dot-graph-images
+ images: output graph of images to dot (graphviz)
2013-05-06 17:48:07 -07:00
Thatcher Peskens
0d929d13d3 Updated index to reflect new (short) 'engine' message (merged with solomon's new text), also moved around the layout a bit and fixed some small text errors. 2013-05-06 17:41:51 -07:00
Guillaume J. Charmes
a0d80ed3e6 Merge pull request #534 from dotcloud/510-update-go
* Packaging: packaging ubuntu; issue #510: Use goland-stable PPA package to build docker
2013-05-06 17:27:02 -07:00
Guillaume J. Charmes
e8853ec3a4 Merge pull request #532 from dotcloud/login_cookie_fix
- Registry: Fix issue when login in with a different user and trying to push
2013-05-06 17:23:57 -07:00
Guillaume J. Charmes
8ea9811089 Merge pull request #512 from dotcloud/builder-doc
+ Documentation: Add the documentation for docker builder
2013-05-06 17:22:35 -07:00
Guillaume J. Charmes
f3f2cba386 Merge pull request #504 from dotcloud/builder-autorun
+ Builder: Implement the autorun capability within docker builder
2013-05-06 17:21:31 -07:00
Guillaume J. Charmes
d581f0808c Merge pull request #511 from dotcloud/builder-cache
+ Builder: Add caching to docker builder
2013-05-06 17:20:22 -07:00
Guillaume J. Charmes
ce4e87196f Merge pull request #472 from dotcloud/builder
+ Builder: Add support for docker builder with native API as top level command
2013-05-06 17:18:56 -07:00
Guillaume J. Charmes
7757be1f45 Rebase fix 2013-05-06 17:12:56 -07:00
Guillaume J. Charmes
49b05eb24a Update docker builder doc 2013-05-06 17:10:42 -07:00
Guillaume J. Charmes
dae2828957 Moving runtime.Create to builder.Create 2013-05-06 17:09:58 -07:00
Guillaume J. Charmes
3439cd9cea Rebase fix 2013-05-06 17:07:56 -07:00
Guillaume J. Charmes
979db00d9a Fix typo in builder 2013-05-06 17:01:59 -07:00
Guillaume J. Charmes
db4417b601 Implement the CMD instruction in order to allow autorun 2013-05-06 17:01:59 -07:00
Guillaume J. Charmes
a64ebe5feb Allow to stack multiple EXPOSE instructions 2013-05-06 17:01:59 -07:00
Guillaume J. Charmes
602786cd60 Moving runtime.Create to builder.Create 2013-05-06 17:00:51 -07:00
Guillaume J. Charmes
35c59f4e05 Rebase fix 2013-05-06 16:58:09 -07:00
Guillaume J. Charmes
756df27e45 Add compatibility with contrib builder 2013-05-06 16:44:37 -07:00
Guillaume J. Charmes
a46fc3a59e Implement caching for docker builder 2013-05-06 16:44:37 -07:00
Guillaume J. Charmes
9959e2cd63 Rebase master (autorun) 2013-05-06 16:44:37 -07:00
Guillaume J. Charmes
f911ccc27b Moving runtime.Create to builder.Create 2013-05-06 16:44:37 -07:00
Guillaume J. Charmes
96069de4e0 Add build command 2013-05-06 16:44:37 -07:00
Guillaume J. Charmes
d92166cc79 Fix merge issue 2013-05-06 16:43:50 -07:00
Guillaume J. Charmes
ebb59c1125 Remove the open from CmdBuild 2013-05-06 16:42:54 -07:00
Guillaume J. Charmes
e2880950c5 Add build command 2013-05-06 16:42:53 -07:00
Guillaume J. Charmes
62a1850c16 Make the autopull compatible with new registry 2013-05-06 16:40:45 -07:00
Guillaume J. Charmes
2bc4ad9402 Rebase fix 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
ae1e655fb1 Implement EXPOSE to builder 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
92e98c66af Implement MAINTAINER to builder 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
6d6a03dfba More consistent docker build test 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
924b61328c Make the FROM instruction pull the image if not existing 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
4ebec08add Trim the splited builder lines 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
15ea5a479a Update the TestBuild with new format 2013-05-06 16:01:01 -07:00
Guillaume J. Charmes
6c168a8986 Rebase master (autorun) 2013-05-06 16:01:00 -07:00
Guillaume J. Charmes
4386edff0b Better varibale names 2013-05-06 16:01:00 -07:00
Guillaume J. Charmes
6bfb652f5b Change dockerbulder format, no more tabs and COPY becomes INSERT to avoid conflict with contrib script 2013-05-06 16:01:00 -07:00
Guillaume J. Charmes
bbb634a980 Add doc for the builder 2013-05-06 16:01:00 -07:00
Guillaume J. Charmes
034c7a7a5e Remove the open from CmdBuild 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
4390a3182f Fix image pipe with Builder COPY 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
e337949cb0 Add builder_test.go 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
dade95844f Make Builder.Build return the builded image 2013-05-06 16:00:30 -07:00
Nate Jones
74b9e851f6 use new image as base of next command 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
ff95f2b0ec Update the unit tests to reflect the new API 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
f7c5e92a2e Move runtime.Commit to builder.Commit 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
6f2125386a Moving runtime.Create to builder.Create 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
0aebb25410 Implement the COPY operator within the builder 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
9db4972a70 Make sure the destination directory exists when using docker insert 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
9751483112 Add insert command in order to insert external files within an image 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
7bccdc0d33 Add a Builder.Commit method 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
97215ca384 make builder.Run public it now runs only given arguments without sh -c 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
b8f66c0d14 Clear the containers/images upon failure 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
27319da0d2 Add build command 2013-05-06 16:00:30 -07:00
Guillaume J. Charmes
f20b5e1323 Fix issue when login in with a different user and trying to push 2013-05-06 15:58:04 -07:00
Daniel Mizyrycki
15b85d9d76 packaging ubuntu; issue #510: Use goland-stable PPA package to build docker 2013-05-06 15:56:50 -07:00
Solomon Hykes
b6af9d3d2e * Website: put Adam's and Mitchell's nice tweets on top :) 2013-05-06 14:26:58 -07:00
Solomon Hykes
f796b9c76e * Website: Bigger twitter profile pictures 2013-05-06 14:26:07 -07:00
Solomon Hykes
627f7fdbfd + Website: new quotes 2013-05-06 14:24:14 -07:00
Solomon Hykes
b38fc9fcdc Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-05-06 14:13:27 -07:00
Solomon Hykes
8646f7f11c + Website: new high-level overview 2013-05-06 14:11:38 -07:00
Guillaume J. Charmes
87cc8b6058 Update documentation, use docker-latest instead of docker-master 2013-05-06 13:26:23 -07:00
Guillaume J. Charmes
0fabd390a9 Update ubuntulinux.rst 2013-05-06 13:11:08 -07:00
Solomon Hykes
2ac7298e4e Bring back lego picture 2013-05-06 12:24:44 -07:00
Solomon Hykes
840bde4393 + Documentation: new introduction and high-level overview 2013-05-06 12:17:51 -07:00
Guillaume J. Charmes
bbad653b1a Update ubuntulinux.rst 2013-05-06 12:00:39 -07:00
Victor Vieux
5a2a5ccdaf removed rcli completly 2013-05-06 16:59:33 +02:00
Victor Vieux
f37399d22b added login and push 2013-05-06 13:34:31 +02:00
Victor Vieux
6f9b574f25 bump to 0.2.2 2013-05-06 11:53:00 +02:00
Victor Vieux
04cd20fa62 split api and server. run return exit code. import, pull and commit uses the smae endpoint. non zero status code on failure 2013-05-06 11:31:22 +02:00
Guillaume J. Charmes
4f202cd07f Bumped version to 0.3.0 2013-05-05 07:46:25 -07:00
Guillaume J. Charmes
da01dd3d56 Merge remote-tracking branch 'origin/registry-update'
+ Registry: Add the new registry support
2013-05-05 07:13:25 -07:00
shin-
09f1cbabb9 Fixed imports 2013-05-06 11:06:44 -07:00
Sam Alba
c9994ed0fb Moved the Debugf message in a registry to a more useful place 2013-05-06 10:57:48 -07:00
Guillaume J. Charmes
b0e076f374 Add output to checksums, code cleaning 2013-05-06 10:57:46 -07:00
Sam Alba
00266df8ac Fixed public pull + Added some verbosity about what is happening 2013-05-06 10:57:45 -07:00
Sam Alba
3febeb93f5 Added help message to invite to login when getting a 401 2013-05-06 10:57:43 -07:00
Sam Alba
bcdf03037b Fixed pulling repositories from library 2013-05-06 10:57:41 -07:00
Sam Alba
a372f982c1 Switching to prod index server 2013-05-06 10:57:38 -07:00
shin-
d985050aeb gofmt pass 2013-05-06 10:57:36 -07:00
shin-
0c5e76958b Use progress reader when uploading/downloading layers 2013-05-06 10:57:06 -07:00
Sam Alba
0f68042053 Handled wrong user credentials by re-init the auth file (it was impossible to login after having wrong crendentials) 2013-05-06 10:57:03 -07:00
shin-
18796d55a6 Fixed some login quirks 2013-05-06 10:57:00 -07:00
shin-
594827d416 Fixed typo in 'username or email already exists' 2013-05-06 10:56:59 -07:00
shin-
5690562fc8 Fix error in PushImage 2013-05-06 10:56:57 -07:00
shin-
be791a223b simplify image.Checksum 2013-05-06 10:56:55 -07:00
shin-
19045b530e simplify graph.Checksums 2013-05-06 10:56:54 -07:00
shin-
b5873806d0 Only send checksums for images not uploaded yet 2013-05-06 10:56:52 -07:00
shin-
f10b0f75e0 Fix checksum computing 2013-05-06 10:56:50 -07:00
shin-
6e2ddf6f60 Checksum system overhaul 2013-05-06 10:56:49 -07:00
shin-
e81a53eea9 Added support for REPO:TAG format in docker pull (overrides -t option) 2013-05-06 10:56:47 -07:00
shin-
1c76f91fc4 Fixed minor bugs in docker pull 2013-05-06 10:56:45 -07:00
shin-
be75608906 Fixed checksum computing. Ensure checksum is computed when image metadata is loaded from disk. Fixed docker push workflow. Moved hash computing to utils 2013-05-06 10:56:10 -07:00
shin-
3c85e9390e Added X-Docker-Token header to initial index requests 2013-05-06 10:54:57 -07:00
shin-
ea3374bcb0 Prepend hash method to the image checksum 2013-05-06 10:54:55 -07:00
shin-
6e936c8fd3 Follow redirections when sending PUT request in PushRepository 2013-05-06 10:54:53 -07:00
shin-
4cd9e4722c Fixed graph.Checksums() 2013-05-06 10:54:52 -07:00
shin-
630d358384 Fixed checksum representation 2013-05-06 10:54:50 -07:00
shin-
84be35dce1 Fixed docker login 2013-05-06 10:54:48 -07:00
shin-
23953e7d67 Style changes in auth.Login 2013-05-06 10:54:46 -07:00
shin-
6644a3c78a Reactivated CmdPush in commands.go 2013-05-06 10:54:45 -07:00
shin-
e179c66400 Reimplemented docker pull for new registry API (command is still deactivated) 2013-05-06 10:54:41 -07:00
shin-
048fd671ef Implemented checksum computation on image creation (necessary for new push primitive) 2013-05-06 10:52:42 -07:00
shin-
7c1a27e2ad gofmt pass 2013-05-06 10:52:10 -07:00
shin-
1cf8a2c26c Changed some of the routes to reflect changes made to the API ; added HTTPClient singleton to the graph object 2013-05-06 10:52:08 -07:00
shin-
e639309a7a Reimplemented feature: downloading all tags on a repository using docker pull. Temporarily commented out CmdPush 2013-05-06 10:51:10 -07:00
shin-
2f082510a7 Implemented new version of PullRepository. Missing support for whole repository pull (= no tag specified) 2013-05-06 10:51:07 -07:00
shin-
2421838b0a Support for the new registry/index API (wip) 2013-05-06 10:51:04 -07:00
Ken Cochrane
58ca46af39 Merge pull request #500 from kencochrane/registry-api-doc
added Docker Index search API doc
2013-05-06 10:44:50 -07:00
Ken Cochrane
09d4b9452d added new sphinx contrib extention for better REST API docs, and changed the index search API so that it uses the new docs, as a test to make sure it works correctly 2013-05-06 13:38:51 -04:00
Ken Cochrane
d78b2d4ade Merge github.com:dotcloud/docker into registry-api-doc 2013-05-06 13:13:17 -04:00
Barry Allard
424cc678eb closes #522 2013-05-04 21:20:41 -07:00
Solomon Hykes
1561232261 First draft of new README. Feedback and contributions welcome! 2013-05-04 19:47:57 -07:00
Solomon Hykes
e392b7ee9b Merge pull request #515 from drnic/vagrant_overrides
Allow reuse of existing vagrant boxes by env variables
2013-05-04 16:47:17 -07:00
Guillaume J. Charmes
c3a5dd76cf Merge pull request #520 from dotcloud/519-no_command_specified-fix
- runtime: Fix the command existance check
2013-05-04 12:03:08 -07:00
Nate Jones
359ecf88de add doc for images -viz 2013-05-03 21:12:43 -07:00
Nate Jones
3dba4022ad add tests for 'images' subcommand 2013-05-03 21:12:43 -07:00
Nate Jones
f4de9d919d add image graph output (dot/graphviz) 2013-05-03 21:12:43 -07:00
Dr Nic Williams
04f41ebdbc Allow reuse of existing vagrant boxes by env variables
Usage:

    BOX_NAME=precise64 vagrant up
2013-05-03 15:35:51 -07:00
Guillaume J. Charmes
c34989f1c4 Merge pull request #501 from losinggeneration/fix_cgroup_memory_check
- runtime: strings.Split may return an empty string on no match
2013-05-03 14:29:43 -07:00
Solomon Hykes
a7c0e9a355 Fix a bug in the Makefile which caused dependency download to fail 2013-05-03 12:58:44 -07:00
Guillaume J. Charmes
19df5a7965 Merge pull request #487 from brunoqc/patch-2
* vagrant: Use only one deb line in /etc/apt
2013-05-03 11:55:16 -07:00
Harley Laue
589d7c68db Check that the line is valid with 6 parts after split 2013-05-03 13:49:10 -05:00
Guillaume J. Charmes
8ef72cbc94 Merge pull request #508 from bdon/master
* docs: doc fix
2013-05-03 11:41:14 -07:00
Victor Vieux
75418ec849 Merge branch 'master' into remote-api 2013-05-03 17:59:11 +02:00
Victor Vieux
c6963da54e makefile from master 2013-05-03 17:51:11 +02:00
Guillaume J. Charmes
b9ec03c21b Fix the command existance check 2013-05-02 20:50:28 -07:00
Brandon Liu
6cbe27b7a5 correct documentation for where images are stored on filesystem. 2013-05-02 20:37:08 -07:00
Solomon Hykes
a82b60b30d dockerbuilder: change order of dependencies 2013-05-02 19:22:41 -07:00
Solomon Hykes
c08d245539 dockerbuilder: let the Makefile upload to s3 with 'make release' 2013-05-02 18:11:54 -07:00
Guillaume J. Charmes
64d7bc442d Fix server crash when running an image without command without autorun 2013-05-02 13:56:45 -07:00
Harley Laue
4bc8ef42d4 strings.Split may return an empty string on no match
* This fixes an index out of range crash if cgroup memory is not
  enabled.
2013-05-02 14:44:41 -05:00
Guillaume J. Charmes
8378498951 Fix issue within mergeConfig preventing hostname and user to be set 2013-05-02 12:32:10 -07:00
Guillaume J. Charmes
1617a18258 Fix typo for command run docs 2013-05-02 12:11:57 -07:00
Solomon Hykes
6c1bb39c09 Fix date typos in changelog 2013-05-03 15:40:32 -07:00
Solomon Hykes
f6b5cd77eb Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-05-03 15:37:37 -07:00
Solomon Hykes
5ffd63070f Bumped version to 0.2.2 2013-05-03 15:19:20 -07:00
Solomon Hykes
701132259d + Documentation: new example: sharing data between 2 couchdb databases 2013-05-03 15:13:12 -07:00
Solomon Hykes
18b8eeb484 + Support for data volumes 2013-05-03 13:03:47 -07:00
Solomon Hykes
b6a5e604ab Add s3 upload to 'make release' 2013-05-02 11:32:55 -07:00
Ken Cochrane
b682a8ea9e added Docker Index search API doc 2013-05-02 14:32:38 -04:00
Solomon Hykes
6e486b638b + Hack: 'make s3release' uploads a clean build to s3 2013-05-02 11:25:49 -07:00
Bruno Bigras
74cd7e822d Use only one deb line in /etc/apt
This prevents the script from filling up /etc/apt/sources.list with more than one deb line which cause a warning when updating.
2013-05-02 13:33:23 -04:00
Victor Vieux
4f0bda2dd5 up to date with master 2013-05-02 18:36:23 +02:00
Guillaume J. Charmes
21b9dcd518 Update docs for Command Run 2013-05-02 09:26:29 -07:00
Guillaume J. Charmes
897cc573f0 Fix the graph.Create prototype 2013-05-02 09:23:29 -07:00
Guillaume J. Charmes
b0459adc27 Comply to the new graph.Create() prototype 2013-05-02 09:14:23 -07:00
Guillaume J. Charmes
3edd14b8c2 Implement the data volume removal 2013-05-02 09:14:23 -07:00
Guillaume J. Charmes
4099a31304 Implement the -volumes-from in order to mount volumes from an other container 2013-05-02 09:14:22 -07:00
Guillaume J. Charmes
6fb495bf6f Move the id of volumes to Container (instead of Container.Config) 2013-05-02 09:14:22 -07:00
Guillaume J. Charmes
faf8daa7c6 Switch back config to map[string]struct{} 2013-05-02 09:14:22 -07:00
Guillaume J. Charmes
8d9aaee60b Handle data volumes mount points 2013-05-02 09:14:22 -07:00
Guillaume J. Charmes
35d704c8a0 Change the volumes type to map[string]string to store both source and destination 2013-05-02 09:14:22 -07:00
Solomon Hykes
1df5f4094b docker run -v PATH: bind a new data volume to a container 2013-05-02 09:14:22 -07:00
unclejack
528da23d6a use Go 1.0.3 to build docker 2013-05-02 15:27:37 +03:00
Guillaume J. Charmes
ff5e238de9 Merge pull request #496 from dotcloud/480-vagrant-fix
- vagrant: Fix main Vagrantfile
2013-05-01 23:38:18 -07:00
Solomon Hykes
c63dce393e Merge pull request #492 from kencochrane/registry-api-doc
+ Registry: added the registry API to the docker docs
2013-05-01 23:00:58 -07:00
Solomon Hykes
d6a63132ef Merge branch 'origin/new-dockerbuilder' 2013-05-02 05:57:50 +00:00
Solomon Hykes
e7271cdaae dockerbuilder: fix permissions 2013-05-02 05:56:51 +00:00
Solomon Hykes
6ca3b151b1 * Hack: improve the way dockerbuilder is built 2013-05-01 22:05:36 -07:00
Victor Vieux
a4bcf7e1ac refactoring run/attach/logs 2013-05-02 05:07:06 +02:00
Daniel Mizyrycki
0d9475346f Fix main Vagrantfile 2013-05-01 18:49:31 -07:00
Solomon Hykes
71199f595d New Dockerfile operation: 'add' 2013-05-01 18:32:38 -07:00
Solomon Hykes
58b95878f1 - Hack: fix dockerbuilder to build feature branches 2013-05-02 01:16:23 +00:00
Guillaume J. Charmes
e431dc26f1 Merge pull request #482 from dotcloud/move_capabilitie_function
* runtime: Move the capabilities detection into a runtime method
2013-05-01 17:43:32 -07:00
Solomon Hykes
09b1cd58c0 Merge branch 'master' of ssh://github.com/dotcloud/docker 2013-05-01 17:18:05 -07:00
Solomon Hykes
d42639e5c5 Bumped version to 0.2.1 2013-05-01 17:17:13 -07:00
Guillaume J. Charmes
d0c2e31fb9 Merge pull request #495 from dotcloud/autorun_docs
* docs: Update commandline Commit doc
2013-05-01 17:14:53 -07:00
Guillaume J. Charmes
509a01bbe4 Merge pull request #493 from dotcloud/374-developer-environment
* hack: development; issue #374: Refactor 'make hack' making Vagrantfile and VM more useful
2013-05-01 16:54:29 -07:00
Solomon Hykes
e7fb7f13d5 new Dockerfile keyword: cmd to set a default runtime command 2013-05-01 16:43:37 -07:00
Daniel Mizyrycki
d172da58ce development; issue #374: Update VM documentation 2013-05-01 15:59:54 -07:00
Solomon Hykes
ad86dde10c * 'docker commit' inherits parent layer's run configuration by default 2013-05-01 15:45:39 -07:00
Guillaume J. Charmes
c20e46587d Update commandline Commit doc 2013-05-01 15:43:02 -07:00
Daniel Mizyrycki
eeb03164cf development; issue #374: Upgrade development VM box to Ubuntu-13.04 with kernel 3.8 2013-05-01 15:26:27 -07:00
Daniel Mizyrycki
bb61678b57 development; issue #374: Refactor 'make hack' making Vagrantfile and VM more useful 2013-05-01 15:26:27 -07:00
Guillaume J. Charmes
a75a1b3859 When no -config is set while committing, use the config of the base image 2013-05-01 15:24:28 -07:00
Solomon Hykes
08812096f5 New Dockerfile operation 'expose' exposes default tcp ports 2013-05-01 14:16:56 -07:00
Solomon Hykes
5c30faf6f7 Set a layer's default runtime options with 'docker commit -run' instead of 'docker commit -config' 2013-05-01 12:45:45 -07:00
Solomon Hykes
f7aaa06606 + Commit default runtime options with a layer 2013-05-01 11:33:21 -07:00
Guillaume J. Charmes
7ff65d40d5 Actually use the mergeConfig function 2013-05-01 11:22:06 -07:00
Ken Cochrane
904c2a0fc3 added the registry API to the docker docs 2013-05-01 12:31:46 -04:00
Solomon Hykes
a3ce90b78b Added dummy script for docker-build example 2013-05-01 00:49:28 -07:00
Solomon Hykes
03b83b3210 Fix example dockerfile 2013-05-01 00:44:36 -07:00
Solomon Hykes
40ccf1d300 new Dockerfile keyword: 'push' 2013-05-01 00:42:11 -07:00
Solomon Hykes
038ca5ee39 docker-build: added support for 'maintainer' keyword 2013-05-01 00:14:52 -07:00
Solomon Hykes
957c500ac9 Merge pull request #485 from brunoqc/patch-1
* Packaging: connect to Ubuntu key server on port 80
2013-04-30 15:46:57 -07:00
Guillaume J. Charmes
62a595da5c Merge pull request #488 from tobert/cgroups-via-proc-mounts
* runtime: Use /proc/mounts instead of mount(8)
2013-04-30 14:39:14 -07:00
Guillaume J. Charmes
d97661aa71 Improve crashTest 2013-04-30 11:16:26 -07:00
Al Tobey
c6119da339 Use /proc/mounts instead of mount(8)
Specifically, Ubuntu Precise's cgroup-lite script uses mount -n
to mount the cgroup filesystems so they don't appear in mtab, so
detection always fails unless the admin updates mtab with /proc/mounts.

/proc/mounts is valid on just about every Linux machine in existence and
as a bonus is much easier to parse.

I also removed the regex in favor of a more accurate parser that should
also support monolitic cgroup mounts (e.g. mount -t cgroup none /cgroup).
2013-04-30 17:37:43 +00:00
Victor Vieux
36b968bb09 [] instead fon null, timetsamps and wip import 2013-04-30 17:04:31 +02:00
Bruno Bigras
5051c20833 Use the 80 port with keyserver.ubuntu.com
Use the 80 port with keyserver.ubuntu.com so it works with corporate firewalls
2013-04-29 15:53:50 -03:00
Victor Vieux
131c6ab3e6 more accurate http errors, attach handle tty correctly now 2013-04-29 17:46:41 +02:00
Victor Vieux
e5104a4cb4 working tty 2013-04-29 15:12:18 +02:00
Victor Vieux
22f5e35579 fix last commit 2013-04-29 11:49:04 +02:00
Victor Vieux
30cb4b351f run now try to pull if unknown image 2013-04-29 11:46:31 +02:00
Guillaume J. Charmes
cdc2657ee9 Improve crashTest 2013-04-28 07:10:58 -07:00
Guillaume J. Charmes
76a1a7cf5b Simplify the crashTest 2013-04-28 06:23:02 -07:00
Guillaume J. Charmes
20c2a4f80f add network endpoint for crashTest 2013-04-28 03:54:22 -07:00
Guillaume J. Charmes
ebe157ebb5 Update the crashTest to have the dockerpath in env 2013-04-28 01:27:56 -07:00
Solomon Hykes
cb431f223f Merge pull request #484 from tianon/mkimage-debian
* Contrib: updated mkimage-debian
2013-04-29 12:12:02 -07:00
Tianon Gravi
ab34115b42 Use default mirror from debootstrap when not explicitly provided, and add better target directory naming 2013-04-28 13:38:26 -06:00
Tianon Gravi
4b3354af3f Improve mkimage-debian script to also tag using the release version number of the final image (6.0.7, 7.0, etc.)
This is as discussed on #447.
2013-04-28 12:31:28 -06:00
Guillaume J. Charmes
9042535f5a Move the capabilities detection into a runtime method 2013-04-26 14:32:55 -07:00
Guillaume J. Charmes
8f81e175af Merge pull request #473 from dotcloud/26-auto_restart_containers-feature
+ runtime: Add -r flag to dockerd in order to restart previously running container....
2013-04-26 14:02:01 -07:00
Guillaume J. Charmes
636c7835d3 Merge pull request #467 from dotcloud/improve_localhost_port_test
* tests: Improve unit test to avoid unnecessary warnigns
2013-04-26 14:01:13 -07:00
Guillaume J. Charmes
6d1dd8b41a Merge pull request #478 from tianon/mkimage-debian
+ contrib: Add contrib/mkimage-debian.sh used to create the tianon/debian images
2013-04-26 13:51:47 -07:00
Guillaume J. Charmes
ae97477284 Remove -command in CmdCommit and make -config use Json 2013-04-26 10:48:33 -07:00
Tianon Gravi
86ad98e72a Add contrib/mkimage-debian.sh used to create the tianon/debian images 2013-04-26 08:54:29 -06:00
Victor Vieux
a48eb4dff8 run now try to pull if unknown image 2013-04-26 15:08:33 +02:00
Solomon Hykes
03d82922aa Merge pull request #474 from brianm/vmware_fusion_provider
Support for VMWare Fusion Provider in Vagrantfile
2013-04-26 01:31:11 -07:00
Guillaume J. Charmes
30d327d37e Add TestCommitAutoRun 2013-04-25 17:03:13 -07:00
Guillaume J. Charmes
724e2d6b0a Update unit test in order to comply with new api 2013-04-25 17:02:38 -07:00
Guillaume J. Charmes
51d6228261 Implement -config and -command in CmdCommit in order to allow autorun 2013-04-25 16:48:31 -07:00
Brian McCallister
4db680fda4 don't fight the box kernel version, not worth it 2013-04-25 06:29:13 -06:00
Brian McCallister
9c7293508d get aufs dependencies into vmware image 2013-04-25 06:09:04 -06:00
Brian McCallister
9d8743a7ae vmware fusion provider config 2013-04-25 05:59:31 -06:00
Guillaume J. Charmes
50144aeb42 Add -r flag to dockerd in order to restart previously running container. Fixes #26 2013-04-24 19:01:23 -07:00
Guillaume J. Charmes
ee298d1420 Specify a different bridge for tests than for regular runtime 2013-04-24 17:43:41 -07:00
Solomon Hykes
03855b0027 Merge pull request #466 from dotcloud/441-vagrant-improve
* Packaging: simplify Vagrantfile
2013-04-24 17:25:20 -07:00
Daniel Mizyrycki
2726e3649a vagrant; issue #441: Improve main config including aws ubuntu lts dependency 2013-04-24 11:30:15 -07:00
Victor Vieux
75c0dc9526 fixed inspect 2013-04-24 18:50:26 +02:00
Victor Vieux
c7bbe7ca79 added export 2013-04-24 16:32:51 +02:00
Victor Vieux
79512b2a80 added commit 2013-04-24 16:06:30 +02:00
Victor Vieux
1e357c6969 changed not found errors to 404, added inspect, wait and diff 2013-04-24 14:01:40 +02:00
Guillaume J. Charmes
6ebb249131 Remove unecessary memeory limit within tests 2013-04-23 11:25:16 -07:00
Guillaume J. Charmes
c45beabcd5 Improve TestMultipleAttachRestart to avoid unnecessary warning 2013-04-23 11:22:30 -07:00
Guillaume J. Charmes
a22c78523f Wait for the container to finish in TestAttachDisconnect before destroying it 2013-04-23 11:09:48 -07:00
Guillaume J. Charmes
5a02c9ba0a Make sure the container is well started prior to perform the test 2013-04-23 11:08:31 -07:00
Victor Vieux
cf19be44a8 added run (wip), fixed ps and images, added port and tag 2013-04-23 18:20:53 +02:00
Victor Vieux
6ce475dbdf added push hijack (wip) 2013-04-22 23:37:22 +02:00
Victor Vieux
1aa7f1392d restify api 2013-04-22 18:17:47 +02:00
Victor Vieux
b295239de2 added: info, history, logs, ps, start, stop, restart, rm, rmi 2013-04-19 15:24:37 +02:00
Victor Vieux
79e9105806 added kill and images(wip) 2013-04-18 18:56:22 +02:00
Victor Vieux
c0d5d5969b skeleton remote API, only version working (wip) 2013-04-18 03:13:43 +02:00
Victor Vieux
92cd75607b Merge branch 'remote-api' of https://github.com/dotcloud/docker into remote-api 2013-04-17 12:21:56 +02:00
Solomon Hykes
a11b31399b Skeleton of http API 2013-04-16 19:53:08 +02:00
Solomon Hykes
38e2d00199 Skeleton of http API 2013-04-10 19:48:21 -07:00
171 changed files with 11604 additions and 3420 deletions

View File

@@ -2,7 +2,7 @@
<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 J. Charmes <guillaume.charmes@dotcloud.com> <charmes.guillaume@gmail.com>
<guillaume.charmes@dotcloud.com> <guillaume@dotcloud.com>
<kencochrane@gmail.com> <KenCochrane@gmail.com>
<sridharr@activestate.com> <github@srid.name>
@@ -16,4 +16,6 @@ Tim Terhorst <mynamewastaken+git@gmail.com>
Andy Smith <github@anarkystic.com>
<kalessin@kalessin.fr> <louis@dotcloud.com>
<victor.vieux@dotcloud.com> <victor@dotcloud.com>
<victor.vieux@dotcloud.com> <dev@vvieux.com>
<dominik@honnef.co> <dominikh@fork-bomb.org>
Thatcher Peskens <thatcher@dotcloud.com>

15
AUTHORS
View File

@@ -1,24 +1,34 @@
Al Tobey <al@ooyala.com>
Alexey Shamrin <shamrin@gmail.com>
Andrea Luzzardi <aluzzardi@gmail.com>
Andy Rothfusz <github@metaliveblog.com>
Andy Smith <github@anarkystic.com>
Antony Messerli <amesserl@rackspace.com>
Barry Allard <barry.allard@gmail.com>
Brandon Liu <bdon@bdon.org>
Brian McCallister <brianm@skife.org>
Bruno Bigras <bigras.bruno@gmail.com>
Caleb Spare <cespare@gmail.com>
Charles Hooper <charles.hooper@dotcloud.com>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com>
Daniel Robinson <gottagetmac@gmail.com>
Daniel Von Fange <daniel@leancoder.com>
Dominik Honnef <dominik@honnef.co>
Don Spaulding <donspauldingii@gmail.com>
Dr Nic Williams <drnicwilliams@gmail.com>
Evan Wies <evan@neomantra.net>
ezbercih <cem.ezberci@gmail.com>
Flavio Castelli <fcastelli@suse.com>
Francisco Souza <f@souza.cc>
Frederick F. Kautz IV <fkautz@alumni.cmu.edu>
Guillaume J. Charmes <guillaume.charmes@dotcloud.com>
Harley Laue <losinggeneration@gmail.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>
Jonas Pfenniger <jonas@pfenniger.name>
Jonathan Rudenberg <jonathan@titanous.com>
Julien Barbier <write0@gmail.com>
Jérôme Petazzoni <jerome.petazzoni@dotcloud.com>
@@ -27,8 +37,11 @@ Kevin J. Lynagh <kevin@keminglabs.com>
Louis Opter <kalessin@kalessin.fr>
Maxim Treskin <zerthurd@gmail.com>
Mikhail Sobolev <mss@mawhrin.net>
Nate Jones <nate@endot.org>
Nelson Chen <crazysim@gmail.com>
Niall O'Higgins <niallo@unworkable.org>
odk- <github@odkurzacz.org>
Paul Bowsher <pbowsher@globalpersonals.co.uk>
Paul Hammond <paul@paulhammond.org>
Piotr Bogdan <ppbogdan@gmail.com>
Robert Obryk <robryk@gmail.com>
@@ -38,6 +51,8 @@ Silas Sewell <silas@sewell.org>
Solomon Hykes <solomon@dotcloud.com>
Sridhar Ratnakumar <sridharr@activestate.com>
Thatcher Peskens <thatcher@dotcloud.com>
Thomas Bikeev <thomas.bikeev@mac.com>
Tianon Gravi <admwiggin@gmail.com>
Tim Terhorst <mynamewastaken+git@gmail.com>
Troy Howard <thoward37@gmail.com>
unclejack <unclejacksons@gmail.com>

View File

@@ -1,6 +1,68 @@
# Changelog
## 0.2.0 (2012-04-23)
## 0.3.3 (2013-05-23)
- Registry: Fix push regression
- Various bugfixes
## 0.3.2 (2013-05-09)
* Runtime: Store the actual archive on commit
* Registry: Improve the checksum process
* Registry: Use the size to have a good progress bar while pushing
* Registry: Use the actual archive if it exists in order to speed up the push
- Registry: Fix error 400 on push
## 0.3.1 (2013-05-08)
+ Builder: Implement the autorun capability within docker builder
+ Builder: Add caching to docker builder
+ Builder: Add support for docker builder with native API as top level command
+ Runtime: Add go version to debug infos
+ Builder: Implement ENV within docker builder
+ Registry: Add docker search top level command in order to search a repository
+ Images: output graph of images to dot (graphviz)
+ Documentation: new introduction and high-level overview
+ Documentation: Add the documentation for docker builder
+ Website: new high-level overview
- Makefile: Swap "go get" for "go get -d", especially to compile on go1.1rc
- Images: fix ByParent function
- Builder: Check the command existance prior create and add Unit tests for the case
- Registry: Fix pull for official images with specific tag
- Registry: Fix issue when login in with a different user and trying to push
- Documentation: CSS fix for docker documentation to make REST API docs look better.
- Documentation: Fixed CouchDB example page header mistake
- Documentation: fixed README formatting
* Registry: Improve checksum - async calculation
* Runtime: kernel version - don't show the dash if flavor is empty
* Documentation: updated www.docker.io website.
* Builder: use any whitespaces instead of tabs
* Packaging: packaging ubuntu; issue #510: Use goland-stable PPA package to build docker
## 0.3.0 (2013-05-06)
+ Registry: Implement the new registry
+ Documentation: new example: sharing data between 2 couchdb databases
- Runtime: Fix the command existance check
- Runtime: strings.Split may return an empty string on no match
- Runtime: Fix an index out of range crash if cgroup memory is not
* Documentation: Various improvments
* Vagrant: Use only one deb line in /etc/apt
## 0.2.2 (2013-05-03)
+ Support for data volumes ('docker run -v=PATH')
+ Share data volumes between containers ('docker run -volumes-from')
+ Improved documentation
* Upgrade to Go 1.0.3
* Various upgrades to the dev environment for contributors
## 0.2.1 (2013-05-01)
+ 'docker commit -run' bundles a layer with default runtime options: command, ports etc.
* Improve install process on Vagrant
+ New Dockerfile operation: "maintainer"
+ New Dockerfile operation: "expose"
+ New Dockerfile operation: "cmd"
+ Contrib script to build a Debian base layer
+ 'docker -d -r': restart crashed containers at daemon startup
* Runtime: improve test coverage
## 0.2.0 (2013-04-23)
- Runtime: ghost containers can be killed and waited for
* Documentation: update install intructions
- Packaging: fix Vagrantfile
@@ -8,13 +70,12 @@
+ Add a changelog
- Various bugfixes
## 0.1.8 (2013-04-22)
- Dynamically detect cgroup capabilities
- Issue stability warning on kernels <3.8
- 'docker push' buffers on disk instead of memory
- Fix 'docker diff' for removed files
- Fix 'docker stop' for ghost containers
- Fix 'docker stop' for ghost containers
- Fix handling of pidfile
- Various bugfixes and stability improvements
@@ -35,7 +96,7 @@
- Improve diagnosis of missing system capabilities
- Allow disabling memory limits at compile time
- Add debian packaging
- Documentation: installing on Arch Linux
- Documentation: installing on Arch Linux
- Documentation: running Redis on docker
- Fixed lxc 0.9 compatibility
- Automatically load aufs module

View File

@@ -38,14 +38,15 @@ $(DOCKER_BIN): $(DOCKER_DIR)
$(DOCKER_DIR):
@mkdir -p $(dir $@)
@rm -f $@
@ln -sf $(CURDIR)/ $@
@(cd $(DOCKER_MAIN); go get $(GO_OPTIONS))
@if [ -h $@ ]; then rm -f $@; fi; ln -sf $(CURDIR)/ $@
@(cd $(DOCKER_MAIN); go get -d $(GO_OPTIONS))
whichrelease:
echo $(RELEASE_VERSION)
release: $(BINRELEASE)
s3cmd -P put $(BINRELEASE) s3://get.docker.io/builds/`uname -s`/`uname -m`/docker-$(RELEASE_VERSION).tgz
srcrelease: $(SRCRELEASE)
deps: $(DOCKER_DIR)
@@ -75,4 +76,7 @@ fmt:
@gofmt -s -l -w .
hack:
cd $(CURDIR)/buildbot && vagrant up
cd $(CURDIR)/hack && vagrant up
ssh-dev:
cd $(CURDIR)/hack && vagrant ssh

View File

@@ -1,37 +1,94 @@
Docker: the Linux container runtime
===================================
Docker: the Linux container engine
==================================
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 an open-source engine which automates the deployment of applications as highly portable, self-sufficient containers.
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.
Docker containers are both *hardware-agnostic* and *platform-agnostic*. This means that they can run anywhere, from your
laptop to the largest EC2 compute instance and everything in between - and they don't require that you use a particular
language, framework or packaging system. That makes them great building blocks for deploying and scaling web apps, databases
and backend services without depending on a particular stack or provider.
![Docker L](docs/sources/static_files/lego_docker.jpg "Docker")
Docker is an open-source implementation of the deployment engine which powers [dotCloud](http://dotcloud.com), a popular Platform-as-a-Service.
It benefits directly from the experience accumulated over several years of large-scale operation and support of hundreds of thousands
of applications and databases.
* *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.
![Docker L](docs/sources/concepts/images/lego_docker.jpg "Docker")
* *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.
## Better than VMs
* *Isolation*: docker isolates processes from each other and from the underlying host, using lightweight containers.
A common method for distributing applications and sandbox their execution is to use virtual machines, or VMs. Typical VM formats
are VMWare's vmdk, Oracle Virtualbox's vdi, and Amazon EC2's ami. In theory these formats should allow every developer to
automatically package their application into a "machine" for easy distribution and deployment. In practice, that almost never
happens, for a few reasons:
* *Repeatability*: because containers are isolated in their own filesystem, they behave the same regardless of where, when, and alongside what they run.
* *Size*: VMs are very large which makes them impractical to store and transfer.
* *Performance*: running VMs consumes significant CPU and memory, which makes them impractical in many scenarios, for example local development of multi-tier applications, and
large-scale deployment of cpu and memory-intensive applications on large numbers of machines.
* *Portability*: competing VM environments don't play well with each other. Although conversion tools do exist, they are limited and add even more overhead.
* *Hardware-centric*: VMs were designed with machine operators in mind, not software developers. As a result, they offer very limited tooling for what developers need most:
building, testing and running their software. For example, VMs offer no facilities for application versioning, monitoring, configuration, logging or service discovery.
By contrast, Docker relies on a different sandboxing method known as *containerization*. Unlike traditional virtualization,
containerization takes place at the kernel level. Most modern operating system kernels now support the primitives necessary
for containerization, including Linux with [openvz](http://openvz.org), [vserver](http://linux-vserver.org) and more recently [lxc](http://lxc.sourceforge.net),
Solaris with [zones](http://docs.oracle.com/cd/E26502_01/html/E29024/preface-1.html#scrolltoc) and FreeBSD with [Jails](http://www.freebsd.org/doc/handbook/jails.html).
Docker builds on top of these low-level primitives to offer developers a portable format and runtime environment that solves
all 4 problems. Docker containers are small (and their transfer can be optimized with layers), they have basically zero memory and cpu overhead,
they are completely portable and are designed from the ground up with an application-centric design.
The best part: because docker operates at the OS level, it can still be run inside a VM!
## Plays well with others
Docker does not require that you buy into a particular programming language, framework, packaging system or configuration language.
Is your application a unix process? Does it use files, tcp connections, environment variables, standard unix streams and command-line
arguments as inputs and outputs? Then docker can run it.
Can your application's build be expressed as a sequence of such commands? Then docker can build it.
Notable features
-----------------
## Escape dependency hell
* Filesystem isolation: each process container runs in a completely separate root filesystem.
A common problem for developers is the difficulty of managing all their application's dependencies in a simple and automated way.
* Resource isolation: system resources like cpu and memory can be allocated differently to each process container, using cgroups.
This is usually difficult for several reasons:
* Network isolation: each process container runs in its own network namespace, with a virtual interface and IP address of its own.
* *Cross-platform dependencies*. Modern applications often depend on a combination of system libraries and binaries, language-specific packages, framework-specific modules,
internal components developed for another project, etc. These dependencies live in different "worlds" and require different tools - these tools typically don't work
well with each other, requiring awkward custom integrations.
* Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremely fast, memory-cheap and disk-cheap.
* Conflicting dependencies. Different applications may depend on different versions of the same dependency. Packaging tools handle these situations with various degrees of ease -
but they all handle them in different and incompatible ways, which again forces the developer to do extra work.
* Custom dependencies. A developer may need to prepare a custom version of his application's dependency. Some packaging systems can handle custom versions of a dependency,
others can't - and all of them handle it differently.
* 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.
Docker solves dependency hell by giving the developer a simple way to express *all* his application's dependencies in one place,
and streamline the process of assembling them. If this makes you think of [XKCD 927](http://xkcd.com/927/), don't worry. Docker doesn't
*replace* your favorite packaging systems. It simply orchestrates their use in a simple and repeatable way. How does it do that? With layers.
Docker defines a build as running a sequence of unix commands, one after the other, in the same container. Build commands modify the contents of the container
(usually by installing new files on the filesystem), the next command modifies it some more, etc. Since each build command inherits the result of the previous
commands, the *order* in which the commands are executed expresses *dependencies*.
Here's a typical docker build process:
```bash
from ubuntu:12.10
run apt-get update
run DEBIAN_FRONTEND=noninteractive apt-get install -q -y python
run DEBIAN_FRONTEND=noninteractive apt-get install -q -y python-pip
run pip install django
run DEBIAN_FRONTEND=noninteractive apt-get install -q -y curl
run curl -L https://github.com/shykes/helloflask/archive/master.tar.gz | tar -xzv
run cd helloflask-master && pip install -r requirements.txt
```
Note that Docker doesn't care *how* dependencies are built - as long as they can be built by running a unix command in a container.
* 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.
Install instructions
==================
@@ -236,7 +293,7 @@ a format that is self-describing and portable, so that any compliant runtime can
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.
A great analogy for this is the shipping container. Just like how 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.
### 1. STANDARD OPERATIONS
@@ -264,7 +321,7 @@ Similarly, before Standard Containers, by the time a software component ran in p
### 5. 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.
There are 17 million shipping containers in existence, packed with every physical good imaginable. Every single one of them can be loaded onto 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.

96
Vagrantfile vendored
View File

@@ -1,71 +1,62 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
def v10(config)
config.vm.box = 'precise64'
config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
BOX_NAME = ENV['BOX_NAME'] || "ubuntu"
BOX_URI = ENV['BOX_URI'] || "http://files.vagrantup.com/precise64.box"
AWS_REGION = ENV['AWS_REGION'] || "us-east-1"
AWS_AMI = ENV['AWS_AMI'] || "ami-d0f89fb9"
# Install ubuntu packaging dependencies and create ubuntu packages
config.vm.provision :shell, :inline => "echo 'deb http://ppa.launchpad.net/dotcloud/lxc-docker/ubuntu precise main' >>/etc/apt/sources.list"
config.vm.provision :shell, :inline => 'export DEBIAN_FRONTEND=noninteractive; apt-get -qq update; apt-get install -qq -y --force-yes lxc-docker'
Vagrant::Config.run do |config|
# Setup virtual machine box. This VM configuration code is always executed.
config.vm.box = BOX_NAME
config.vm.box_url = BOX_URI
# Provision docker and new kernel if deployment was not done
if Dir.glob("#{File.dirname(__FILE__)}/.vagrant/machines/default/*/id").empty?
# Add lxc-docker package
pkg_cmd = "apt-get update -qq; apt-get install -q -y python-software-properties; " \
"add-apt-repository -y ppa:dotcloud/lxc-docker; apt-get update -qq; " \
"apt-get install -q -y lxc-docker; "
# Add X.org Ubuntu backported 3.8 kernel
pkg_cmd << "add-apt-repository -y ppa:ubuntu-x-swat/r-lts-backport; " \
"apt-get update -qq; apt-get install -q -y linux-image-3.8.0-19-generic; "
# Add guest additions if local vbox VM
is_vbox = true
ARGV.each do |arg| is_vbox &&= !arg.downcase.start_with?("--provider") end
if is_vbox
pkg_cmd << "apt-get install -q -y linux-headers-3.8.0-19-generic dkms; " \
"echo 'Downloading VBox Guest Additions...'; " \
"wget -q http://dlc.sun.com.edgesuite.net/virtualbox/4.2.12/VBoxGuestAdditions_4.2.12.iso; "
# Prepare the VM to add guest additions after reboot
pkg_cmd << "echo -e 'mount -o loop,ro /home/vagrant/VBoxGuestAdditions_4.2.12.iso /mnt\n" \
"echo yes | /mnt/VBoxLinuxAdditions.run\numount /mnt\n" \
"rm /root/guest_additions.sh; ' > /root/guest_additions.sh; " \
"chmod 700 /root/guest_additions.sh; " \
"sed -i -E 's#^exit 0#[ -x /root/guest_additions.sh ] \\&\\& /root/guest_additions.sh#' /etc/rc.local; " \
"echo 'Installation of VBox Guest Additions is proceeding in the background.'; " \
"echo '\"vagrant reload\" can be used in about 2 minutes to activate the new guest additions.'; "
end
# Activate new kernel
pkg_cmd << "shutdown -r +1; "
config.vm.provision :shell, :inline => pkg_cmd
end
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
# Providers were added on Vagrant >= 1.1.0
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-d0f89fb9"
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 = 'precise64'
config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
end
end
Vagrant::VERSION >= "1.2.0" and Vagrant.configure("2") do |config|
config.vm.provider :aws do |aws, override|
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"]
override.ssh.private_key_path = ENV["AWS_SSH_PRIVKEY"]
override.ssh.username = "ubuntu"
aws.region = "us-east-1"
aws.ami = "ami-d0f89fb9"
aws.region = AWS_REGION
aws.ami = AWS_AMI
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"]
@@ -75,8 +66,7 @@ Vagrant::VERSION >= "1.2.0" and Vagrant.configure("2") do |config|
end
config.vm.provider :virtualbox do |vb|
config.vm.box = 'precise64'
config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
config.vm.box = BOX_NAME
config.vm.box_url = BOX_URI
end
end

667
api.go Normal file
View File

@@ -0,0 +1,667 @@
package docker
import (
"encoding/json"
"fmt"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/utils"
"github.com/gorilla/mux"
"io"
"log"
"net/http"
"strconv"
"strings"
)
const API_VERSION = 1.0
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
return nil, nil, err
}
// Flush the options to make sure the client sets the raw mode
conn.Write([]byte{})
return conn, conn, nil
}
//If we don't do this, POST method without Content-type (even with empty body) will fail
func parseForm(r *http.Request) error {
if err := r.ParseForm(); err != nil && !strings.HasPrefix(err.Error(), "mime:") {
return err
}
return nil
}
func httpError(w http.ResponseWriter, err error) {
if strings.HasPrefix(err.Error(), "No such") {
http.Error(w, err.Error(), http.StatusNotFound)
} else if strings.HasPrefix(err.Error(), "Bad parameter") {
http.Error(w, err.Error(), http.StatusBadRequest)
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func writeJson(w http.ResponseWriter, b []byte) {
w.Header().Set("Content-Type", "application/json")
w.Write(b)
}
func getBoolParam(value string) (bool, error) {
if value == "1" || strings.ToLower(value) == "true" {
return true, nil
}
if value == "" || value == "0" || strings.ToLower(value) == "false" {
return false, nil
}
return false, fmt.Errorf("Bad parameter")
}
func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
b, err := json.Marshal(srv.registry.GetAuthConfig())
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
config := &auth.AuthConfig{}
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
return err
}
if config.Username == srv.registry.GetAuthConfig().Username {
config.Password = srv.registry.GetAuthConfig().Password
}
newAuthConfig := auth.NewAuthConfig(config.Username, config.Password, config.Email, srv.runtime.root)
status, err := auth.Login(newAuthConfig)
if err != nil {
return err
}
srv.registry.ResetClient(newAuthConfig)
if status != "" {
b, err := json.Marshal(&ApiAuth{Status: status})
if err != nil {
return err
}
writeJson(w, b)
return nil
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func getVersion(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
m := srv.DockerVersion()
b, err := json.Marshal(m)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func postContainersKill(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ContainerKill(name); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func getContainersExport(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ContainerExport(name, w); err != nil {
utils.Debugf("%s", err.Error())
return err
}
return nil
}
func getImagesJson(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
all, err := getBoolParam(r.Form.Get("all"))
if err != nil {
return err
}
filter := r.Form.Get("filter")
outs, err := srv.Images(all, filter)
if err != nil {
return err
}
b, err := json.Marshal(outs)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func getImagesViz(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := srv.ImagesViz(w); err != nil {
return err
}
return nil
}
func getInfo(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
out := srv.DockerInfo()
b, err := json.Marshal(out)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func getImagesHistory(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
outs, err := srv.ImageHistory(name)
if err != nil {
return err
}
b, err := json.Marshal(outs)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func getContainersChanges(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
changesStr, err := srv.ContainerChanges(name)
if err != nil {
return err
}
b, err := json.Marshal(changesStr)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func getContainersPs(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
all, err := getBoolParam(r.Form.Get("all"))
if err != nil {
return err
}
since := r.Form.Get("since")
before := r.Form.Get("before")
n, err := strconv.Atoi(r.Form.Get("limit"))
if err != nil {
n = -1
}
outs := srv.Containers(all, n, since, before)
b, err := json.Marshal(outs)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func postImagesTag(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
repo := r.Form.Get("repo")
tag := r.Form.Get("tag")
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
force, err := getBoolParam(r.Form.Get("force"))
if err != nil {
return err
}
if err := srv.ContainerTag(name, repo, tag, force); err != nil {
return err
}
w.WriteHeader(http.StatusCreated)
return nil
}
func postCommit(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
config := &Config{}
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
utils.Debugf("%s", err.Error())
}
repo := r.Form.Get("repo")
tag := r.Form.Get("tag")
container := r.Form.Get("container")
author := r.Form.Get("author")
comment := r.Form.Get("comment")
id, err := srv.ContainerCommit(container, repo, tag, author, comment, config)
if err != nil {
return err
}
b, err := json.Marshal(&ApiId{id})
if err != nil {
return err
}
w.WriteHeader(http.StatusCreated)
writeJson(w, b)
return nil
}
// Creates an image from Pull or from Import
func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
src := r.Form.Get("fromSrc")
image := r.Form.Get("fromImage")
tag := r.Form.Get("tag")
repo := r.Form.Get("repo")
if image != "" { //pull
registry := r.Form.Get("registry")
if err := srv.ImagePull(image, tag, registry, w); err != nil {
return err
}
} else { //import
if err := srv.ImageImport(src, repo, tag, r.Body, w); err != nil {
return err
}
}
return nil
}
func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
term := r.Form.Get("term")
outs, err := srv.ImagesSearch(term)
if err != nil {
return err
}
b, err := json.Marshal(outs)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
url := r.Form.Get("url")
path := r.Form.Get("path")
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ImageInsert(name, url, path, w); err != nil {
return err
}
return nil
}
func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
registry := r.Form.Get("registry")
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ImagePush(name, registry, w); err != nil {
return err
}
return nil
}
func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
config := &Config{}
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
return err
}
id, err := srv.ContainerCreate(config)
if err != nil {
return err
}
out := &ApiRun{
Id: id,
}
if config.Memory > 0 && !srv.runtime.capabilities.MemoryLimit {
log.Println("WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.")
out.Warnings = append(out.Warnings, "Your kernel does not support memory limit capabilities. Limitation discarded.")
}
if config.Memory > 0 && !srv.runtime.capabilities.SwapLimit {
log.Println("WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.")
out.Warnings = append(out.Warnings, "Your kernel does not support memory swap capabilities. Limitation discarded.")
}
b, err := json.Marshal(out)
if err != nil {
return err
}
w.WriteHeader(http.StatusCreated)
writeJson(w, b)
return nil
}
func postContainersRestart(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
t, err := strconv.Atoi(r.Form.Get("t"))
if err != nil || t < 0 {
t = 10
}
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ContainerRestart(name, t); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func deleteContainers(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
removeVolume, err := getBoolParam(r.Form.Get("v"))
if err != nil {
return err
}
if err := srv.ContainerDestroy(name, removeVolume); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func deleteImages(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ImageDelete(name); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func postContainersStart(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ContainerStart(name); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func postContainersStop(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
t, err := strconv.Atoi(r.Form.Get("t"))
if err != nil || t < 0 {
t = 10
}
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
if err := srv.ContainerStop(name, t); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
return nil
}
func postContainersWait(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
status, err := srv.ContainerWait(name)
if err != nil {
return err
}
b, err := json.Marshal(&ApiWait{StatusCode: status})
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
logs, err := getBoolParam(r.Form.Get("logs"))
if err != nil {
return err
}
stream, err := getBoolParam(r.Form.Get("stream"))
if err != nil {
return err
}
stdin, err := getBoolParam(r.Form.Get("stdin"))
if err != nil {
return err
}
stdout, err := getBoolParam(r.Form.Get("stdout"))
if err != nil {
return err
}
stderr, err := getBoolParam(r.Form.Get("stderr"))
if err != nil {
return err
}
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
in, out, err := hijackServer(w)
if err != nil {
return err
}
defer in.Close()
fmt.Fprintf(out, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
if err := srv.ContainerAttach(name, logs, stream, stdin, stdout, stderr, in, out); err != nil {
fmt.Fprintf(out, "Error: %s\n", err)
}
return nil
}
func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
container, err := srv.ContainerInspect(name)
if err != nil {
return err
}
b, err := json.Marshal(container)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func getImagesByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
image, err := srv.ImageInspect(name)
if err != nil {
return err
}
b, err := json.Marshal(image)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func postImagesGetCache(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
apiConfig := &ApiImageConfig{}
if err := json.NewDecoder(r.Body).Decode(apiConfig); err != nil {
return err
}
image, err := srv.ImageGetCached(apiConfig.Id, apiConfig.Config)
if err != nil {
return err
}
if image == nil {
w.WriteHeader(http.StatusNotFound)
return nil
}
apiId := &ApiId{Id: image.Id}
b, err := json.Marshal(apiId)
if err != nil {
return err
}
writeJson(w, b)
return nil
}
func ListenAndServe(addr string, srv *Server, logging bool) error {
r := mux.NewRouter()
log.Printf("Listening for HTTP on %s\n", addr)
m := map[string]map[string]func(*Server, float64, http.ResponseWriter, *http.Request, map[string]string) error{
"GET": {
"/auth": getAuth,
"/version": getVersion,
"/info": getInfo,
"/images/json": getImagesJson,
"/images/viz": getImagesViz,
"/images/search": getImagesSearch,
"/images/{name:.*}/history": getImagesHistory,
"/images/{name:.*}/json": getImagesByName,
"/containers/ps": getContainersPs,
"/containers/{name:.*}/export": getContainersExport,
"/containers/{name:.*}/changes": getContainersChanges,
"/containers/{name:.*}/json": getContainersByName,
},
"POST": {
"/auth": postAuth,
"/commit": postCommit,
"/images/create": postImagesCreate,
"/images/{name:.*}/insert": postImagesInsert,
"/images/{name:.*}/push": postImagesPush,
"/images/{name:.*}/tag": postImagesTag,
"/images/getCache": postImagesGetCache,
"/containers/create": postContainersCreate,
"/containers/{name:.*}/kill": postContainersKill,
"/containers/{name:.*}/restart": postContainersRestart,
"/containers/{name:.*}/start": postContainersStart,
"/containers/{name:.*}/stop": postContainersStop,
"/containers/{name:.*}/wait": postContainersWait,
"/containers/{name:.*}/attach": postContainersAttach,
},
"DELETE": {
"/containers/{name:.*}": deleteContainers,
"/images/{name:.*}": deleteImages,
},
}
for method, routes := range m {
for route, fct := range routes {
utils.Debugf("Registering %s, %s", method, route)
// NOTE: scope issue, make sure the variables are local and won't be changed
localRoute := route
localMethod := method
localFct := fct
f := func(w http.ResponseWriter, r *http.Request) {
utils.Debugf("Calling %s %s", localMethod, localRoute)
if logging {
log.Println(r.Method, r.RequestURI)
}
if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") {
userAgent := strings.Split(r.Header.Get("User-Agent"), "/")
if len(userAgent) == 2 && userAgent[1] != VERSION {
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], VERSION)
}
}
version, err := strconv.ParseFloat(mux.Vars(r)["version"], 64)
if err != nil {
version = API_VERSION
}
if version == 0 || version > API_VERSION {
w.WriteHeader(http.StatusNotFound)
return
}
if err := localFct(srv, version, w, r, mux.Vars(r)); err != nil {
httpError(w, err)
}
}
r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(f)
r.Path(localRoute).Methods(localMethod).HandlerFunc(f)
}
}
return http.ListenAndServe(addr, r)
}

71
api_params.go Normal file
View File

@@ -0,0 +1,71 @@
package docker
type ApiHistory struct {
Id string
Created int64
CreatedBy string
}
type ApiImages struct {
Repository string `json:",omitempty"`
Tag string `json:",omitempty"`
Id string
Created int64
}
type ApiInfo struct {
Containers int
Version string
Images int
Debug bool
GoVersion string
NFd int `json:",omitempty"`
NGoroutines int `json:",omitempty"`
}
type ApiContainers struct {
Id string
Image string
Command string
Created int64
Status string
Ports string
}
type ApiSearch struct {
Name string
Description string
}
type ApiId struct {
Id string
}
type ApiRun struct {
Id string
Warnings []string
}
type ApiPort struct {
Port string
}
type ApiVersion struct {
Version string
GitCommit string
MemoryLimit bool
SwapLimit bool
}
type ApiWait struct {
StatusCode int
}
type ApiAuth struct {
Status string
}
type ApiImageConfig struct {
Id string
*Config
}

1273
api_test.go Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,6 @@ package auth
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
@@ -16,13 +15,13 @@ import (
const CONFIGFILE = ".dockercfg"
// the registry server we want to login against
const REGISTRY_SERVER = "https://registry.docker.io"
const INDEX_SERVER = "https://index.docker.io/v1"
type AuthConfig struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
rootPath string `json:-`
rootPath string
}
func NewAuthConfig(username, password, email, rootPath string) *AuthConfig {
@@ -34,6 +33,13 @@ func NewAuthConfig(username, password, email, rootPath string) *AuthConfig {
}
}
func IndexServerAddress() string {
if os.Getenv("DOCKER_INDEX_URL") != "" {
return os.Getenv("DOCKER_INDEX_URL") + "/v1"
}
return INDEX_SERVER
}
// create a base64 encoded auth string to store in config
func EncodeAuth(authConfig *AuthConfig) string {
authStr := authConfig.Username + ":" + authConfig.Password
@@ -76,6 +82,9 @@ func LoadConfig(rootPath string) (*AuthConfig, error) {
return nil, err
}
arr := strings.Split(string(b), "\n")
if len(arr) < 2 {
return nil, fmt.Errorf("The Auth config file is empty")
}
origAuth := strings.Split(arr[0], " = ")
origEmail := strings.Split(arr[1], " = ")
authConfig, err := DecodeAuth(origAuth[1])
@@ -89,9 +98,14 @@ func LoadConfig(rootPath string) (*AuthConfig, error) {
// save the auth config
func saveConfig(rootPath, authStr string, email string) error {
confFile := path.Join(rootPath, CONFIGFILE)
if len(email) == 0 {
os.Remove(confFile)
return nil
}
lines := "auth = " + authStr + "\n" + "email = " + email + "\n"
b := []byte(lines)
err := ioutil.WriteFile(path.Join(rootPath, CONFIGFILE), b, 0600)
err := ioutil.WriteFile(confFile, b, 0600)
if err != nil {
return err
}
@@ -101,40 +115,38 @@ func saveConfig(rootPath, authStr string, email string) error {
// try to register/login to the registry server
func Login(authConfig *AuthConfig) (string, error) {
storeConfig := false
client := &http.Client{}
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)
return "", fmt.Errorf("Config Error: %s", err)
}
// 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)
req1, err := http.Post(IndexServerAddress()+"/users/", "application/json; charset=utf-8", b)
if err != nil {
errMsg = fmt.Sprintf("Server Error: %s", err)
return "", errors.New(errMsg)
return "", fmt.Errorf("Server Error: %s", err)
}
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)
return "", fmt.Errorf("Server Error: [%#v] %s", reqStatusCode, err)
}
if reqStatusCode == 201 {
status = "Account Created\n"
status = "Account created. Please use the confirmation link we sent" +
" to your e-mail to activate it.\n"
storeConfig = true
} else if reqStatusCode == 403 {
return "", fmt.Errorf("Login: Your account hasn't been activated. " +
"Please check your e-mail for a confirmation link.")
} 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)
if string(reqBody) == "\"Username or email already exists\"" {
req, err := http.NewRequest("GET", IndexServerAddress()+"/users/", nil)
req.SetBasicAuth(authConfig.Username, authConfig.Password)
resp, err := client.Do(req)
if err != nil {
@@ -148,17 +160,18 @@ func Login(authConfig *AuthConfig) (string, error) {
if resp.StatusCode == 200 {
status = "Login Succeeded\n"
storeConfig = true
} else if resp.StatusCode == 401 {
saveConfig(authConfig.rootPath, "", "")
return "", fmt.Errorf("Wrong login/password, please try again")
} else {
status = fmt.Sprintf("Login: %s", body)
return "", errors.New(status)
return "", fmt.Errorf("Login: %s (Code: %d; Headers: %s)", body,
resp.StatusCode, resp.Header)
}
} else {
status = fmt.Sprintf("Registration: %s", reqBody)
return "", errors.New(status)
return "", fmt.Errorf("Registration: %s", reqBody)
}
} else {
status = fmt.Sprintf("[%s] : %s", reqStatusCode, reqBody)
return "", errors.New(status)
return "", fmt.Errorf("Unexpected status code [%d] : %s", reqStatusCode, reqBody)
}
if storeConfig {
authStr := EncodeAuth(authConfig)

View File

@@ -1,6 +1,10 @@
package auth
import (
"crypto/rand"
"encoding/hex"
"os"
"strings"
"testing"
)
@@ -21,3 +25,49 @@ func TestEncodeAuth(t *testing.T) {
t.Fatal("AuthString encoding isn't correct.")
}
}
func TestLogin(t *testing.T) {
os.Setenv("DOCKER_INDEX_URL", "https://indexstaging-docker.dotcloud.com")
defer os.Setenv("DOCKER_INDEX_URL", "")
authConfig := NewAuthConfig("unittester", "surlautrerivejetattendrai", "noise+unittester@dotcloud.com", "/tmp")
status, err := Login(authConfig)
if err != nil {
t.Fatal(err)
}
if status != "Login Succeeded\n" {
t.Fatalf("Expected status \"Login Succeeded\", found \"%s\" instead", status)
}
}
func TestCreateAccount(t *testing.T) {
os.Setenv("DOCKER_INDEX_URL", "https://indexstaging-docker.dotcloud.com")
defer os.Setenv("DOCKER_INDEX_URL", "")
tokenBuffer := make([]byte, 16)
_, err := rand.Read(tokenBuffer)
if err != nil {
t.Fatal(err)
}
token := hex.EncodeToString(tokenBuffer)[:12]
username := "ut" + token
authConfig := NewAuthConfig(username, "test42", "docker-ut+"+token+"@example.com", "/tmp")
status, err := Login(authConfig)
if err != nil {
t.Fatal(err)
}
expectedStatus := "Account created. Please use the confirmation link we sent" +
" to your e-mail to activate it.\n"
if status != expectedStatus {
t.Fatalf("Expected status: \"%s\", found \"%s\" instead.", expectedStatus, status)
}
status, err = Login(authConfig)
if err == nil {
t.Fatalf("Expected error but found nil instead")
}
expectedError := "Login: Account is not Active"
if !strings.Contains(err.Error(), expectedError) {
t.Fatalf("Expected message \"%s\" but found \"%s\" instead", expectedError, err.Error())
}
}

28
buildbot/Vagrantfile vendored
View File

@@ -1,28 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
$BUILDBOT_IP = '192.168.33.21'
def v10(config)
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"
config.vm.share_folder 'v-data', '/data/docker', File.dirname(__FILE__) + '/..'
config.vm.network :hostonly, $BUILDBOT_IP
# Ensure puppet is installed on the instance
config.vm.provision :shell, :inline => 'apt-get -qq update; apt-get install -y puppet'
config.vm.provision :puppet do |puppet|
puppet.manifests_path = '.'
puppet.manifest_file = 'buildbot.pp'
puppet.options = ['--templatedir','.']
end
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

View File

@@ -1,43 +0,0 @@
#!/bin/bash
# Auto setup of buildbot configuration. Package installation is being done
# on buildbot.pp
# Dependencies: buildbot, buildbot-slave, supervisor
SLAVE_NAME='buildworker'
SLAVE_SOCKET='localhost:9989'
BUILDBOT_PWD='pass-docker'
USER='vagrant'
ROOT_PATH='/data/buildbot'
DOCKER_PATH='/data/docker'
BUILDBOT_CFG="$DOCKER_PATH/buildbot/buildbot-cfg"
IP=$(grep BUILDBOT_IP /data/docker/buildbot/Vagrantfile | awk -F "'" '{ print $2; }')
function run { su $USER -c "$1"; }
export PATH=/bin:sbin:/usr/bin:/usr/sbin:/usr/local/bin
# Exit if buildbot has already been installed
[ -d "$ROOT_PATH" ] && exit 0
# Setup buildbot
run "mkdir -p ${ROOT_PATH}"
cd ${ROOT_PATH}
run "buildbot create-master master"
run "cp $BUILDBOT_CFG/master.cfg master"
run "sed -i 's/localhost/$IP/' master/master.cfg"
run "buildslave create-slave slave $SLAVE_SOCKET $SLAVE_NAME $BUILDBOT_PWD"
# Allow buildbot subprocesses (docker tests) to properly run in containers,
# in particular with docker -u
run "sed -i 's/^umask = None/umask = 000/' ${ROOT_PATH}/slave/buildbot.tac"
# Setup supervisor
cp $BUILDBOT_CFG/buildbot.conf /etc/supervisor/conf.d/buildbot.conf
sed -i "s/^chmod=0700.*0700./chmod=0770\nchown=root:$USER/" /etc/supervisor/supervisord.conf
kill -HUP `pgrep -f "/usr/bin/python /usr/bin/supervisord"`
# Add git hook
cp $BUILDBOT_CFG/post-commit $DOCKER_PATH/.git/hooks
sed -i "s/localhost/$IP/" $DOCKER_PATH/.git/hooks/post-commit

View File

@@ -1,32 +0,0 @@
node default {
$USER = 'vagrant'
$ROOT_PATH = '/data/buildbot'
$DOCKER_PATH = '/data/docker'
exec {'apt_update': command => '/usr/bin/apt-get update' }
Package { require => Exec['apt_update'] }
group {'puppet': ensure => 'present'}
# Install dependencies
Package { ensure => 'installed' }
package { ['python-dev','python-pip','supervisor','lxc','bsdtar','git','golang']: }
file{[ '/data' ]:
owner => $USER, group => $USER, ensure => 'directory' }
file {'/var/tmp/requirements.txt':
content => template('requirements.txt') }
exec {'requirements':
require => [ Package['python-dev'], Package['python-pip'],
File['/var/tmp/requirements.txt'] ],
cwd => '/var/tmp',
command => "/bin/sh -c '(/usr/bin/pip install -r requirements.txt;
rm /var/tmp/requirements.txt)'" }
exec {'buildbot-cfg-sh':
require => [ Package['supervisor'], Exec['requirements']],
path => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin',
cwd => '/data',
command => "$DOCKER_PATH/buildbot/buildbot-cfg/buildbot-cfg.sh" }
}

118
builder.go Normal file
View File

@@ -0,0 +1,118 @@
package docker
import (
"fmt"
"os"
"path"
"time"
)
type Builder struct {
runtime *Runtime
repositories *TagStore
graph *Graph
config *Config
image *Image
}
func NewBuilder(runtime *Runtime) *Builder {
return &Builder{
runtime: runtime,
graph: runtime.graph,
repositories: runtime.repositories,
}
}
func (builder *Builder) Create(config *Config) (*Container, error) {
// Lookup image
img, err := builder.repositories.LookupImage(config.Image)
if err != nil {
return nil, err
}
if img.Config != nil {
MergeConfig(config, img.Config)
}
if config.Cmd == nil || len(config.Cmd) == 0 {
return nil, fmt.Errorf("No command specified")
}
// Generate id
id := GenerateId()
// Generate default hostname
// FIXME: the lxc template no longer needs to set a default hostname
if config.Hostname == "" {
config.Hostname = id[:12]
}
container := &Container{
// FIXME: we should generate the ID here instead of receiving it as an argument
Id: id,
Created: time.Now(),
Path: config.Cmd[0],
Args: config.Cmd[1:], //FIXME: de-duplicate from config
Config: config,
Image: img.Id, // Always use the resolved image id
NetworkSettings: &NetworkSettings{},
// FIXME: do we need to store this in the container?
SysInitPath: sysInitPath,
}
container.root = builder.runtime.containerRoot(container.Id)
// Step 1: create the container directory.
// This doubles as a barrier to avoid race conditions.
if err := os.Mkdir(container.root, 0700); err != nil {
return nil, err
}
// If custom dns exists, then create a resolv.conf for the container
if len(config.Dns) > 0 {
container.ResolvConfPath = path.Join(container.root, "resolv.conf")
f, err := os.Create(container.ResolvConfPath)
if err != nil {
return nil, err
}
defer f.Close()
for _, dns := range config.Dns {
if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil {
return nil, err
}
}
} else {
container.ResolvConfPath = "/etc/resolv.conf"
}
// Step 2: save the container json
if err := container.ToDisk(); err != nil {
return nil, err
}
// Step 3: register the container
if err := builder.runtime.Register(container); err != nil {
return nil, err
}
return container, nil
}
// Commit creates a new filesystem image from the current state of a container.
// The image can optionally be tagged into a repository
func (builder *Builder) Commit(container *Container, repository, tag, comment, author string, config *Config) (*Image, error) {
// FIXME: freeze the container before copying it to avoid data corruption?
// FIXME: this shouldn't be in commands.
rwTar, err := container.ExportRw()
if err != nil {
return nil, err
}
// Create a new image from the container's base layers + a new layer from container changes
img, err := builder.graph.Create(rwTar, container, comment, author, config)
if err != nil {
return nil, err
}
// Register the image if needed
if repository != "" {
if err := builder.repositories.Set(repository, tag, img.Id, true); err != nil {
return img, err
}
}
return img, nil
}

305
builder_client.go Normal file
View File

@@ -0,0 +1,305 @@
package docker
import (
"bufio"
"encoding/json"
"fmt"
"github.com/dotcloud/docker/utils"
"io"
"net/url"
"os"
"reflect"
"strings"
)
type BuilderClient interface {
Build(io.Reader) (string, error)
CmdFrom(string) error
CmdRun(string) error
}
type builderClient struct {
cli *DockerCli
image string
maintainer string
config *Config
tmpContainers map[string]struct{}
tmpImages map[string]struct{}
needCommit bool
}
func (b *builderClient) clearTmp(containers, images map[string]struct{}) {
for i := range images {
if _, _, err := b.cli.call("DELETE", "/images/"+i, nil); err != nil {
utils.Debugf("%s", err)
}
utils.Debugf("Removing image %s", i)
}
}
func (b *builderClient) CmdFrom(name string) error {
obj, statusCode, err := b.cli.call("GET", "/images/"+name+"/json", nil)
if statusCode == 404 {
remote := name
var tag string
if strings.Contains(remote, ":") {
remoteParts := strings.Split(remote, ":")
tag = remoteParts[1]
remote = remoteParts[0]
}
var out io.Writer
if os.Getenv("DEBUG") != "" {
out = os.Stdout
} else {
out = &utils.NopWriter{}
}
if err := b.cli.stream("POST", "/images/create?fromImage="+remote+"&tag="+tag, nil, out); err != nil {
return err
}
obj, _, err = b.cli.call("GET", "/images/"+name+"/json", nil)
if err != nil {
return err
}
}
if err != nil {
return err
}
img := &ApiId{}
if err := json.Unmarshal(obj, img); err != nil {
return err
}
b.image = img.Id
utils.Debugf("Using image %s", b.image)
return nil
}
func (b *builderClient) CmdMaintainer(name string) error {
b.needCommit = true
b.maintainer = name
return nil
}
func (b *builderClient) CmdRun(args string) error {
if b.image == "" {
return fmt.Errorf("Please provide a source image with `from` prior to run")
}
config, _, err := ParseRun([]string{b.image, "/bin/sh", "-c", args}, nil)
if err != nil {
return err
}
cmd, env := b.config.Cmd, b.config.Env
b.config.Cmd = nil
MergeConfig(b.config, config)
body, statusCode, err := b.cli.call("POST", "/images/getCache", &ApiImageConfig{Id: b.image, Config: b.config})
if err != nil {
if statusCode != 404 {
return err
}
}
if statusCode != 404 {
apiId := &ApiId{}
if err := json.Unmarshal(body, apiId); err != nil {
return err
}
utils.Debugf("Use cached version")
b.image = apiId.Id
return nil
}
cid, err := b.run()
if err != nil {
return err
}
b.config.Cmd, b.config.Env = cmd, env
return b.commit(cid)
}
func (b *builderClient) CmdEnv(args string) error {
b.needCommit = true
tmp := strings.SplitN(args, " ", 2)
if len(tmp) != 2 {
return fmt.Errorf("Invalid ENV format")
}
key := strings.Trim(tmp[0], " ")
value := strings.Trim(tmp[1], " ")
for i, elem := range b.config.Env {
if strings.HasPrefix(elem, key+"=") {
b.config.Env[i] = key + "=" + value
return nil
}
}
b.config.Env = append(b.config.Env, key+"="+value)
return nil
}
func (b *builderClient) CmdCmd(args string) error {
b.needCommit = true
var cmd []string
if err := json.Unmarshal([]byte(args), &cmd); err != nil {
utils.Debugf("Error unmarshalling: %s, using /bin/sh -c", err)
b.config.Cmd = []string{"/bin/sh", "-c", args}
} else {
b.config.Cmd = cmd
}
return nil
}
func (b *builderClient) CmdExpose(args string) error {
ports := strings.Split(args, " ")
b.config.PortSpecs = append(ports, b.config.PortSpecs...)
return nil
}
func (b *builderClient) CmdInsert(args string) error {
// FIXME: Reimplement this once the remove_hijack branch gets merged.
// We need to retrieve the resulting Id
return fmt.Errorf("INSERT not implemented")
}
func (b *builderClient) run() (string, error) {
if b.image == "" {
return "", fmt.Errorf("Please provide a source image with `from` prior to run")
}
b.config.Image = b.image
body, _, err := b.cli.call("POST", "/containers/create", b.config)
if err != nil {
return "", err
}
apiRun := &ApiRun{}
if err := json.Unmarshal(body, apiRun); err != nil {
return "", err
}
for _, warning := range apiRun.Warnings {
fmt.Fprintln(os.Stderr, "WARNING: ", warning)
}
//start the container
_, _, err = b.cli.call("POST", "/containers/"+apiRun.Id+"/start", nil)
if err != nil {
return "", err
}
b.tmpContainers[apiRun.Id] = struct{}{}
// Wait for it to finish
body, _, err = b.cli.call("POST", "/containers/"+apiRun.Id+"/wait", nil)
if err != nil {
return "", err
}
apiWait := &ApiWait{}
if err := json.Unmarshal(body, apiWait); err != nil {
return "", err
}
if apiWait.StatusCode != 0 {
return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, apiWait.StatusCode)
}
return apiRun.Id, nil
}
func (b *builderClient) commit(id string) error {
if b.image == "" {
return fmt.Errorf("Please provide a source image with `from` prior to run")
}
b.config.Image = b.image
if id == "" {
cmd := b.config.Cmd
b.config.Cmd = []string{"true"}
if cid, err := b.run(); err != nil {
return err
} else {
id = cid
}
b.config.Cmd = cmd
}
// Commit the container
v := url.Values{}
v.Set("container", id)
v.Set("author", b.maintainer)
body, _, err := b.cli.call("POST", "/commit?"+v.Encode(), b.config)
if err != nil {
return err
}
apiId := &ApiId{}
if err := json.Unmarshal(body, apiId); err != nil {
return err
}
b.tmpImages[apiId.Id] = struct{}{}
b.image = apiId.Id
b.needCommit = false
return nil
}
func (b *builderClient) Build(dockerfile io.Reader) (string, error) {
defer b.clearTmp(b.tmpContainers, b.tmpImages)
file := bufio.NewReader(dockerfile)
for {
line, err := file.ReadString('\n')
if err != nil {
if err == io.EOF {
break
}
return "", err
}
line = strings.Replace(strings.TrimSpace(line), " ", " ", 1)
// Skip comments and empty line
if len(line) == 0 || line[0] == '#' {
continue
}
tmp := strings.SplitN(line, " ", 2)
if len(tmp) != 2 {
return "", fmt.Errorf("Invalid Dockerfile format")
}
instruction := strings.ToLower(strings.Trim(tmp[0], " "))
arguments := strings.Trim(tmp[1], " ")
fmt.Printf("%s %s (%s)\n", strings.ToUpper(instruction), arguments, b.image)
method, exists := reflect.TypeOf(b).MethodByName("Cmd" + strings.ToUpper(instruction[:1]) + strings.ToLower(instruction[1:]))
if !exists {
fmt.Printf("Skipping unknown instruction %s\n", strings.ToUpper(instruction))
}
ret := method.Func.Call([]reflect.Value{reflect.ValueOf(b), reflect.ValueOf(arguments)})[0].Interface()
if ret != nil {
return "", ret.(error)
}
fmt.Printf("===> %v\n", b.image)
}
if b.needCommit {
if err := b.commit(""); err != nil {
return "", err
}
}
if b.image != "" {
// The build is successful, keep the temporary containers and images
for i := range b.tmpImages {
delete(b.tmpImages, i)
}
for i := range b.tmpContainers {
delete(b.tmpContainers, i)
}
fmt.Printf("Build finished. image id: %s\n", b.image)
return b.image, nil
}
return "", fmt.Errorf("An error occured during the build\n")
}
func NewBuilderClient(addr string, port int) BuilderClient {
return &builderClient{
cli: NewDockerCli(addr, port),
config: &Config{},
tmpContainers: make(map[string]struct{}),
tmpImages: make(map[string]struct{}),
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -3,9 +3,8 @@ package docker
import (
"bufio"
"fmt"
"github.com/dotcloud/docker/rcli"
"io"
"io/ioutil"
_ "io/ioutil"
"strings"
"testing"
"time"
@@ -59,6 +58,7 @@ func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error
return nil
}
/*TODO
func cmdWait(srv *Server, container *Container) error {
stdout, stdoutPipe := io.Pipe()
@@ -73,6 +73,77 @@ func cmdWait(srv *Server, container *Container) error {
return closeWrap(stdout, stdoutPipe)
}
func cmdImages(srv *Server, args ...string) (string, error) {
stdout, stdoutPipe := io.Pipe()
go func() {
if err := srv.CmdImages(nil, stdoutPipe, args...); err != nil {
return
}
// force the pipe closed, so that the code below gets an EOF
stdoutPipe.Close()
}()
output, err := ioutil.ReadAll(stdout)
if err != nil {
return "", err
}
// Cleanup pipes
return string(output), closeWrap(stdout, stdoutPipe)
}
// TestImages checks that 'docker images' displays information correctly
func TestImages(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
output, err := cmdImages(srv)
if !strings.Contains(output, "REPOSITORY") {
t.Fatal("'images' should have a header")
}
if !strings.Contains(output, "docker-ut") {
t.Fatal("'images' should show the docker-ut image")
}
if !strings.Contains(output, "e9aa60c60128") {
t.Fatal("'images' should show the docker-ut image id")
}
output, err = cmdImages(srv, "-q")
if strings.Contains(output, "REPOSITORY") {
t.Fatal("'images -q' should not have a header")
}
if strings.Contains(output, "docker-ut") {
t.Fatal("'images' should not show the docker-ut image name")
}
if !strings.Contains(output, "e9aa60c60128") {
t.Fatal("'images' should show the docker-ut image id")
}
output, err = cmdImages(srv, "-viz")
if !strings.HasPrefix(output, "digraph docker {") {
t.Fatal("'images -v' should start with the dot header")
}
if !strings.HasSuffix(output, "}\n") {
t.Fatal("'images -v' should end with a '}'")
}
if !strings.Contains(output, "base -> \"e9aa60c60128\" [style=invis]") {
t.Fatal("'images -v' should have the docker-ut image id node")
}
// todo: add checks for -a
}
// TestRunHostname checks that 'docker run -h' correctly sets a custom hostname
func TestRunHostname(t *testing.T) {
runtime, err := newTestRuntime()
@@ -339,9 +410,10 @@ func TestAttachDisconnect(t *testing.T) {
srv := &Server{runtime: runtime}
container, err := runtime.Create(
container, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).Id,
CpuShares: 1000,
Memory: 33554432,
Cmd: []string{"/bin/cat"},
OpenStdin: true,
@@ -394,4 +466,6 @@ func TestAttachDisconnect(t *testing.T) {
// Try to avoid the timeoout in destroy. Best effort, don't check error
cStdin, _ := container.StdinPipe()
cStdin.Close()
container.Wait()
}
*/

View File

@@ -2,8 +2,9 @@ package docker
import (
"encoding/json"
"flag"
"fmt"
"github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/utils"
"github.com/kr/pty"
"io"
"io/ioutil"
@@ -39,8 +40,8 @@ type Container struct {
ResolvConfPath string
cmd *exec.Cmd
stdout *writeBroadcaster
stderr *writeBroadcaster
stdout *utils.WriteBroadcaster
stderr *utils.WriteBroadcaster
stdin io.ReadCloser
stdinPipe io.WriteCloser
ptyMaster io.Closer
@@ -48,6 +49,7 @@ type Container struct {
runtime *Runtime
waitLock chan struct{}
Volumes map[string]string
}
type Config struct {
@@ -55,6 +57,7 @@ type Config struct {
User string
Memory int64 // Memory limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap
CpuShares int64 // CPU shares (relative weight vs. other containers)
AttachStdin bool
AttachStdout bool
AttachStderr bool
@@ -66,10 +69,12 @@ type Config struct {
Cmd []string
Dns []string
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
Volumes map[string]struct{}
VolumesFrom string
}
func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Config, error) {
cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
func ParseRun(args []string, capabilities *Capabilities) (*Config, *flag.FlagSet, error) {
cmd := Subcmd("run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
if len(args) > 0 && args[0] != "--help" {
cmd.SetOutput(ioutil.Discard)
}
@@ -83,11 +88,13 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con
flTty := cmd.Bool("t", false, "Allocate a pseudo-tty")
flMemory := cmd.Int64("m", 0, "Memory limit (in bytes)")
if *flMemory > 0 && !capabilities.MemoryLimit {
fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
if capabilities != nil && *flMemory > 0 && !capabilities.MemoryLimit {
//fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
*flMemory = 0
}
flCpuShares := cmd.Int64("c", 0, "CPU shares (relative weight)")
var flPorts ListOpts
cmd.Var(&flPorts, "p", "Expose a container's port to the host (use 'docker port' to see the actual mapping)")
@@ -97,11 +104,16 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con
var flDns ListOpts
cmd.Var(&flDns, "dns", "Set custom dns servers")
flVolumes := NewPathOpts()
cmd.Var(flVolumes, "v", "Attach a data volume")
flVolumesFrom := cmd.String("volumes-from", "", "Mount volumes from the specified container")
if err := cmd.Parse(args); err != nil {
return nil, err
return nil, cmd, err
}
if *flDetach && len(flAttach) > 0 {
return nil, fmt.Errorf("Conflicting options: -a and -d")
return nil, cmd, fmt.Errorf("Conflicting options: -a and -d")
}
// If neither -d or -a are set, attach to everything by default
if len(flAttach) == 0 && !*flDetach {
@@ -129,6 +141,7 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con
Tty: *flTty,
OpenStdin: *flStdin,
Memory: *flMemory,
CpuShares: *flCpuShares,
AttachStdin: flAttach.Get("stdin"),
AttachStdout: flAttach.Get("stdout"),
AttachStderr: flAttach.Get("stderr"),
@@ -136,10 +149,12 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con
Cmd: runCmd,
Dns: flDns,
Image: image,
Volumes: flVolumes,
VolumesFrom: *flVolumesFrom,
}
if *flMemory > 0 && !capabilities.SwapLimit {
fmt.Fprintf(stdout, "WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n")
if capabilities != nil && *flMemory > 0 && !capabilities.SwapLimit {
//fmt.Fprintf(stdout, "WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n")
config.MemorySwap = -1
}
@@ -147,7 +162,7 @@ func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Con
if config.OpenStdin && config.AttachStdin {
config.StdinOnce = true
}
return config, nil
return config, cmd, nil
}
type NetworkSettings struct {
@@ -168,6 +183,23 @@ func (settings *NetworkSettings) PortMappingHuman() string {
return strings.Join(mapping, ", ")
}
// Inject the io.Reader at the given path. Note: do not close the reader
func (container *Container) Inject(file io.Reader, pth string) error {
// Make sure the directory exists
if err := os.MkdirAll(path.Join(container.rwPath(), path.Dir(pth)), 0755); err != nil {
return err
}
// FIXME: Handle permissions/already existing dest
dest, err := os.Create(path.Join(container.rwPath(), pth))
if err != nil {
return err
}
if _, err := io.Copy(dest, file); err != nil {
return err
}
return nil
}
func (container *Container) Cmd() *exec.Cmd {
return container.cmd
}
@@ -220,9 +252,9 @@ func (container *Container) startPty() error {
// Copy the PTYs to our broadcasters
go func() {
defer container.stdout.CloseWriters()
Debugf("[startPty] Begin of stdout pipe")
utils.Debugf("[startPty] Begin of stdout pipe")
io.Copy(container.stdout, ptyMaster)
Debugf("[startPty] End of stdout pipe")
utils.Debugf("[startPty] End of stdout pipe")
}()
// stdin
@@ -231,9 +263,9 @@ func (container *Container) startPty() error {
container.cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true}
go func() {
defer container.stdin.Close()
Debugf("[startPty] Begin of stdin pipe")
utils.Debugf("[startPty] Begin of stdin pipe")
io.Copy(ptyMaster, container.stdin)
Debugf("[startPty] End of stdin pipe")
utils.Debugf("[startPty] End of stdin pipe")
}()
}
if err := container.cmd.Start(); err != nil {
@@ -253,9 +285,9 @@ func (container *Container) start() error {
}
go func() {
defer stdin.Close()
Debugf("Begin of stdin pipe [start]")
utils.Debugf("Begin of stdin pipe [start]")
io.Copy(stdin, container.stdin)
Debugf("End of stdin pipe [start]")
utils.Debugf("End of stdin pipe [start]")
}()
}
return container.cmd.Start()
@@ -272,8 +304,8 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
errors <- err
} else {
go func() {
Debugf("[start] attach stdin\n")
defer Debugf("[end] attach stdin\n")
utils.Debugf("[start] attach stdin\n")
defer utils.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()
@@ -285,12 +317,12 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
defer cStdin.Close()
}
if container.Config.Tty {
_, err = CopyEscapable(cStdin, stdin)
_, err = utils.CopyEscapable(cStdin, stdin)
} else {
_, err = io.Copy(cStdin, stdin)
}
if err != nil {
Debugf("[error] attach stdin: %s\n", err)
utils.Debugf("[error] attach stdin: %s\n", err)
}
// Discard error, expecting pipe error
errors <- nil
@@ -304,8 +336,8 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
} else {
cStdout = p
go func() {
Debugf("[start] attach stdout\n")
defer Debugf("[end] attach stdout\n")
utils.Debugf("[start] attach stdout\n")
defer utils.Debugf("[end] attach stdout\n")
// If we are in StdinOnce mode, then close stdin
if container.Config.StdinOnce {
if stdin != nil {
@@ -317,7 +349,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
}
_, err := io.Copy(stdout, cStdout)
if err != nil {
Debugf("[error] attach stdout: %s\n", err)
utils.Debugf("[error] attach stdout: %s\n", err)
}
errors <- err
}()
@@ -330,8 +362,8 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
} else {
cStderr = p
go func() {
Debugf("[start] attach stderr\n")
defer Debugf("[end] attach stderr\n")
utils.Debugf("[start] attach stderr\n")
defer utils.Debugf("[end] attach stderr\n")
// If we are in StdinOnce mode, then close stdin
if container.Config.StdinOnce {
if stdin != nil {
@@ -343,13 +375,13 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
}
_, err := io.Copy(stderr, cStderr)
if err != nil {
Debugf("[error] attach stderr: %s\n", err)
utils.Debugf("[error] attach stderr: %s\n", err)
}
errors <- err
}()
}
}
return Go(func() error {
return utils.Go(func() error {
if cStdout != nil {
defer cStdout.Close()
}
@@ -359,14 +391,14 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
// 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)
utils.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)
utils.Debugf("Job %d returned error %s. Aborting all jobs\n", i+1, err)
return err
}
Debugf("Job %d completed successfully\n", i+1)
utils.Debugf("Job %d completed successfully\n", i+1)
}
Debugf("All jobs completed successfully\n")
utils.Debugf("All jobs completed successfully\n")
return nil
})
}
@@ -394,10 +426,40 @@ func (container *Container) Start() error {
log.Printf("WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n")
container.Config.MemorySwap = -1
}
container.Volumes = make(map[string]string)
// Create the requested volumes volumes
for volPath := range container.Config.Volumes {
if c, err := container.runtime.volumes.Create(nil, container, "", "", nil); err != nil {
return err
} else {
if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
return nil
}
container.Volumes[volPath] = c.Id
}
}
if container.Config.VolumesFrom != "" {
c := container.runtime.Get(container.Config.VolumesFrom)
if c == nil {
return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.Id)
}
for volPath, id := range c.Volumes {
if _, exists := container.Volumes[volPath]; exists {
return fmt.Errorf("The requested volume %s overlap one of the volume of the container %s", volPath, c.Id)
}
if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
return nil
}
container.Volumes[volPath] = id
}
}
if err := container.generateLXCConfig(); err != nil {
return err
}
params := []string{
"-n", container.Id,
"-f", container.lxcConfigPath(),
@@ -456,6 +518,7 @@ func (container *Container) Start() error {
// Init the lock
container.waitLock = make(chan struct{})
container.ToDisk()
go container.monitor()
return nil
@@ -493,13 +556,13 @@ func (container *Container) StdinPipe() (io.WriteCloser, error) {
func (container *Container) StdoutPipe() (io.ReadCloser, error) {
reader, writer := io.Pipe()
container.stdout.AddWriter(writer)
return newBufReader(reader), nil
return utils.NewBufReader(reader), nil
}
func (container *Container) StderrPipe() (io.ReadCloser, error) {
reader, writer := io.Pipe()
container.stderr.AddWriter(writer)
return newBufReader(reader), nil
return utils.NewBufReader(reader), nil
}
func (container *Container) allocateNetwork() error {
@@ -547,20 +610,20 @@ func (container *Container) waitLxc() error {
func (container *Container) monitor() {
// Wait for the program to exit
Debugf("Waiting for process")
utils.Debugf("Waiting for process")
// If the command does not exists, try to wait via lxc
if container.cmd == nil {
if err := container.waitLxc(); err != nil {
Debugf("%s: Process: %s", container.Id, err)
utils.Debugf("%s: Process: %s", container.Id, err)
}
} else {
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)
utils.Debugf("%s: Process: %s", container.Id, err)
}
}
Debugf("Process finished")
utils.Debugf("Process finished")
var exitCode int = -1
if container.cmd != nil {
@@ -571,19 +634,19 @@ func (container *Container) monitor() {
container.releaseNetwork()
if container.Config.OpenStdin {
if err := container.stdin.Close(); err != nil {
Debugf("%s: Error close stdin: %s", container.Id, err)
utils.Debugf("%s: Error close stdin: %s", container.Id, err)
}
}
if err := container.stdout.CloseWriters(); err != nil {
Debugf("%s: Error close stdout: %s", container.Id, err)
utils.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)
utils.Debugf("%s: Error close stderr: %s", container.Id, err)
}
if container.ptyMaster != nil {
if err := container.ptyMaster.Close(); err != nil {
Debugf("%s: Error closing Pty master: %s", container.Id, err)
utils.Debugf("%s: Error closing Pty master: %s", container.Id, err)
}
}
@@ -695,6 +758,14 @@ func (container *Container) ExportRw() (Archive, error) {
return Tar(container.rwPath(), Uncompressed)
}
func (container *Container) RwChecksum() (string, error) {
rwData, err := Tar(container.rwPath(), Xz)
if err != nil {
return "", err
}
return utils.HashData(rwData)
}
func (container *Container) Export() (Archive, error) {
if err := container.EnsureMounted(); err != nil {
return nil, err
@@ -763,7 +834,7 @@ func (container *Container) Unmount() error {
// 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)
return utils.TruncateId(container.Id)
}
func (container *Container) logPath(name string) string {
@@ -787,6 +858,22 @@ func (container *Container) RootfsPath() string {
return path.Join(container.root, "rootfs")
}
func (container *Container) GetVolumes() (map[string]string, error) {
ret := make(map[string]string)
for volPath, id := range container.Volumes {
volume, err := container.runtime.volumes.Get(id)
if err != nil {
return nil, err
}
root, err := volume.root()
if err != nil {
return nil, err
}
ret[volPath] = path.Join(root, "layer")
}
return ret, nil
}
func (container *Container) rwPath() string {
return path.Join(container.root, "rw")
}

View File

@@ -20,11 +20,10 @@ func TestIdFormat(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container1, err := runtime.Create(
container1, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/sh", "-c", "echo hello world"},
Memory: 33554432,
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/sh", "-c", "echo hello world"},
},
)
if err != nil {
@@ -45,12 +44,11 @@ func TestMultipleAttachRestart(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(
container, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/sh", "-c",
"i=1; while [ $i -le 5 ]; do i=`expr $i + 1`; echo hello; done"},
Memory: 33554432,
},
)
if err != nil {
@@ -116,8 +114,8 @@ func TestMultipleAttachRestart(t *testing.T) {
if err := container.Start(); err != nil {
t.Fatal(err)
}
timeout := make(chan bool)
go func() {
setTimeout(t, "Timeout reading from the process", 3*time.Second, func() {
l1, err = bufio.NewReader(stdout1).ReadString('\n')
if err != nil {
t.Fatal(err)
@@ -139,15 +137,8 @@ func TestMultipleAttachRestart(t *testing.T) {
if strings.Trim(l3, " \r\n") != "hello" {
t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l3)
}
timeout <- false
}()
go func() {
time.Sleep(3 * time.Second)
timeout <- true
}()
if <-timeout {
t.Fatalf("Timeout reading from the process")
}
})
container.Wait()
}
func TestDiff(t *testing.T) {
@@ -157,8 +148,10 @@ func TestDiff(t *testing.T) {
}
defer nuke(runtime)
builder := NewBuilder(runtime)
// Create a container and remove a file
container1, err := runtime.Create(
container1, err := builder.Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/rm", "/etc/passwd"},
@@ -193,13 +186,13 @@ func TestDiff(t *testing.T) {
if err != nil {
t.Error(err)
}
img, err := runtime.graph.Create(rwTar, container1, "unit test commited image - diff", "")
img, err := runtime.graph.Create(rwTar, container1, "unit test commited image - diff", "", nil)
if err != nil {
t.Error(err)
}
// Create a new container from the commited image
container2, err := runtime.Create(
container2, err := builder.Create(
&Config{
Image: img.Id,
Cmd: []string{"cat", "/etc/passwd"},
@@ -226,17 +219,18 @@ func TestDiff(t *testing.T) {
}
}
func TestCommitRun(t *testing.T) {
func TestCommitAutoRun(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
container1, err := runtime.Create(
builder := NewBuilder(runtime)
container1, err := builder.Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/sh", "-c", "echo hello > /world"},
Memory: 33554432,
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/sh", "-c", "echo hello > /world"},
},
)
if err != nil {
@@ -258,18 +252,97 @@ func TestCommitRun(t *testing.T) {
if err != nil {
t.Error(err)
}
img, err := runtime.graph.Create(rwTar, container1, "unit test commited image", "")
img, err := runtime.graph.Create(rwTar, container1, "unit test commited image", "", &Config{Cmd: []string{"cat", "/world"}})
if err != nil {
t.Error(err)
}
// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
container2, err := builder.Create(
&Config{
Image: img.Id,
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container2)
stdout, err := container2.StdoutPipe()
if err != nil {
t.Fatal(err)
}
stderr, err := container2.StderrPipe()
if err != nil {
t.Fatal(err)
}
if err := container2.Start(); err != nil {
t.Fatal(err)
}
container2.Wait()
output, err := ioutil.ReadAll(stdout)
if err != nil {
t.Fatal(err)
}
output2, err := ioutil.ReadAll(stderr)
if err != nil {
t.Fatal(err)
}
if err := stdout.Close(); err != nil {
t.Fatal(err)
}
if err := stderr.Close(); err != nil {
t.Fatal(err)
}
if string(output) != "hello\n" {
t.Fatalf("Unexpected output. Expected %s, received: %s (err: %s)", "hello\n", output, output2)
}
}
func TestCommitRun(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
builder := NewBuilder(runtime)
container1, err := builder.Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/sh", "-c", "echo hello > /world"},
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container1)
if container1.State.Running {
t.Errorf("Container shouldn't be running")
}
if err := container1.Run(); err != nil {
t.Fatal(err)
}
if container1.State.Running {
t.Errorf("Container shouldn't be running")
}
rwTar, err := container1.ExportRw()
if err != nil {
t.Error(err)
}
img, err := runtime.graph.Create(rwTar, container1, "unit test commited image", "", nil)
if err != nil {
t.Error(err)
}
// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
container2, err := runtime.Create(
container2, err := builder.Create(
&Config{
Image: img.Id,
Memory: 33554432,
Cmd: []string{"cat", "/world"},
Image: img.Id,
Cmd: []string{"cat", "/world"},
},
)
if err != nil {
@@ -313,10 +386,11 @@ func TestStart(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(
container, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).Id,
Memory: 33554432,
CpuShares: 1000,
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
@@ -326,6 +400,11 @@ func TestStart(t *testing.T) {
}
defer runtime.Destroy(container)
cStdin, err := container.StdinPipe()
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
t.Fatal(err)
}
@@ -341,7 +420,6 @@ func TestStart(t *testing.T) {
}
// Try to avoid the timeoout in destroy. Best effort, don't check error
cStdin, _ := container.StdinPipe()
cStdin.Close()
container.WaitTimeout(2 * time.Second)
}
@@ -352,11 +430,10 @@ func TestRun(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(
container, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).Id,
Memory: 33554432,
Cmd: []string{"ls", "-al"},
Image: GetTestImage(runtime).Id,
Cmd: []string{"ls", "-al"},
},
)
if err != nil {
@@ -381,7 +458,7 @@ func TestOutput(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(
container, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"echo", "-n", "foobar"},
@@ -406,7 +483,7 @@ func TestKillDifferentUser(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"tail", "-f", "/etc/resolv.conf"},
User: "daemon",
@@ -454,7 +531,7 @@ func TestKill(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"cat", "/dev/zero"},
},
@@ -500,7 +577,9 @@ func TestExitCode(t *testing.T) {
}
defer nuke(runtime)
trueContainer, err := runtime.Create(&Config{
builder := NewBuilder(runtime)
trueContainer, err := builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/true", ""},
})
@@ -515,7 +594,7 @@ func TestExitCode(t *testing.T) {
t.Errorf("Unexpected exit code %d (expected 0)", trueContainer.State.ExitCode)
}
falseContainer, err := runtime.Create(&Config{
falseContainer, err := builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/false", ""},
})
@@ -537,7 +616,7 @@ func TestRestart(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"echo", "-n", "foobar"},
},
@@ -570,7 +649,7 @@ func TestRestartStdin(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"cat"},
@@ -649,8 +728,10 @@ func TestUser(t *testing.T) {
}
defer nuke(runtime)
builder := NewBuilder(runtime)
// Default user must be root
container, err := runtime.Create(&Config{
container, err := builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"id"},
},
@@ -668,7 +749,7 @@ func TestUser(t *testing.T) {
}
// Set a username
container, err = runtime.Create(&Config{
container, err = builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"id"},
@@ -688,7 +769,7 @@ func TestUser(t *testing.T) {
}
// Set a UID
container, err = runtime.Create(&Config{
container, err = builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"id"},
@@ -708,7 +789,7 @@ func TestUser(t *testing.T) {
}
// Set a different user by uid
container, err = runtime.Create(&Config{
container, err = builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"id"},
@@ -730,7 +811,7 @@ func TestUser(t *testing.T) {
}
// Set a different user by username
container, err = runtime.Create(&Config{
container, err = builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"id"},
@@ -757,7 +838,9 @@ func TestMultipleContainers(t *testing.T) {
}
defer nuke(runtime)
container1, err := runtime.Create(&Config{
builder := NewBuilder(runtime)
container1, err := builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"cat", "/dev/zero"},
},
@@ -767,7 +850,7 @@ func TestMultipleContainers(t *testing.T) {
}
defer runtime.Destroy(container1)
container2, err := runtime.Create(&Config{
container2, err := builder.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"cat", "/dev/zero"},
},
@@ -813,7 +896,7 @@ func TestStdin(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"cat"},
@@ -860,7 +943,7 @@ func TestTty(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"cat"},
@@ -907,7 +990,7 @@ func TestEnv(t *testing.T) {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/usr/bin/env"},
},
@@ -981,12 +1064,17 @@ func TestLXCConfig(t *testing.T) {
memMin := 33554432
memMax := 536870912
mem := memMin + rand.Intn(memMax-memMin)
container, err := runtime.Create(&Config{
// CPU shares as well
cpuMin := 100
cpuMax := 10000
cpu := cpuMin + rand.Intn(cpuMax-cpuMin)
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/true"},
Hostname: "foobar",
Memory: int64(mem),
Hostname: "foobar",
Memory: int64(mem),
CpuShares: int64(cpu),
},
)
if err != nil {
@@ -1008,7 +1096,7 @@ func BenchmarkRunSequencial(b *testing.B) {
}
defer nuke(runtime)
for i := 0; i < b.N; i++ {
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"echo", "-n", "foo"},
},
@@ -1043,7 +1131,7 @@ func BenchmarkRunParallel(b *testing.B) {
complete := make(chan error)
tasks = append(tasks, complete)
go func(i int, complete chan error) {
container, err := runtime.Create(&Config{
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"echo", "-n", "foo"},
},

View File

@@ -1,17 +1,22 @@
package main
import (
"fmt"
"io"
"log"
"net"
"os"
"os/exec"
"path"
"time"
)
const DOCKER_PATH = "/home/creack/dotcloud/docker/docker/docker"
var DOCKER_PATH string = path.Join(os.Getenv("DOCKERPATH"), "docker")
// WARNING: this crashTest will 1) crash your host, 2) remove all containers
func runDaemon() (*exec.Cmd, error) {
os.Remove("/var/run/docker.pid")
exec.Command("rm", "-rf", "/var/lib/docker/containers").Run()
cmd := exec.Command(DOCKER_PATH, "-d")
outPipe, err := cmd.StdoutPipe()
if err != nil {
@@ -38,19 +43,43 @@ func crashTest() error {
return err
}
var endpoint string
if ep := os.Getenv("TEST_ENDPOINT"); ep == "" {
endpoint = "192.168.56.1:7979"
} else {
endpoint = ep
}
c := make(chan bool)
var conn io.Writer
go func() {
conn, _ = net.Dial("tcp", endpoint)
c <- false
}()
go func() {
time.Sleep(2 * time.Second)
c <- true
}()
<-c
restartCount := 0
totalTestCount := 1
for {
daemon, err := runDaemon()
if err != nil {
return err
}
restartCount++
// time.Sleep(5000 * time.Millisecond)
var stop bool
go func() error {
stop = false
for i := 0; i < 100 && !stop; i++ {
for i := 0; i < 100 && !stop; {
func() error {
cmd := exec.Command(DOCKER_PATH, "run", "base", "echo", "hello", "world")
log.Printf("%d", i)
cmd := exec.Command(DOCKER_PATH, "run", "base", "echo", fmt.Sprintf("%d", totalTestCount))
i++
totalTestCount++
outPipe, err := cmd.StdoutPipe()
if err != nil {
return err
@@ -62,9 +91,10 @@ func crashTest() error {
if err := cmd.Start(); err != nil {
return err
}
go func() {
io.Copy(os.Stdout, outPipe)
}()
if conn != nil {
go io.Copy(conn, outPipe)
}
// Expecting error, do not check
inPipe.Write([]byte("hello world!!!!!\n"))
go inPipe.Write([]byte("hello world!!!!!\n"))

View File

@@ -49,26 +49,39 @@ def docker(args, stdin=None):
def image_exists(img):
return docker(["inspect", img]).read().strip() != ""
def run_and_commit(img_in, cmd, stdin=None):
def image_config(img):
return json.loads(docker(["inspect", img]).read()).get("config", {})
def run_and_commit(img_in, cmd, stdin=None, author=None, run=None):
run_id = docker(["run"] + (["-i", "-a", "stdin"] if stdin else ["-d"]) + [img_in, "/bin/sh", "-c", cmd], stdin=stdin).read().rstrip()
print "---> Waiting for " + run_id
result=int(docker(["wait", run_id]).read().rstrip())
if result != 0:
print "!!! '{}' return non-zero exit code '{}'. Aborting.".format(cmd, result)
sys.exit(1)
return docker(["commit", run_id]).read().rstrip()
return docker(["commit"] + (["-author", author] if author else []) + (["-run", json.dumps(run)] if run is not None else []) + [run_id]).read().rstrip()
def insert(base, src, dst):
def insert(base, src, dst, author=None):
print "COPY {} to {} in {}".format(src, dst, base)
if dst == "":
raise Exception("Missing destination path")
stdin = file(src)
stdin.seek(0)
return run_and_commit(base, "cat > {0}; chmod +x {0}".format(dst), stdin=stdin)
return run_and_commit(base, "cat > {0}; chmod +x {0}".format(dst), stdin=stdin, author=author)
def add(base, src, dst, author=None):
print "PUSH to {} in {}".format(dst, base)
if src == ".":
tar = subprocess.Popen(["tar", "-c", "."], stdout=subprocess.PIPE).stdout
else:
tar = subprocess.Popen(["curl", src], stdout=subprocess.PIPE).stdout
if dst == "":
raise Exception("Missing argument to push")
return run_and_commit(base, "mkdir -p '{0}' && tar -C '{0}' -x".format(dst), stdin=tar, author=author)
def main():
base=""
maintainer=""
steps = []
try:
for line in sys.stdin.readlines():
@@ -76,23 +89,48 @@ def main():
# Skip comments and empty lines
if line == "" or line[0] == "#":
continue
op, param = line.split(" ", 1)
op, param = line.split(None, 1)
print op.upper() + " " + param
if op == "from":
print "FROM " + param
base = param
steps.append(base)
elif op == "maintainer":
maintainer = param
elif op == "run":
print "RUN " + param
result = run_and_commit(base, param)
result = run_and_commit(base, param, author=maintainer)
steps.append(result)
base = result
print "===> " + base
elif op == "copy":
src, dst = param.split(" ", 1)
result = insert(base, src, dst)
result = insert(base, src, dst, author=maintainer)
steps.append(result)
base = result
print "===> " + base
elif op == "add":
src, dst = param.split(" ", 1)
result = add(base, src, dst, author=maintainer)
steps.append(result)
base=result
print "===> " + base
elif op == "expose":
config = image_config(base)
if config.get("PortSpecs") is None:
config["PortSpecs"] = []
portspec = param.strip()
config["PortSpecs"].append(portspec)
result = run_and_commit(base, "# (nop) expose port {}".format(portspec), author=maintainer, run=config)
steps.append(result)
base=result
print "===> " + base
elif op == "cmd":
config = image_config(base)
cmd = list(json.loads(param))
config["Cmd"] = cmd
result = run_and_commit(base, "# (nop) set default command to '{}'".format(" ".join(cmd)), author=maintainer, run=config)
steps.append(result)
base=result
print "===> " + base
else:
print "Skipping uknown op " + op
except:

View File

@@ -1,11 +1,13 @@
# Start build from a know base image
maintainer Solomon Hykes <solomon@dotcloud.com>
from base:ubuntu-12.10
# Update ubuntu sources
run echo 'deb http://archive.ubuntu.com/ubuntu quantal main universe multiverse' > /etc/apt/sources.list
run apt-get update
# Install system packages
run DEBIAN_FRONTEND=noninteractive apt-get install -y -q git
run DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl
run DEBIAN_FRONTEND=noninteractive apt-get install -y -q golang
run DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl
run DEBIAN_FRONTEND=noninteractive apt-get install -y -q golang
# Insert files from the host (./myscript must be present in the current directory)
copy myscript /usr/local/bin/myscript
copy myscript /usr/local/bin/myscript
push /src

View File

@@ -0,0 +1,3 @@
#!/bin/sh
echo hello, world!

View File

@@ -36,9 +36,9 @@ else
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 |
curl -s http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-latest.tgz |
tar -C /usr/local/bin --strip-components=1 -zxf- \
docker-master/docker
docker-latest/docker
if [ -f /etc/init/dockerd.conf ]
then

61
contrib/mkimage-debian.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/bash
set -e
# these should match the names found at http://www.debian.org/releases/
stableSuite='squeeze'
testingSuite='wheezy'
unstableSuite='sid'
# if suite is equal to this, it gets the "latest" tag
latestSuite="$testingSuite"
variant='minbase'
include='iproute,iputils-ping'
repo="$1"
suite="${2:-$latestSuite}"
mirror="${3:-}" # stick to the default debootstrap mirror if one is not provided
if [ ! "$repo" ]; then
echo >&2 "usage: $0 repo [suite [mirror]]"
echo >&2 " ie: $0 tianon/debian squeeze"
exit 1
fi
target="/tmp/docker-rootfs-debian-$suite-$$-$RANDOM"
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
returnTo="$(pwd -P)"
set -x
# bootstrap
mkdir -p "$target"
sudo debootstrap --verbose --variant="$variant" --include="$include" "$suite" "$target" "$mirror"
cd "$target"
# create the image
img=$(sudo tar -c . | docker import -)
# tag suite
docker tag $img $repo $suite
if [ "$suite" = "$latestSuite" ]; then
# tag latest
docker tag $img $repo latest
fi
# test the image
docker run -i -t $repo:$suite echo success
# unstable's version numbers match testing (since it's mostly just a sandbox for testing), so it doesn't get a version number tag
if [ "$suite" != "$unstableSuite" -a "$suite" != 'unstable' ]; then
# tag the specific version
ver=$(docker run $repo:$suite cat /etc/debian_version)
docker tag $img $repo $ver
fi
# cleanup
cd "$returnTo"
sudo rm -rf "$target"

View File

@@ -4,9 +4,7 @@ import (
"flag"
"fmt"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/term"
"io"
"github.com/dotcloud/docker/utils"
"io/ioutil"
"log"
"os"
@@ -20,7 +18,7 @@ var (
)
func main() {
if docker.SelfPath() == "/sbin/init" {
if utils.SelfPath() == "/sbin/init" {
// Running in init mode
docker.SysInit()
return
@@ -28,6 +26,7 @@ func main() {
// FIXME: Switch d and D ? (to be more sshd like)
flDaemon := flag.Bool("d", false, "Daemon mode")
flDebug := flag.Bool("D", false, "Debug mode")
flAutoRestart := flag.Bool("r", false, "Restart previously running containers")
bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID")
flag.Parse()
@@ -45,12 +44,14 @@ func main() {
flag.Usage()
return
}
if err := daemon(*pidfile); err != nil {
if err := daemon(*pidfile, *flAutoRestart); err != nil {
log.Fatal(err)
os.Exit(-1)
}
} else {
if err := runCommand(flag.Args()); err != nil {
if err := docker.ParseCommands(flag.Args()...); err != nil {
log.Fatal(err)
os.Exit(-1)
}
}
}
@@ -82,7 +83,7 @@ func removePidFile(pidfile string) {
}
}
func daemon(pidfile string) error {
func daemon(pidfile string, autoRestart bool) error {
if err := createPidFile(pidfile); err != nil {
log.Fatal(err)
}
@@ -97,50 +98,10 @@ func daemon(pidfile string) error {
os.Exit(0)
}()
service, err := docker.NewServer()
server, err := docker.NewServer(autoRestart)
if err != nil {
return err
}
return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
}
func runCommand(args []string) error {
// 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 {
options := conn.GetOptions()
if options.RawTerminal &&
term.IsTerminal(int(os.Stdin.Fd())) &&
os.Getenv("NORAW") == "" {
if oldState, err := rcli.SetRawTerminal(); err != nil {
return err
} else {
defer rcli.RestoreTerminal(oldState)
}
}
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 {
return fmt.Errorf("Can't connect to docker daemon. Is 'docker -d' running on this host?")
}
return nil
return docker.ListenAndServe("0.0.0.0:4243", server, true)
}

View File

@@ -44,32 +44,28 @@ clean:
-rm -rf $(BUILDDIR)/*
docs:
-rm -rf $(BUILDDIR)/*
#-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/
cp sources/nginx.conf $(BUILDDIR)/html/
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
@echo "Build finished. The documentation pages are now in $(BUILDDIR)/html."
site:
cp -r website $(BUILDDIR)/
cp -r theme/docker/static/ $(BUILDDIR)/website/
@echo
@echo "The Website pages are in $(BUILDDIR)/site."
connect:
@echo pushing changes to staging site
@cd _build/html/ ; \
@dotcloud list ; \
dotcloud connect dockerwebsite
@echo connecting dotcloud to www.docker.io website, make sure to use user 1
@cd _build/website/ ; \
dotcloud connect dockerwebsite ;
dotcloud list
push:
@cd _build/html/ ; \
@cd _build/website/ ; \
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"

View File

@@ -15,6 +15,7 @@ Installation
* Work in your own fork of the code, we accept pull requests.
* Install sphinx: ``pip install sphinx``
* Install sphinx httpdomain contrib package ``sphinxcontrib-httpdomain``
* If pip is not available you can probably install it using your favorite package manager as **python-pip**
Usage

2
docs/requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
Sphinx==1.1.3
sphinxcontrib-httpdomain==1.1.8

View File

View File

@@ -1 +0,0 @@
docker.io

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
:title: API Documentation
:description: docker documentation
:keywords: docker, ipa, documentation
API's
=============
This following :
.. toctree::
:maxdepth: 3
registry_api
index_search_api
docker_remote_api

View File

@@ -0,0 +1,43 @@
:title: Docker Index documentation
:description: Documentation for docker Index
:keywords: docker, index, api
=======================
Docker Index Search API
=======================
Search
------
.. http:get:: /v1/search
Search the Index given a search term. It accepts :http:method:`get` only.
**Example request**:
.. sourcecode:: http
GET /v1/search?q=search_term HTTP/1.1
Host: example.com
Accept: application/json
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{"query":"search_term",
"num_results": 2,
"results" : [
{"name": "dotcloud/base", "description": "A base ubuntu64 image..."},
{"name": "base2", "description": "A base ubuntu64 image..."},
]
}
:query q: what you want to search for
:statuscode 200: no error
:statuscode 500: server error

View File

@@ -0,0 +1,473 @@
:title: Registry Documentation
:description: Documentation for docker Registry and Registry API
:keywords: docker, registry, api, index
===================
Docker Registry API
===================
.. contents:: Table of Contents
1. The 3 roles
===============
1.1 Index
---------
The Index is responsible for centralizing information about:
- User accounts
- Checksums of the images
- Public namespaces
The Index has different components:
- Web UI
- Meta-data store (comments, stars, list public repositories)
- Authentication service
- Tokenization
The index is authoritative for those information.
We expect that there will be only one instance of the index, run and managed by dotCloud.
1.2 Registry
------------
- It stores the images and the graph for a set of repositories
- It does not have user accounts data
- It has no notion of user accounts or authorization
- It delegates authentication and authorization to the Index Auth service using tokens
- It supports different storage backends (S3, cloud files, local FS)
- It doesnt have a local database
- It will be open-sourced at some point
We expect that there will be multiple registries out there. To help to grasp the context, here are some examples of registries:
- **sponsor registry**: such a registry is provided by a third-party hosting infrastructure as a convenience for their customers and the docker community as a whole. Its costs are supported by the third party, but the management and operation of the registry are supported by dotCloud. It features read/write access, and delegates authentication and authorization to the Index.
- **mirror registry**: such a registry is provided by a third-party hosting infrastructure but is targeted at their customers only. Some mechanism (unspecified to date) ensures that public images are pulled from a sponsor registry to the mirror registry, to make sure that the customers of the third-party provider can “docker pull” those images locally.
- **vendor registry**: such a registry is provided by a software vendor, who wants to distribute docker images. It would be operated and managed by the vendor. Only users authorized by the vendor would be able to get write access. Some images would be public (accessible for anyone), others private (accessible only for authorized users). Authentication and authorization would be delegated to the Index. The goal of vendor registries is to let someone do “docker pull basho/riak1.3” and automatically push from the vendor registry (instead of a sponsor registry); i.e. get all the convenience of a sponsor registry, while retaining control on the asset distribution.
- **private registry**: such a registry is located behind a firewall, or protected by an additional security layer (HTTP authorization, SSL client-side certificates, IP address authorization...). The registry is operated by a private entity, outside of dotClouds control. It can optionally delegate additional authorization to the Index, but it is not mandatory.
.. note::
Mirror registries and private registries which do not use the Index dont even need to run the registry code. They can be implemented by any kind of transport implementing HTTP GET and PUT. Read-only registries can be powered by a simple static HTTP server.
.. note::
The latter implies that while HTTP is the protocol of choice for a registry, multiple schemes are possible (and in some cases, trivial):
- HTTP with GET (and PUT for read-write registries);
- local mount point;
- remote docker addressed through SSH.
The latter would only require two new commands in docker, e.g. “registryget” and “registryput”, wrapping access to the local filesystem (and optionally doing consistency checks). Authentication and authorization are then delegated to SSH (e.g. with public keys).
1.3 Docker
----------
On top of being a runtime for LXC, Docker is the Registry client. It supports:
- Push / Pull on the registry
- Client authentication on the Index
2. Workflow
===========
2.1 Pull
--------
.. image:: /static_files/docker_pull_chart.png
1. Contact the Index to know where I should download “samalba/busybox”
2. Index replies:
a. “samalba/busybox” is on Registry A
b. here are the checksums for “samalba/busybox” (for all layers)
c. token
3. Contact Registry A to receive the layers for “samalba/busybox” (all of them to the base image). Registry A is authoritative for “samalba/busybox” but keeps a copy of all inherited layers and serve them all from the same location.
4. registry contacts index to verify if token/user is allowed to download images
5. Index returns true/false lettings registry know if it should proceed or error out
6. Get the payload for all layers
Its possible to run docker pull \https://<registry>/repositories/samalba/busybox. In this case, docker bypasses the Index. However the security is not guaranteed (in case Registry A is corrupted) because there wont be any checksum checks.
Currently registry redirects to s3 urls for downloads, going forward all downloads need to be streamed through the registry. The Registry will then abstract the calls to S3 by a top-level class which implements sub-classes for S3 and local storage.
Token is only returned when the 'X-Docker-Token' header is sent with request.
Basic Auth is required to pull private repos. Basic auth isn't required for pulling public repos, but if one is provided, it needs to be valid and for an active account.
API (pulling repository foo/bar):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. (Docker -> Index) GET /v1/repositories/foo/bar/images
**Headers**:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
X-Docker-Token: true
**Action**:
(looking up the foo/bar in db and gets images and checksums for that repo (all if no tag is specified, if tag, only checksums for those tags) see part 4.4.1)
2. (Index -> Docker) HTTP 200 OK
**Headers**:
- Authorization: Token signature=123abc,repository=”foo/bar”,access=write
- X-Docker-Endpoints: registry.docker.io [, registry2.docker.io]
**Body**:
Jsonified checksums (see part 4.4.1)
3. (Docker -> Registry) GET /v1/repositories/foo/bar/tags/latest
**Headers**:
Authorization: Token signature=123abc,repository=”foo/bar”,access=write
4. (Registry -> Index) GET /v1/repositories/foo/bar/images
**Headers**:
Authorization: Token signature=123abc,repository=”foo/bar”,access=read
**Body**:
<ids and checksums in payload>
**Action**:
( Lookup token see if they have access to pull.)
If good:
HTTP 200 OK
Index will invalidate the token
If bad:
HTTP 401 Unauthorized
5. (Docker -> Registry) GET /v1/images/928374982374/ancestry
**Action**:
(for each image id returned in the registry, fetch /json + /layer)
.. note::
If someone makes a second request, then we will always give a new token, never reuse tokens.
2.2 Push
--------
.. image:: /static_files/docker_push_chart.png
1. Contact the index to allocate the repository name “samalba/busybox” (authentication required with user credentials)
2. If authentication works and namespace available, “samalba/busybox” is allocated and a temporary token is returned (namespace is marked as initialized in index)
3. Push the image on the registry (along with the token)
4. Registry A contacts the Index to verify the token (token must corresponds to the repository name)
5. Index validates the token. Registry A starts reading the stream pushed by docker and store the repository (with its images)
6. docker contacts the index to give checksums for upload images
.. note::
**Its possible not to use the Index at all!** In this case, a deployed version of the Registry is deployed to store and serve images. Those images are not authentified and the security is not guaranteed.
.. note::
**Index can be replaced!** For a private Registry deployed, a custom Index can be used to serve and validate token according to different policies.
Docker computes the checksums and submit them to the Index at the end of the push. When a repository name does not have checksums on the Index, it means that the push is in progress (since checksums are submitted at the end).
API (pushing repos foo/bar):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. (Docker -> Index) PUT /v1/repositories/foo/bar/
**Headers**:
Authorization: Basic sdkjfskdjfhsdkjfh==
X-Docker-Token: true
**Action**::
- in index, we allocated a new repository, and set to initialized
**Body**::
(The body contains the list of images that are going to be pushed, with empty checksums. The checksums will be set at the end of the push)::
[{“id”: “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”}]
2. (Index -> Docker) 200 Created
**Headers**:
- WWW-Authenticate: Token signature=123abc,repository=”foo/bar”,access=write
- X-Docker-Endpoints: registry.docker.io [, registry2.docker.io]
3. (Docker -> Registry) PUT /v1/images/98765432_parent/json
**Headers**:
Authorization: Token signature=123abc,repository=”foo/bar”,access=write
4. (Registry->Index) GET /v1/repositories/foo/bar/images
**Headers**:
Authorization: Token signature=123abc,repository=”foo/bar”,access=write
**Action**::
- Index:
will invalidate the token.
- Registry:
grants a session (if token is approved) and fetches the images id
5. (Docker -> Registry) PUT /v1/images/98765432_parent/json
**Headers**::
- Authorization: Token signature=123abc,repository=”foo/bar”,access=write
- Cookie: (Cookie provided by the Registry)
6. (Docker -> Registry) PUT /v1/images/98765432/json
**Headers**:
Cookie: (Cookie provided by the Registry)
7. (Docker -> Registry) PUT /v1/images/98765432_parent/layer
**Headers**:
Cookie: (Cookie provided by the Registry)
8. (Docker -> Registry) PUT /v1/images/98765432/layer
**Headers**:
X-Docker-Checksum: sha256:436745873465fdjkhdfjkgh
9. (Docker -> Registry) PUT /v1/repositories/foo/bar/tags/latest
**Headers**:
Cookie: (Cookie provided by the Registry)
**Body**:
“98765432”
10. (Docker -> Index) PUT /v1/repositories/foo/bar/images
**Headers**:
Authorization: Basic 123oislifjsldfj==
X-Docker-Endpoints: registry1.docker.io (no validation on this right now)
**Body**:
(The image, ids, tags and checksums)
[{“id”: “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”,
“checksum”: “b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087”}]
**Return** HTTP 204
.. note::
If push fails and they need to start again, what happens in the index, there will already be a record for the namespace/name, but it will be initialized. Should we allow it, or mark as name already used? One edge case could be if someone pushes the same thing at the same time with two different shells.
If it's a retry on the Registry, Docker has a cookie (provided by the registry after token validation). So the Index wont have to provide a new token.
3. How to use the Registry in standalone mode
=============================================
The Index has two main purposes (along with its fancy social features):
- Resolve short names (to avoid passing absolute URLs all the time)
- username/projectname -> \https://registry.docker.io/users/<username>/repositories/<projectname>/
- team/projectname -> \https://registry.docker.io/team/<team>/repositories/<projectname>/
- Authenticate a user as a repos owner (for a central referenced repository)
3.1 Without an Index
--------------------
Using the Registry without the Index can be useful to store the images on a private network without having to rely on an external entity controlled by dotCloud.
In this case, the registry will be launched in a special mode (--standalone? --no-index?). In this mode, the only thing which changes is that Registry will never contact the Index to verify a token. It will be the Registry owner responsibility to authenticate the user who pushes (or even pulls) an image using any mechanism (HTTP auth, IP based, etc...).
In this scenario, the Registry is responsible for the security in case of data corruption since the checksums are not delivered by a trusted entity.
As hinted previously, a standalone registry can also be implemented by any HTTP server handling GET/PUT requests (or even only GET requests if no write access is necessary).
3.2 With an Index
-----------------
The Index data needed by the Registry are simple:
- Serve the checksums
- Provide and authorize a Token
In the scenario of a Registry running on a private network with the need of centralizing and authorizing, its easy to use a custom Index.
The only challenge will be to tell Docker to contact (and trust) this custom Index. Docker will be configurable at some point to use a specific Index, itll be the private entity responsibility (basically the organization who uses Docker in a private environment) to maintain the Index and the Dockers configuration among its consumers.
4. The API
==========
The first version of the api is available here: https://github.com/jpetazzo/docker/blob/acd51ecea8f5d3c02b00a08176171c59442df8b3/docs/images-repositories-push-pull.md
4.1 Images
----------
The format returned in the images is not defined here (for layer and json), basically because Registry stores exactly the same kind of information as Docker uses to manage them.
The format of ancestry is a line-separated list of image ids, in age order. I.e. the images parent is on the last line, the parent of the parent on the next-to-last line, etc.; if the image has no parent, the file is empty.
GET /v1/images/<image_id>/layer
PUT /v1/images/<image_id>/layer
GET /v1/images/<image_id>/json
PUT /v1/images/<image_id>/json
GET /v1/images/<image_id>/ancestry
PUT /v1/images/<image_id>/ancestry
4.2 Users
---------
4.2.1 Create a user (Index)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
POST /v1/users
**Body**:
{"email": "sam@dotcloud.com", "password": "toto42", "username": "foobar"'}
**Validation**:
- **username** : min 4 character, max 30 characters, all lowercase no special characters.
- **password**: min 5 characters
**Valid**: return HTTP 200
Errors: HTTP 400 (we should create error codes for possible errors)
- invalid json
- missing field
- wrong format (username, password, email, etc)
- forbidden name
- name already exists
.. note::
A user account will be valid only if the email has been validated (a validation link is sent to the email address).
4.2.2 Update a user (Index)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
PUT /v1/users/<username>
**Body**:
{"password": "toto"}
.. note::
We can also update email address, if they do, they will need to reverify their new email address.
4.2.3 Login (Index)
^^^^^^^^^^^^^^^^^^^
Does nothing else but asking for a user authentication. Can be used to validate credentials. HTTP Basic Auth for now, maybe change in future.
GET /v1/users
**Return**:
- Valid: HTTP 200
- Invalid login: HTTP 401
- Account inactive: HTTP 403 Account is not Active
4.3 Tags (Registry)
-------------------
The Registry does not know anything about users. Even though repositories are under usernames, its just a namespace for the registry. Allowing us to implement organizations or different namespaces per user later, without modifying the Registrys API.
4.3.1 Get all tags
^^^^^^^^^^^^^^^^^^
GET /v1/repositories/<namespace>/<repository_name>/tags
**Return**: HTTP 200
{
"latest": "9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f",
“0.1.1”: “b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087”
}
4.3.2 Read the content of a tag (resolve the image id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
GET /v1/repositories/<namespace>/<repo_name>/tags/<tag>
**Return**:
"9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f"
4.3.3 Delete a tag (registry)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DELETE /v1/repositories/<namespace>/<repo_name>/tags/<tag>
4.4 Images (Index)
------------------
For the Index to “resolve” the repository name to a Registry location, it uses the X-Docker-Endpoints header. In other terms, this requests always add a “X-Docker-Endpoints” to indicate the location of the registry which hosts this repository.
4.4.1 Get the images
^^^^^^^^^^^^^^^^^^^^^
GET /v1/repositories/<namespace>/<repo_name>/images
**Return**: HTTP 200
[{“id”: “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”, “checksum”: “md5:b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087”}]
4.4.2 Add/update the images
^^^^^^^^^^^^^^^^^^^^^^^^^^^
You always add images, you never remove them.
PUT /v1/repositories/<namespace>/<repo_name>/images
**Body**:
[ {“id”: “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”, “checksum”: “sha256:b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087”} ]
**Return** 204
5. Chaining Registries
======================
Its possible to chain Registries server for several reasons:
- Load balancing
- Delegate the next request to another server
When a Registry is a reference for a repository, it should host the entire images chain in order to avoid breaking the chain during the download.
The Index and Registry use this mechanism to redirect on one or the other.
Example with an image download:
On every request, a special header can be returned:
X-Docker-Endpoints: server1,server2
On the next request, the client will always pick a server from this list.
6. Authentication & Authorization
=================================
6.1 On the Index
-----------------
The Index supports both “Basic” and “Token” challenges. Usually when there is a “401 Unauthorized”, the Index replies this::
401 Unauthorized
WWW-Authenticate: Basic realm="auth required",Token
You have 3 options:
1. Provide user credentials and ask for a token
**Header**:
- Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
- X-Docker-Token: true
In this case, along with the 200 response, youll get a new token (if user auth is ok):
If authorization isn't correct you get a 401 response.
If account isn't active you will get a 403 response.
**Response**:
- 200 OK
- X-Docker-Token: Token signature=123abc,repository=”foo/bar”,access=read
2. Provide user credentials only
**Header**:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
3. Provide Token
**Header**:
Authorization: Token signature=123abc,repository=”foo/bar”,access=read
6.2 On the Registry
-------------------
The Registry only supports the Token challenge::
401 Unauthorized
WWW-Authenticate: Token
The only way is to provide a token on “401 Unauthorized” responses::
Authorization: Token signature=123abc,repository=”foo/bar”,access=read
Usually, the Registry provides a Cookie when a Token verification succeeded. Every time the Registry passes a Cookie, you have to pass it back the same cookie.::
200 OK
Set-Cookie: session="wD/J7LqL5ctqw8haL10vgfhrb2Q=?foo=UydiYXInCnAxCi4=&timestamp=RjEzNjYzMTQ5NDcuNDc0NjQzCi4="; Path=/; HttpOnly
Next request::
GET /(...)
Cookie: session="wD/J7LqL5ctqw8haL10vgfhrb2Q=?foo=UydiYXInCnAxCi4=&timestamp=RjEzNjYzMTQ5NDcuNDc0NjQzCi4="

View File

@@ -4,7 +4,7 @@
.. _cli:
Command Line Interface
Overview
======================
Docker Usage
@@ -24,9 +24,10 @@ Available Commands
~~~~~~~~~~~~~~~~~~
.. toctree::
:maxdepth: 1
:maxdepth: 2
command/attach
command/build
command/commit
command/diff
command/export
@@ -46,6 +47,7 @@ Available Commands
command/rm
command/rmi
command/run
command/search
command/start
command/stop
command/tag

View File

@@ -1,3 +1,7 @@
:title: Attach Command
:description: Attach to a running container
:keywords: attach, container, docker, documentation
===========================================
``attach`` -- Attach to a running container
===========================================

View File

@@ -0,0 +1,13 @@
:title: Build Command
:description: Build a new image from the Dockerfile passed via stdin
:keywords: build, docker, container, documentation
========================================================
``build`` -- Build a container from Dockerfile via stdin
========================================================
::
Usage: docker build -
Example: cat Dockerfile | docker build -
Build a new image from the Dockerfile passed via stdin

View File

@@ -1,3 +1,7 @@
:title: Commit Command
:description: Create a new image from a container's changes
:keywords: commit, docker, container, documentation
===========================================================
``commit`` -- Create a new image from a container's changes
===========================================================
@@ -9,3 +13,20 @@
Create a new image from a container's changes
-m="": Commit message
-author="": Author (eg. "John Hannibal Smith <hannibal@a-team.com>"
-run="": Config automatically applied when the image is run. "+`(ex: {"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}')
Full -run example::
{"Hostname": "",
"User": "",
"CpuShares": 0,
"Memory": 0,
"MemorySwap": 0,
"PortSpecs": ["22", "80", "443"],
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": ["FOO=BAR", "FOO2=BAR2"],
"Cmd": ["cat", "-e", "/etc/resolv.conf"],
"Dns": ["8.8.8.8", "8.8.4.4"]}

View File

@@ -1,3 +1,7 @@
:title: Diff Command
:description: Inspect changes on a container's filesystem
:keywords: diff, docker, container, documentation
=======================================================
``diff`` -- Inspect changes on a container's filesystem
=======================================================

View File

@@ -1,3 +1,7 @@
:title: Export Command
:description: Export the contents of a filesystem as a tar archive
:keywords: export, docker, container, documentation
=================================================================
``export`` -- Stream the contents of a container as a tar archive
=================================================================

View File

@@ -1,3 +1,7 @@
:title: History Command
:description: Show the history of an image
:keywords: history, docker, container, documentation
===========================================
``history`` -- Show the history of an image
===========================================

View File

@@ -1,3 +1,7 @@
:title: Images Command
:description: List images
:keywords: images, docker, container, documentation
=========================
``images`` -- List images
=========================
@@ -10,3 +14,13 @@
-a=false: show all images
-q=false: only show numeric IDs
-viz=false: output in graphviz format
Displaying images visually
--------------------------
::
docker images -viz | dot -Tpng -o docker.png
.. image:: images/docker_images.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -1,3 +1,7 @@
:title: Import Command
:description: Create a new filesystem image from the contents of a tarball
:keywords: import, tarball, docker, url, documentation
==========================================================================
``import`` -- Create a new filesystem image from the contents of a tarball
==========================================================================

View File

@@ -1,3 +1,7 @@
:title: Info Command
:description: Display system-wide information.
:keywords: info, docker, information, documentation
===========================================
``info`` -- Display system-wide information
===========================================

View File

@@ -1,3 +1,7 @@
:title: Inspect Command
:description: Return low-level information on a container
:keywords: inspect, container, docker, documentation
==========================================================
``inspect`` -- Return low-level information on a container
==========================================================

View File

@@ -1,3 +1,7 @@
:title: Kill Command
:description: Kill a running container
:keywords: kill, container, docker, documentation
====================================
``kill`` -- Kill a running container
====================================

View File

@@ -1,3 +1,7 @@
:title: Login Command
:description: Register or Login to the docker registry server
:keywords: login, docker, documentation
============================================================
``login`` -- Register or Login to the docker registry server
============================================================

View File

@@ -1,3 +1,7 @@
:title: Logs Command
:description: Fetch the logs of a container
:keywords: logs, container, docker, documentation
=========================================
``logs`` -- Fetch the logs of a container
=========================================

View File

@@ -1,3 +1,7 @@
:title: Port Command
:description: Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
:keywords: port, docker, container, documentation
=========================================================================
``port`` -- Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
=========================================================================

View File

@@ -1,3 +1,7 @@
:title: Ps Command
:description: List containers
:keywords: ps, docker, documentation, container
=========================
``ps`` -- List containers
=========================

View File

@@ -1,3 +1,7 @@
:title: Pull Command
:description: Pull an image or a repository from the registry
:keywords: pull, image, repo, repository, documentation, docker
=========================================================================
``pull`` -- Pull an image or a repository from the docker registry server
=========================================================================

View File

@@ -1,3 +1,7 @@
:title: Push Command
:description: Push an image or a repository to the registry
:keywords: push, docker, image, repository, documentation, repo
=======================================================================
``push`` -- Push an image or a repository to the docker registry server
=======================================================================

View File

@@ -1,3 +1,7 @@
:title: Restart Command
:description: Restart a running container
:keywords: restart, container, docker, documentation
==========================================
``restart`` -- Restart a running container
==========================================

View File

@@ -1,3 +1,7 @@
:title: Rm Command
:description: Remove a container
:keywords: remove, container, docker, documentation, rm
============================
``rm`` -- Remove a container
============================

View File

@@ -1,3 +1,7 @@
:title: Rmi Command
:description: Remove an image
:keywords: rmi, remove, image, docker, documentation
==========================
``rmi`` -- Remove an image
==========================

View File

@@ -1,3 +1,7 @@
:title: Run Command
:description: Run a command in a new container
:keywords: run, container, docker, documentation
===========================================
``run`` -- Run a command in a new container
===========================================
@@ -9,6 +13,7 @@
Run a command in a new container
-a=map[]: Attach to stdin, stdout or stderr.
-c=0: CPU shares (relative weight)
-d=false: Detached mode: leave the container running in the background
-e=[]: Set environment variables
-h="": Container host name
@@ -17,3 +22,6 @@
-p=[]: Map a network port to the container
-t=false: Allocate a pseudo-tty
-u="": Username or UID
-d=[]: Set custom dns servers for the container
-v=[]: Creates a new volume and mounts it at the specified path.
-volumes-from="": Mount all volumes from the given container.

View File

@@ -0,0 +1,14 @@
:title: Search Command
:description: Searches for the TERM parameter on the Docker index and prints out a list of repositories that match.
:keywords: search, docker, image, documentation
===================================================================
``search`` -- Search for an image in the docker index
===================================================================
::
Usage: docker search TERM
Searches for the TERM parameter on the Docker index and prints out a list of repositories
that match.

View File

@@ -1,3 +1,7 @@
:title: Start Command
:description: Start a stopped container
:keywords: start, docker, container, documentation
======================================
``start`` -- Start a stopped container
======================================

View File

@@ -1,3 +1,7 @@
:title: Stop Command
:description: Stop a running container
:keywords: stop, container, docker, documentation
====================================
``stop`` -- Stop a running container
====================================

View File

@@ -1,3 +1,7 @@
:title: Tag Command
:description: Tag an image into a repository
:keywords: tag, docker, image, repository, documentation, repo
=========================================
``tag`` -- Tag an image into a repository
=========================================

View File

@@ -1,3 +1,7 @@
:title: Version Command
:description:
:keywords: version, docker, documentation
==================================================
``version`` -- Show the docker version information
==================================================

View File

@@ -1,3 +1,7 @@
:title: Wait Command
:description: Block until a container stops, then print its exit code.
:keywords: wait, docker, container, documentation
===================================================================
``wait`` -- Block until a container stops, then print its exit code
===================================================================

View File

@@ -1,6 +1,6 @@
:title: docker documentation
:title: Commands
:description: -- todo: change me
:keywords: todo: change me
:keywords: todo, commands, command line, help, docker, documentation
Commands
@@ -9,8 +9,33 @@ Commands
Contents:
.. toctree::
:maxdepth: 2
:maxdepth: 1
basics
workingwithrepository
cli
cli
attach <command/attach>
build <command/build>
commit <command/commit>
diff <command/diff>
export <command/export>
history <command/history>
images <command/images>
import <command/import>
info <command/info>
inspect <command/inspect>
kill <command/kill>
login <command/login>
logs <command/logs>
port <command/port>
ps <command/ps>
pull <command/pull>
push <command/push>
restart <command/restart>
rm <command/rm>
rmi <command/rmi>
run <command/run>
search <command/search>
start <command/start>
stop <command/stop>
tag <command/tag>
version <command/version>
wait <command/wait>

View File

@@ -1,42 +0,0 @@
.. _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>

View File

@@ -1,4 +1,4 @@
:title: Building blocks
:title: Building Blocks
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
@@ -12,7 +12,7 @@ Images
------
An original container image. These are stored on disk and are comparable with what you normally expect from a stopped virtual machine image. Images are stored (and retrieved from) repository
Images are stored on your local file system under /var/lib/docker/images
Images are stored on your local file system under /var/lib/docker/graph
.. _containers:

View File

@@ -1,128 +1,8 @@
:title: Introduction
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
:keywords: containers, lxc, concepts, explanation, docker, documentation
: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
^^^^^^^^
This document has been moved to :ref:`introduction`, please update your bookmarks.

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

@@ -1,6 +1,6 @@
:title: docker documentation
:title: Concepts
:description: -- todo: change me
:keywords: todo: change me
:keywords: concepts, documentation, docker, containers
@@ -12,6 +12,6 @@ Contents:
.. toctree::
:maxdepth: 1
introduction
../index
buildingblocks

View File

@@ -2,8 +2,6 @@
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
Introduction
============
@@ -20,7 +18,7 @@ Docker is a great building block for automating distributed systems: large-scale
- **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
.. image:: images/lego_docker.jpg
What is a Standard Container?

View File

@@ -25,7 +25,7 @@ import sys, os
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
extensions = ['sphinxcontrib.httpdomain']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -41,7 +41,7 @@ html_add_permalinks = None
# The master toctree document.
master_doc = 'index'
master_doc = 'toctree'
# General information about the project.
project = u'Docker'

View File

@@ -1,3 +1,7 @@
:title: Contribution Guidelines
:description: Contribution guidelines: create issues, convetions, pull requests
:keywords: contributing, docker, documentation, help, guideline
Contributing to Docker
======================

View File

@@ -16,7 +16,7 @@ Instructions that have been verified to work on Ubuntu 12.10,
mkdir -p $GOPATH/src/github.com/dotcloud
cd $GOPATH/src/github.com/dotcloud
git clone git@github.com:dotcloud/docker.git
git clone git://github.com/dotcloud/docker.git
cd docker
go get -v github.com/dotcloud/docker/...

View File

@@ -0,0 +1,53 @@
:title: Sharing data between 2 couchdb databases
:description: Sharing data between 2 couchdb databases
:keywords: docker, example, package installation, networking, couchdb, data volumes
.. _running_couchdb_service:
Create a CouchDB service
========================
.. include:: example_header.inc
Here's an example of using data volumes to share the same data between 2 couchdb containers.
This could be used for hot upgrades, testing different versions of couchdb on the same data, etc.
Create first database
---------------------
Note that we're marking /var/lib/couchdb as a data volume.
.. code-block:: bash
COUCH1=$(docker run -d -v /var/lib/couchdb shykes/couchdb:2013-05-03)
Add data to the first database
------------------------------
We're assuming your docker host is reachable at `localhost`. If not, replace `localhost` with the public IP of your docker host.
.. code-block:: bash
HOST=localhost
URL="http://$HOST:$(docker port $COUCH1 5984)/_utils/"
echo "Navigate to $URL in your browser, and use the couch interface to add data"
Create second database
----------------------
This time, we're requesting shared access to $COUCH1's volumes.
.. code-block:: bash
COUCH2=$(docker run -d -volumes-from $COUCH1) shykes/couchdb:2013-05-03)
Browse data on the second database
----------------------------------
.. code-block:: bash
HOST=localhost
URL="http://$HOST:$(docker port $COUCH2 5984)/_utils/"
echo "Navigate to $URL in your browser. You should see the same data as in the first database!"
Congratulations, you are running 2 Couchdb containers, completely isolated from each other *except* for their data.

View File

@@ -18,3 +18,4 @@ Contents:
python_web_app
running_redis_service
running_ssh_service
couchdb_data_volumes

View File

@@ -40,7 +40,7 @@ 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)
BUILD_IMG=$(docker commit $BUILD_JOB _/builds/github.com/shykes/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.

View File

@@ -1,3 +1,7 @@
:title: FAQ
:description: Most frequently asked questions.
:keywords: faq, questions, documentation, docker
FAQ
===
@@ -15,7 +19,7 @@ Most frequently asked questions.
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.
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_ installation guides.
4. **How do containers compare to virtual machines?**
@@ -35,8 +39,8 @@ Most frequently asked questions.
* `Ask questions on Stackoverflow`_
* `Join the conversation on Twitter`_
.. _Windows: ../documentation/installation/windows.html
.. _MacOSX: ../documentation/installation/macos.html
.. _Windows: ../installation/windows/
.. _MacOSX: ../installation/vagrant/
.. _the repo: http://www.github.com/dotcloud/docker
.. _IRC\: docker on freenode: irc://chat.freenode.net#docker
.. _Github: http://www.github.com/dotcloud/docker

View File

@@ -1,21 +1,127 @@
:title: docker documentation
:description: docker documentation
:keywords:
:title: Introduction
:description: An introduction to docker and standard containers?
:keywords: containers, lxc, concepts, explanation
Documentation
=============
.. _introduction:
This documentation has the following resources:
Introduction
============
.. toctree::
:maxdepth: 1
Docker - The Linux container runtime
------------------------------------
concepts/index
installation/index
examples/index
contributing/index
commandline/index
faq
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.
.. image:: http://www.docker.io/_static/lego_docker.jpg
- **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:: concepts/images/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
^^^^^^^^

View File

@@ -0,0 +1,27 @@
:title: Index Environment Variable
:description: Setting this environment variable on the docker server will change the URL docker index.
:keywords: docker, index environment variable, documentation
=================================
Docker Index Environment Variable
=================================
Variable
--------
.. code-block:: sh
DOCKER_INDEX_URL
Setting this environment variable on the docker server will change the URL docker index.
This address is used in commands such as ``docker login``, ``docker push`` and ``docker pull``.
The docker daemon doesn't need to be restarted for this parameter to take effect.
Example
-------
.. code-block:: sh
docker -d &
export DOCKER_INDEX_URL="https://index.docker.io"

View File

@@ -1,3 +1,7 @@
:title: Installation on Amazon EC2
:description: Docker installation on Amazon EC2 with a single vagrant command. Vagrant 1.1 or higher is required.
:keywords: amazon ec2, virtualization, cloud, docker, documentation, installation
Amazon EC2
==========
@@ -68,7 +72,7 @@ Docker can now be installed on Amazon EC2 with a single vagrant command. Vagrant
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
If you have an advanced AWS setup, you might want to have a look at https://github.com/mitchellh/vagrant-aws
7. Connect to your machine

View File

@@ -1,3 +1,7 @@
:title: Installation on Arch Linux
:description: Docker installation on Arch Linux.
:keywords: arch linux, virtualization, docker, documentation, installation
.. _arch_linux:
Arch Linux

View File

@@ -1,3 +1,7 @@
:title: Installation from Binaries
:description: This instruction set is meant for hackers who want to try out Docker on a variety of environments.
:keywords: binaries, installation, docker, documentation, linux
.. _binaries:
Binaries
@@ -5,49 +9,59 @@ Binaries
**Please note this project is currently under heavy development. It should not be used in production.**
**This instruction set is meant for hackers who want to try out Docker on a variety of environments.**
Right now, the officially supported distributions are:
- Ubuntu 12.04 (precise LTS) (64-bit)
- Ubuntu 12.10 (quantal) (64-bit)
- :ref:`ubuntu_precise`
- :ref:`ubuntu_raring`
Install dependencies:
---------------------
But we know people have had success running it under
::
- Debian
- Suse
- :ref:`arch_linux`
sudo apt-get install lxc bsdtar
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.
Dependencies:
-------------
Install the docker binary:
* 3.8 Kernel
* AUFS filesystem support
* lxc
* bsdtar
::
wget http://get.docker.io/builds/Linux/x86_64/docker-master.tgz
tar -xf docker-master.tgz
sudo cp ./docker-master /usr/local/bin
Get the docker binary:
----------------------
Note: docker currently only supports 64-bit Linux hosts.
.. code-block:: bash
wget http://get.docker.io/builds/Linux/x86_64/docker-latest.tgz
tar -xf docker-latest.tgz
Run the docker daemon
---------------------
::
.. code-block:: bash
sudo docker -d &
# start the docker in daemon mode from the directory you unpacked
sudo ./docker -d &
Run your first container!
-------------------------
::
.. code-block:: bash
docker run -i -t ubuntu /bin/bash
# check your docker version
./docker version
# run a container and open an interactive shell in the container
./docker run -i -t ubuntu /bin/bash
Continue with the :ref:`hello_world` example.
Continue with the :ref:`hello_world` example.

View File

@@ -1,6 +1,6 @@
:title: docker documentation
:title: Documentation
:description: -- todo: change me
:keywords: todo: change me
:keywords: todo, docker, documentation, installation, OS support
@@ -14,8 +14,10 @@ Contents:
ubuntulinux
binaries
archlinux
vagrant
windows
amazon
rackspace
archlinux
upgrading
kernel

View File

@@ -0,0 +1,115 @@
:title: Kernel Requirements
:description: Kernel supports
:keywords: kernel requirements, kernel support, docker, installation, cgroups, namespaces
.. _kernel:
Kernel Requirements
===================
In short, Docker has the following kernel requirements:
- Linux version 3.8 or above.
- `AUFS support <http://aufs.sourceforge.net/>`_.
- Cgroups and namespaces must be enabled.
The officially supported kernel is the one recommended by the
:ref:`ubuntu_linux` installation path. It is the one that most developers
will use, and the one that receives the most attention from the core
contributors. If you decide to go with a different kernel and hit a bug,
please try to reproduce it with the official kernels first.
If you cannot or do not want to use the "official" kernels,
here is some technical background about the features (both optional and
mandatory) that docker needs to run successfully.
Linux version 3.8 or above
--------------------------
Kernel versions 3.2 to 3.5 are not stable when used with docker.
In some circumstances, you will experience kernel "oopses", or even crashes.
The symptoms include:
- a container being killed in the middle of an operation (e.g. an ``apt-get``
command doesn't complete);
- kernel messages including mentioning calls to ``mntput`` or
``d_hash_and_lookup``;
- kernel crash causing the machine to freeze for a few minutes, or even
completely.
While it is still possible to use older kernels for development, it is
really not advised to do so.
Docker checks the kernel version when it starts, and emits a warning if it
detects something older than 3.8.
See issue `#407 <https://github.com/dotcloud/docker/issues/407>`_ for details.
AUFS support
------------
Docker currently relies on AUFS, an unioning filesystem.
While AUFS is included in the kernels built by the Debian and Ubuntu
distributions, is not part of the standard kernel. This means that if
you decide to roll your own kernel, you will have to patch your
kernel tree to add AUFS. The process is documented on
`AUFS webpage <http://aufs.sourceforge.net/>`_.
Cgroups and namespaces
----------------------
You need to enable namespaces and cgroups, to the extend of what is needed
to run LXC containers. Technically, while namespaces have been introduced
in the early 2.6 kernels, we do not advise to try any kernel before 2.6.32
to run LXC containers. Note that 2.6.32 has some documented issues regarding
network namespace setup and teardown; those issues are not a risk if you
run containers in a private environment, but can lead to denial-of-service
attacks if you want to run untrusted code in your containers. For more details,
see `[LP#720095 <https://bugs.launchpad.net/ubuntu/+source/linux/+bug/720095>`_.
Kernels 2.6.38, and every version since 3.2, have been deployed successfully
to run containerized production workloads. Feature-wise, there is no huge
improvement between 2.6.38 and up to 3.6 (as far as docker is concerned!).
Extra Cgroup Controllers
------------------------
Most control groups can be enabled or disabled individually. For instance,
you can decide that you do not want to compile support for the CPU or memory
controller. In some cases, the feature can be enabled or disabled at boot
time. It is worth mentioning that some distributions (like Debian) disable
"expensive" features, like the memory controller, because they can have
a significant performance impact.
In the specific case of the memory cgroup, docker will detect if the cgroup
is available or not. If it's not, it will print a warning, and it won't
use the feature. If you want to enable that feature -- read on!
Memory and Swap Accounting on Debian/Ubuntu
-------------------------------------------
If you use Debian or Ubuntu kernels, and want to enable memory and swap
accounting, you must add the following command-line parameters to your kernel::
cgroup_enable=memory swapaccount
On Debian or Ubuntu systems, if you use the default GRUB bootloader, you can
add those parameters by editing ``/etc/default/grub`` and extending
``GRUB_CMDLINE_LINUX``. Look for the following line::
GRUB_CMDLINE_LINUX=""
And replace it by the following one::
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount"
Then run ``update-grub``, and reboot.

View File

@@ -0,0 +1,95 @@
:title: Rackspace Cloud Installation
:description: Installing Docker on Ubuntu proviced by Rackspace
:keywords: Rackspace Cloud, installation, docker, linux, ubuntu
===============
Rackspace Cloud
===============
Please note this is a community contributed installation path. The only 'official' installation is using the
:ref:`ubuntu_linux` installation path. This version may sometimes be out of date.
Installing Docker on Ubuntu proviced by Rackspace is pretty straightforward, and you should mostly be able to follow the
:ref:`ubuntu_linux` installation guide.
**However, there is one caveat:**
If you are using any linux not already shipping with the 3.8 kernel you will need to install it. And this is a little
more difficult on Rackspace.
Rackspace boots their servers using grub's menu.lst and does not like non 'virtual' packages (e.g. xen compatible)
kernels there, although they do work. This makes ``update-grub`` to not have the expected result, and you need to
set the kernel manually.
**Do not attempt this on a production machine!**
.. code-block:: bash
# update apt
apt-get update
# install the new kernel
apt-get install linux-generic-lts-raring
Great, now you have kernel installed in /boot/, next is to make it boot next time.
.. code-block:: bash
# find the exact names
find /boot/ -name '*3.8*'
# this should return some results
Now you need to manually edit /boot/grub/menu.lst, you will find a section at the bottom with the existing options.
Copy the top one and substitute the new kernel into that. Make sure the new kernel is on top, and double check kernel
and initrd point to the right files.
Make special care to double check the kernel and initrd entries.
.. code-block:: bash
# now edit /boot/grub/menu.lst
vi /boot/grub/menu.lst
It will probably look something like this:
::
## ## End Default Options ##
title Ubuntu 12.04.2 LTS, kernel 3.8.x generic
root (hd0)
kernel /boot/vmlinuz-3.8.0-19-generic root=/dev/xvda1 ro quiet splash console=hvc0
initrd /boot/initrd.img-3.8.0-19-generic
title Ubuntu 12.04.2 LTS, kernel 3.2.0-38-virtual
root (hd0)
kernel /boot/vmlinuz-3.2.0-38-virtual root=/dev/xvda1 ro quiet splash console=hvc0
initrd /boot/initrd.img-3.2.0-38-virtual
title Ubuntu 12.04.2 LTS, kernel 3.2.0-38-virtual (recovery mode)
root (hd0)
kernel /boot/vmlinuz-3.2.0-38-virtual root=/dev/xvda1 ro quiet splash single
initrd /boot/initrd.img-3.2.0-38-virtual
Reboot server (either via command line or console)
.. code-block:: bash
# reboot
Verify the kernel was updated
.. code-block:: bash
uname -a
# Linux docker-12-04 3.8.0-19-generic #30~precise1-Ubuntu SMP Wed May 1 22:26:36 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# nice! 3.8.
Now you can finish with the :ref:`ubuntu_linux` instructions.

View File

@@ -1,3 +1,7 @@
:title: Requirements and Installation on Ubuntu Linux
:description: Please note this project is currently under heavy development. It should not be used in production.
:keywords: Docker, Docker documentation, requirements, virtualbox, vagrant, git, ssh, putty, cygwin, linux
.. _ubuntu_linux:
Ubuntu Linux
@@ -5,20 +9,39 @@ Ubuntu Linux
**Please note this project is currently under heavy development. It should not be used in production.**
Right now, the officially supported distribution are:
Right now, the officially supported distributions are:
- :ref:`ubuntu_precise`
- :ref:`ubuntu_raring`
Docker has the following dependencies
* Linux kernel 3.8
* AUFS file system support (we are working on BTRFS support as an alternative)
.. _ubuntu_precise:
Ubuntu Precise 12.04 (LTS) (64-bit)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This installation path should work at all times.
- Ubuntu 12.04 (precise LTS) (64-bit)
- Ubuntu 12.10 (quantal) (64-bit)
Dependencies
------------
The linux-image-extra package is only needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.
**Linux kernel 3.8**
Due to a bug in LXC docker works best on the 3.8 kernel. Precise comes with a 3.2 kernel, so we need to upgrade it. The kernel we install comes with AUFS built in.
.. code-block:: bash
sudo apt-get install linux-image-extra-`uname -r`
# install the backported kernel
sudo apt-get update && sudo apt-get install linux-image-3.8.0-19-generic
# reboot
sudo reboot
Installation
@@ -28,26 +51,66 @@ Docker is available as a Ubuntu PPA (Personal Package Archive),
`hosted on launchpad <https://launchpad.net/~dotcloud/+archive/lxc-docker>`_
which makes installing Docker on Ubuntu very easy.
.. code-block:: bash
# Add the PPA sources to your apt sources list.
sudo sh -c "echo 'deb http://ppa.launchpad.net/dotcloud/lxc-docker/ubuntu precise main' > /etc/apt/sources.list.d/lxc-docker.list"
Add the custom package sources to your apt sources list. Copy and paste the following lines at once.
# Update your sources, you will see a warning.
sudo apt-get update
# Install, you will see another warning that the package cannot be authenticated. Confirm install.
sudo apt-get install lxc-docker
Verify it worked
.. code-block:: bash
sudo sh -c "echo 'deb http://ppa.launchpad.net/dotcloud/lxc-docker/ubuntu precise main' >> /etc/apt/sources.list"
# download the base 'ubuntu' container and run bash inside it while setting up an interactive shell
docker run -i -t ubuntu /bin/bash
# type 'exit' to exit
Update your sources. You will see a warning that GPG signatures cannot be verified.
**Done!**, now continue with the :ref:`hello_world` example.
.. _ubuntu_raring:
Ubuntu Raring 13.04 (64 bit)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dependencies
------------
**AUFS filesystem support**
Ubuntu Raring already comes with the 3.8 kernel, so we don't need to install it. However, not all systems
have AUFS filesystem support enabled, so we need to install it.
.. code-block:: bash
sudo apt-get update
sudo apt-get install linux-image-extra-`uname -r`
Installation
------------
Docker is available as a Ubuntu PPA (Personal Package Archive),
`hosted on launchpad <https://launchpad.net/~dotcloud/+archive/lxc-docker>`_
which makes installing Docker on Ubuntu very easy.
Now install it, you will see another warning that the package cannot be authenticated. Confirm install.
Add the custom package sources to your apt sources list.
.. code-block:: bash
# add the sources to your apt
sudo add-apt-repository ppa:dotcloud/lxc-docker
# update
sudo apt-get update
# install
sudo apt-get install lxc-docker
@@ -55,7 +118,10 @@ Verify it worked
.. code-block:: bash
docker
# download the base 'ubuntu' container and run bash inside it while setting up an interactive shell
docker run -i -t ubuntu /bin/bash
# type exit to exit
**Done!**, now continue with the :ref:`hello_world` example.

View File

@@ -1,41 +1,60 @@
:title: Upgrading
:description: These instructions are for upgrading Docker
:keywords: Docker, Docker documentation, upgrading docker, upgrade
.. _upgrading:
Upgrading
============
These instructions are for upgrading your Docker binary for when you had a custom (non package manager) installation.
If you istalled docker using apt-get, use that to upgrade.
**These instructions are for upgrading Docker**
Get the latest docker binary:
After normal installation
-------------------------
::
If you installed Docker normally using apt-get or used Vagrant, use apt-get to upgrade.
wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz
.. code-block:: bash
# update your sources list
sudo apt-get update
# install the latest
sudo apt-get install lxc-docker
After manual installation
-------------------------
Unpack it to your current dir
::
tar -xf docker-master.tgz
If you installed the Docker binary
Stop your current daemon. How you stop your daemon depends on how you started it.
.. code-block:: bash
- If you started the daemon manually (``sudo docker -d``), you can just kill the process: ``killall docker``
- If the process was started using upstart (the ubuntu startup daemon), you may need to use that to stop it
# kill the running docker daemon
killall docker
Start docker in daemon mode (-d) and disconnect (&) starting ./docker will start the version in your current dir rather
than the one in your PATH.
.. code-block:: bash
Now start the daemon
# get the latest binary
wget http://get.docker.io/builds/Linux/x86_64/docker-latest.tgz
::
.. code-block:: bash
# Unpack it to your current dir
tar -xf docker-latest.tgz
Start docker in daemon mode (-d) and disconnect (&) starting ./docker will start the version in your current dir rather than a version which
might reside in your path.
.. code-block:: bash
# start the new version
sudo ./docker -d &
Alternatively you can replace the docker binary in ``/usr/local/bin``
Alternatively you can replace the docker binary in ``/usr/local/bin``

View File

@@ -1,14 +1,13 @@
:title: Using Vagrant (Mac, Linux)
:description: This guide will setup a new virtualbox virtual machine with docker installed on your computer.
:keywords: Docker, Docker documentation, virtualbox, vagrant, git, ssh, putty, cygwin
.. _install_using_vagrant:
Using Vagrant
=============
Using Vagrant (Mac, Linux)
==========================
Please note this is a community contributed installation path. The only 'official' installation is using the
:ref:`ubuntu_linux` installation path. This version may sometimes be out of date.
**Requirements:**
This guide will setup a new virtual machine with docker installed on your computer. This works on most operating
This guide will setup a new virtualbox virtual machine with docker installed on your computer. This works on most operating
systems, including MacOX, Windows, Linux, FreeBSD and others. If you can install these and have at least 400Mb RAM
to spare you should be good.

View File

@@ -3,8 +3,8 @@
:keywords: Docker, Docker documentation, Windows, requirements, virtualbox, vagrant, git, ssh, putty, cygwin
Windows (with Vagrant)
======================
Using Vagrant (Windows)
=======================
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

22
docs/sources/toctree.rst Normal file
View File

@@ -0,0 +1,22 @@
:title: Documentation
:description: -- todo: change me
:keywords: todo, docker, documentation, installation, usage, examples, contributing, faq, command line, concepts
Documentation
=============
This documentation has the following resources:
.. toctree::
:titlesonly:
concepts/index
installation/index
use/index
examples/index
commandline/index
contributing/index
api/index
faq
.. image:: concepts/images/lego_docker.jpg

View File

@@ -1,6 +1,6 @@
:title: Base commands
:title: Basic Commands
:description: Common usage and commands
:keywords: Examples, Usage
:keywords: Examples, Usage, basic commands, docker, documentation, examples
The basics
@@ -76,8 +76,8 @@ Expose a service on a TCP port
echo "Daemon received: $(docker logs $JOB)"
Committing (saving) an image
-----------------------------
Committing (saving) a container state
-------------------------------------
Save your containers state to a container image, so the state can be re-used.

View File

@@ -0,0 +1,187 @@
:title: Docker Builder
:description: Docker Builder specifes a simple DSL which allows you to automate the steps you would normally manually take to create an image.
:keywords: builder, docker, Docker Builder, automation, image creation
==============
Docker Builder
==============
.. contents:: Table of Contents
Docker Builder specifes a simple DSL which allows you to automate the steps you
would normally manually take to create an image. Docker Build will run your
steps and commit them along the way, giving you a final image.
1. Usage
========
To use Docker Builder, assemble the steps into a text file (commonly referred to
as a Dockerfile) and supply this to `docker build` on STDIN, like so:
``docker build < Dockerfile``
Docker will run your steps one-by-one, committing the result if necessary,
before finally outputting the ID of your new image.
2. Format
=========
The Dockerfile format is quite simple:
``instruction arguments``
The Instruction is not case-sensitive, however convention is for them to be
UPPERCASE in order to distinguish them from arguments more easily.
Dockerfiles are evaluated in order, therefore the first instruction must be
`FROM` in order to specify the base image from which you are building.
Docker will ignore lines in Dockerfiles prefixed with "`#`", so you may add
comment lines. A comment marker in the rest of the line will be treated as an
argument.
2. Instructions
===============
Docker builder comes with a set of instructions, described below.
2.1 FROM
--------
``FROM <image>``
The `FROM` instruction sets the base image for subsequent instructions. As such,
a valid Dockerfile must have it as its first instruction.
`FROM` can be included multiple times within a single Dockerfile in order to
create multiple images. Simply make a note of the last image id output by the
commit before each new `FROM` command.
2.2 MAINTAINER
--------------
``MAINTAINER <name>``
The `MAINTAINER` instruction allows you to set the Author field of the generated
images.
2.3 RUN
-------
``RUN <command>``
The `RUN` instruction will execute any commands on the current image and commit
the results. The resulting committed image will be used for the next step in the
Dockerfile.
Layering `RUN` instructions and generating commits conforms to the
core concepts of Docker where commits are cheap and containers can be created
from any point in an image's history, much like source control.
2.4 CMD
-------
``CMD <command>``
The `CMD` instruction sets the command to be executed when running the image.
This is functionally equivalent to running
`docker commit -run '{"Cmd": <command>}'` outside the builder.
.. note::
Don't confuse `RUN` with `CMD`. `RUN` actually runs a command and commits
the result; `CMD` does not execute anything at build time, but specifies the
intended command for the image.
2.5 EXPOSE
----------
``EXPOSE <port> [<port>...]``
The `EXPOSE` instruction sets ports to be publicly exposed when running the
image. This is functionally equivalent to running
`docker commit -run '{"PortSpecs": ["<port>", "<port2>"]}'` outside the builder.
2.6 ENV
-------
``ENV <key> <value>``
The `ENV` instruction sets the environment variable `<key>` to the value
`<value>`. This value will be passed to all future ``RUN`` instructions. This is
functionally equivalent to prefixing the command with `<key>=<value>`
.. note::
The environment variables will persist when a container is run from the resulting image.
2.7 INSERT
----------
``INSERT <file url> <path>``
The `INSERT` instruction will download the file from the given url to the given
path within the image. It is similar to `RUN curl -o <path> <url>`, assuming
curl was installed within the image.
.. note::
The path must include the file name.
.. note::
This instruction has temporarily disabled
3. Dockerfile Examples
======================
.. code-block:: bash
# Nginx
#
# VERSION 0.0.1
FROM ubuntu
MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com"
# make sure the package repository is up to date
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y inotify-tools nginx apache2 openssh-server
INSERT https://raw.github.com/creack/docker-vps/master/nginx-wrapper.sh /usr/sbin/nginx-wrapper
.. code-block:: bash
# Firefox over VNC
#
# VERSION 0.3
FROM ubuntu
# make sure the package repository is up to date
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN apt-get install -y x11vnc xvfb firefox
RUN mkdir /.vnc
# Setup a password
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way, but it does the trick)
RUN bash -c 'echo "firefox" >> /.bashrc'
EXPOSE 5900
CMD ["x11vnc", "-forever", "-usepw", "-create"]
.. code-block:: bash
# Multiple images example
#
# VERSION 0.1
FROM ubuntu
RUN echo foo > bar
# Will output something like ===> 907ad6c2736f
FROM ubuntu
RUN echo moo > oink
# Will output something like ===> 695d7793cbe4
# You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.

View File

@@ -0,0 +1,19 @@
:title: Documentation
:description: -- todo: change me
:keywords: todo, docker, documentation, basic, builder
Use
========
Contents:
.. toctree::
:maxdepth: 1
basics
workingwithrepository
builder
puppet

112
docs/sources/use/puppet.rst Normal file
View File

@@ -0,0 +1,112 @@
:title: Puppet Usage
:description: Installating and using Puppet
:keywords: puppet, installation, usage, docker, documentation
.. _install_using_puppet:
Using Puppet
=============
.. note::
Please note this is a community contributed installation path. The only 'official' installation is using the
:ref:`ubuntu_linux` installation path. This version may sometimes be out of date.
Requirements
------------
To use this guide you'll need a working installation of Puppet from `Puppetlabs <https://www.puppetlabs.com>`_ .
The module also currently uses the official PPA so only works with Ubuntu.
Installation
------------
The module is available on the `Puppet Forge <https://forge.puppetlabs.com/garethr/docker/>`_
and can be installed using the built-in module tool.
.. code-block:: bash
puppet module install garethr/docker
It can also be found on `GitHub <https://www.github.com/garethr/garethr-docker>`_
if you would rather download the source.
Usage
-----
The module provides a puppet class for installing docker and two defined types
for managing images and containers.
Installation
~~~~~~~~~~~~
.. code-block:: ruby
include 'docker'
Images
~~~~~~
The next step is probably to install a docker image, for this we have a
defined type which can be used like so:
.. code-block:: ruby
docker::image { 'base': }
This is equivalent to running:
.. code-block:: bash
docker pull base
Note that it will only if the image of that name does not already exist.
This is downloading a large binary so on first run can take a while.
For that reason this define turns off the default 5 minute timeout
for exec. Note that you can also remove images you no longer need with:
.. code-block:: ruby
docker::image { 'base':
ensure => 'absent',
}
Containers
~~~~~~~~~~
Now you have an image you can run commands within a container managed by
docker.
.. code-block:: ruby
docker::run { 'helloworld':
image => 'base',
command => '/bin/sh -c "while true; do echo hello world; sleep 1; done"',
}
This is equivalent to running the following command, but under upstart:
.. code-block:: bash
docker run -d base /bin/sh -c "while true; do echo hello world; sleep 1; done"
Run also contains a number of optional parameters:
.. code-block:: ruby
docker::run { 'helloworld':
image => 'base',
command => '/bin/sh -c "while true; do echo hello world; sleep 1; done"',
ports => ['4444', '4555'],
volumes => ['/var/lib/counchdb', '/var/log'],
volumes_from => '6446ea52fbc9',
memory_limit => 10485760, # bytes
username => 'example',
hostname => 'example.com',
env => ['FOO=BAR', 'FOO2=BAR2'],
dns => ['8.8.8.8', '8.8.4.4'],
}
Note that ports, env, dns and volumes can be set with either a single string
or as above with an array of values.

View File

@@ -0,0 +1,79 @@
:title: Working With Repositories
:description: Generally, there are two types of repositories: Top-level repositories which are controlled by the people behind Docker, and user repositories.
:keywords: repo, repositiores, usage, pull image, push image, image, documentation
.. _working_with_the_repository:
Working with the repository
============================
Top-level repositories and user repositories
--------------------------------------------
Generally, there are two types of repositories: Top-level repositories which are controlled by the people behind
Docker, and user repositories.
* Top-level repositories can easily be recognized by not having a / (slash) in their name. These repositories can
generally be trusted.
* User repositories always come in the form of <username>/<repo_name>. This is what your published images will look like.
* User images are not checked, it is therefore up to you whether or not you trust the creator of this image.
Find public images available on the index
-----------------------------------------
Seach by name, namespace or description
.. code-block:: bash
docker search <value>
Download them simply by their name
.. code-block:: bash
docker pull <value>
Very similarly you can search for and browse the index online on https://index.docker.io
Connecting to the repository
----------------------------
You can create a user on the central docker repository online, or 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>

View File

@@ -6,8 +6,9 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="google-site-verification" content="UxV66EKuPe87dgnH1sbrldrx6VsoWMrx5NjwkgUFxXI" />
<title>Docker - {{ meta['title'] if meta and meta['title'] else title }}</title>
<title>{{ meta['title'] if meta and meta['title'] else title }} - Docker Documentation</title>
<meta name="description" content="{{ meta['description'] if meta }}" />
<meta name="keywords" content="{{ meta['keywords'] if meta }}" />
@@ -65,7 +66,7 @@
<ul class="nav">
<li><a href="http://www.docker.io/">Introduction</a></li>
<li><a href="http://www.docker.io/gettingstarted/">Getting started</a></li>
<li class="active"><a href="{{ pathto('concepts/containers/', 1) }}">Documentation</a></li>
<li class="active"><a href="http://docs.docker.io/en/latest/">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>
@@ -74,7 +75,7 @@
</div>
<div style="margin-left: -12px; float: left;">
<a href="{{ pathto('./', 1) }}"><img style="margin-top: 12px; height: 38px" src="{{ pathto('_static/img/docker-letters-logo.gif', 1) }}"></a>
<a href="http://www.docker.io"><img style="margin-top: 12px; height: 38px" src="{{ pathto('_static/img/docker-letters-logo.gif', 1) }}"></a>
</div>
</div>
@@ -154,69 +155,87 @@
<!-- script which should be loaded after everything else -->
<script type="text/javascript">
<script type="text/javascript">
var shiftWindow = function() {
scrollBy(0, -70);
console.log("window shifted")
};
window.addEventListener("hashchange", shiftWindow);
var shiftWindow = function() {
scrollBy(0, -70);
console.log("window shifted")
};
window.addEventListener("hashchange", shiftWindow);
function loadShift() {
if (window.location.hash) {
console.log("window has hash");
function loadShift() {
if (window.location.hash) {
console.log("window has hash");
shiftWindow();
}
}
}
}
$(window).load(function() {
loadShift();
console.log("late loadshift");
});
$(window).load(function() {
loadShift();
console.log("late loadshift");
});
$(function(){
$(function(){
// sidebar accordian-ing
// don't apply on last object (it should be the FAQ)
// sidebar accordian-ing
// don't apply on last object (it should be the FAQ)
var elements = $('.toctree-l2');
for (var i = 0; i < elements.length; i += 1) { var current = $(elements[i]); console.log(current); current.children('ul').hide();}
// define an array to which all opened items should be added
var openmenus = [];
var elements = $('.toctree-l2');
for (var i = 0; i < elements.length; i += 1) { var current = $(elements[i]); current.children('ul').hide();}
// set initial collapsed state
var elements = $('.toctree-l1');
for (var i = 0; i < elements.length; i += 1) {
var current = $(elements[i]);
if (current.hasClass('current')) {
// do nothing
} else {
// collapse children
current.children('ul').hide();
}
}
// set initial collapsed state
var elements = $('.toctree-l1');
for (var i = 0; i < elements.length; i += 1) {
var current = $(elements[i]);
if (current.hasClass('current')) {
// attached handler on click
$('.sidebar > ul > li > a').not(':last').click(function(){
if ($(this).parent().hasClass('current')) {
$(this).parent().children('ul').slideUp(200, function() {
$(this).parent().removeClass('current'); // toggle after effect
});
} else {
//$('.sidebar > ul > li > ul').slideUp(100);
var current = $(this);
setTimeout(function() {
$('.sidebar > ul > li').removeClass('current');
current.parent().addClass('current'); // toggle before effect
current.parent().children('ul').hide();
current.parent().children('ul').slideDown(200);
}, 100);
}
return false;
});
currentlink = current.children('a')[0].href;
openmenus.push(currentlink);
});
</script>
// do nothing
} else {
// collapse children
current.children('ul').hide();
}
}
// attached handler on click
$('.sidebar > ul > li > a').not(':last').click(function(){
var index = $.inArray(this.href, openmenus)
if (index > -1) {
console.log(index);
openmenus.splice(index, 1);
$(this).parent().children('ul').slideUp(200, function() {
// $(this).parent().removeClass('current'); // toggle after effect
});
}
else {
openmenus.push(this.href);
console.log(this);
var current = $(this);
setTimeout(function() {
$('.sidebar > ul > li').removeClass('current');
current.parent().addClass('current'); // toggle before effect
current.parent().children('ul').hide();
current.parent().children('ul').slideDown(200);
}, 100);
}
return false;
});
});
</script>
<!-- Google analytics -->
<script type="text/javascript">

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