Compare commits

..

31 Commits

Author SHA1 Message Date
Michael Crosby e245abcc4d Fix rebase conflicts from master 2013-10-02 13:58:43 -07:00
Michael Crosby 19c53c3833 Add docs and maintainers file for new sub pkgs 2013-10-02 12:48:27 -07:00
Michael Crosby 51db855bc3 Remove network connection when link is removed 2013-10-02 12:44:41 -07:00
Michael Crosby 8c1fae65d3 Convert links to upper case 2013-10-02 12:44:41 -07:00
Michael Crosby 018d3178e3 Add support for names with start command 2013-10-02 12:43:09 -07:00
Michael Crosby 2bae258bff Update make script for ldl 2013-10-02 12:43:09 -07:00
Michael Crosby 394d2f4ea7 Add sqlite as graphdb backend
Add build steps to compile docker statically
with CGO enabled
2013-10-02 12:43:09 -07:00
Michael Crosby 457a9260bc Refactor to use graph for linking 2013-10-02 12:38:41 -07:00
Michael Crosby e4fbeddf53 Add gograph database to handle linking 2013-10-02 12:38:41 -07:00
Michael Crosby a32741b1c2 Remove top level link command and endpoint 2013-10-02 12:38:41 -07:00
Michael Crosby a5dbb9a900 Add name and alias to docker ps output 2013-10-02 12:38:41 -07:00
Michael Crosby 21b9c9c7b4 Restore container links at runtime start 2013-10-02 12:38:41 -07:00
Michael Crosby 828ba3494d Update new unittests after rebase 2013-10-02 12:38:41 -07:00
Michael Crosby 583340bd56 Add default port for link
Add links unit test file
2013-10-02 12:38:41 -07:00
Michael Crosby 12d3e3e644 Add view all links for the engine 2013-10-02 12:38:41 -07:00
Michael Crosby e574bbf55e Do not reference ports for linking containers 2013-10-02 12:38:41 -07:00
Michael Crosby 377bfc3ad2 Create LinkRepository during runtime init 2013-10-02 12:38:41 -07:00
Michael Crosby c7d854af01 Create private link via iptables to linked containers
Allow active links to be removed
2013-10-02 12:38:41 -07:00
Michael Crosby a712b7467e Prevent inter-container communication 2013-10-02 12:38:41 -07:00
Michael Crosby 248e0c63db Add port and ip for links 2013-10-02 12:38:41 -07:00
Michael Crosby 20c962696f Initial commit to add links and inject env 2013-10-02 12:38:41 -07:00
Michael Crosby 234587e0ef Refactor internal port mappings 2013-10-02 12:38:41 -07:00
Michael Crosby 78adacde93 Add IP to APIPort struct 2013-10-02 12:38:41 -07:00
Michael Crosby 2e6329a904 Add -expose flag to expose ports without publishing 2013-10-02 12:38:40 -07:00
Michael Crosby 3e6d3ad1e4 Add warning and build error for public image ports 2013-10-02 12:38:40 -07:00
Michael Crosby 1b3baab4a8 Add destination to iptables conf 2013-10-02 12:38:40 -07:00
Michael Crosby c69549e016 Refactor internal port mappings 2013-10-02 12:38:40 -07:00
Michael Crosby 760648e33e Add flag to set the default ip ports are bound to 2013-10-02 12:36:56 -07:00
Michael Crosby 36b1be2acf Move proxy into sub package 2013-10-02 12:36:56 -07:00
Michael Crosby e1be306389 Add DaemonConfig
Use a config type for accessing data
Add bridgeiface name to config
Add option to disable iptables
2013-10-02 12:36:56 -07:00
Michael Crosby 2a76af221f Move iptables into sub package 2013-10-02 12:36:56 -07:00
267 changed files with 6590 additions and 9379 deletions
-1
View File
@@ -17,4 +17,3 @@ docs/_templates
bundles/
.hg/
.git/
vendor/pkg/
-12
View File
@@ -26,15 +26,3 @@ Roberto Hashioka <roberto_hashioka@hotmail.com>
Konstantin Pelykh <kpelykh@zettaset.com>
David Sissitka <me@dsissitka.com>
Nolan Darilek <nolan@thewordnerd.info>
<mastahyeti@gmail.com> <mastahyeti@users.noreply.github.com>
Benoit Chesneau <bchesneau@gmail.com>
Jordan Arentsen <blissdev@gmail.com>
Daniel Garcia <daniel@danielgarcia.info>
Miguel Angel Fernández <elmendalerenda@gmail.com>
Bhiraj Butala <abhiraj.butala@gmail.com>
Faiz Khan <faizkhan00@gmail.com>
Victor Lyuboslavsky <victor@victoreda.com>
Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
Matthew Mueller <mattmuelle@gmail.com>
<mosoni@ebay.com> <mohitsoni1989@gmail.com>
Shih-Yuan Lee <fourdollars@gmail.com>
+1 -72
View File
@@ -5,100 +5,64 @@
#
Al Tobey <al@ooyala.com>
Alex Gaynor <alex.gaynor@gmail.com>
Alexander Larsson <alexl@redhat.com>
Alexey Shamrin <shamrin@gmail.com>
Andrea Luzzardi <aluzzardi@gmail.com>
Andreas Savvides <andreas@editd.com>
Andreas Tiefenthaler <at@an-ti.eu>
Andrew Macgregor <andrew.macgregor@agworld.com.au>
Andrew Munsell <andrew@wizardapps.net>
Andrews Medina <andrewsmedina@gmail.com>
Andy Rothfusz <github@metaliveblog.com>
Andy Smith <github@anarkystic.com>
Anthony Bishopric <git@anthonybishopric.com>
Antony Messerli <amesserl@rackspace.com>
Asbjørn Enge <asbjorn@hanafjedle.net>
Barry Allard <barry.allard@gmail.com>
Ben Toews <mastahyeti@gmail.com>
Benoit Chesneau <bchesneau@gmail.com>
Bhiraj Butala <abhiraj.butala@gmail.com>
Bouke Haarsma <bouke@webatoom.nl>
Brandon Liu <bdon@bdon.org>
Brandon Philips <brandon@ifup.co>
Brian McCallister <brianm@skife.org>
Brian Olsen <brian@maven-group.org>
Brian Shumate <brian@couchbase.com>
Briehan Lombaard <briehan.lombaard@gmail.com>
Bruno Bigras <bigras.bruno@gmail.com>
Caleb Spare <cespare@gmail.com>
Calen Pennington <cale@edx.org>
Charles Hooper <charles.hooper@dotcloud.com>
Christopher Currie <codemonkey+github@gmail.com>
Colin Dunklau <colin.dunklau@gmail.com>
Colin Rice <colin@daedrum.net>
Dan Buch <d.buch@modcloth.com>
Daniel Garcia <daniel@danielgarcia.info>
Daniel Gasienica <daniel@gasienica.ch>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com>
Daniel Nordberg <dnordberg@gmail.com>
Daniel Robinson <gottagetmac@gmail.com>
Daniel Von Fange <daniel@leancoder.com>
Daniel YC Lin <dlin.tw@gmail.com>
David Calavera <david.calavera@gmail.com>
David Sissitka <me@dsissitka.com>
Deni Bertovic <deni@kset.org>
Dominik Honnef <dominik@honnef.co>
Don Spaulding <donspauldingii@gmail.com>
Dr Nic Williams <drnicwilliams@gmail.com>
Dražen Lučanin <kermit666@gmail.com>
Elias Probst <mail@eliasprobst.eu>
Emily Rose <emily@contactvibe.com>
Eric Hanchrow <ehanchrow@ine.com>
Eric Myhre <hash@exultant.us>
Erno Hopearuoho <erno.hopearuoho@gmail.com>
Evan Phoenix <evan@fallingsnow.net>
Evan Wies <evan@neomantra.net>
ezbercih <cem.ezberci@gmail.com>
Fabrizio Regini <freegenie@gmail.com>
Faiz Khan <faizkhan00@gmail.com>
Fareed Dudhia <fareeddudhia@googlemail.com>
Flavio Castelli <fcastelli@suse.com>
Francisco Souza <f@souza.cc>
Frederick F. Kautz IV <fkautz@alumni.cmu.edu>
Gabriel Monroy <gabriel@opdemand.com>
Gareth Rushgrove <gareth@morethanseven.net>
Greg Thornton <xdissent@me.com>
Guillaume J. Charmes <guillaume.charmes@dotcloud.com>
Gurjeet Singh <gurjeet@singh.im>
Guruprasad <lgp171188@gmail.com>
Harley Laue <losinggeneration@gmail.com>
Hector Castro <hectcastro@gmail.com>
Hunter Blanks <hunter@twilio.com>
Isao Jonas <isao.jonas@gmail.com>
James Carr <james.r.carr@gmail.com>
James Turnbull <james@lovedthanlost.net>
Jason McVetta <jason.mcvetta@gmail.com>
Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
Jeff Lindsay <progrium@gmail.com>
Jeremy Grosser <jeremy@synack.me>
Jim Alateras <jima@comware.com.au>
Jimmy Cuadra <jimmy@jimmycuadra.com>
Joe Van Dyk <joe@tanga.com>
Joffrey F <joffrey@dotcloud.com>
Johan Euphrosine <proppy@google.com>
John Costa <john.costa@gmail.com>
Jon Wedaman <jweede@gmail.com>
Jonas Pfenniger <jonas@pfenniger.name>
Jonathan Mueller <j.mueller@apoveda.ch>
Jonathan Rudenberg <jonathan@titanous.com>
Joost Cassee <joost@cassee.net>
Jordan Arentsen <blissdev@gmail.com>
Joseph Anthony Pasquale Holsten <joseph@josephholsten.com>
Julien Barbier <write0@gmail.com>
Jérôme Petazzoni <jerome.petazzoni@dotcloud.com>
Karan Lyons <karan@karanlyons.com>
Karl Grzeszczak <karl@karlgrz.com>
Kawsar Saiyeed <kawsar.saiyeed@projiris.com>
Keli Hu <dev@keli.hu>
Ken Cochrane <kencochrane@gmail.com>
Kevin Clark <kevin.clark@gmail.com>
@@ -107,46 +71,28 @@ kim0 <email.ahmedkamal@googlemail.com>
Kimbro Staken <kstaken@kstaken.com>
Kiran Gangadharan <kiran.daredevil@gmail.com>
Konstantin Pelykh <kpelykh@zettaset.com>
Kyle Conroy <kyle.j.conroy@gmail.com>
Laurie Voss <github@seldo.com>
Louis Opter <kalessin@kalessin.fr>
Manuel Meurer <manuel@krautcomputing.com>
Marco Hennings <marco.hennings@freiheit.com>
Marcus Farkas <toothlessgear@finitebox.com>
Marcus Ramberg <marcus@nordaaker.com>
Mark McGranaghan <mmcgrana@gmail.com>
Marko Mikulicic <mmikulicic@gmail.com>
Markus Fix <lispmeister@gmail.com>
Martin Redmond <martin@tinychat.com>
Matt Apperson <me@mattapperson.com>
Matt Bachmann <bachmann.matt@gmail.com>
Matthew Mueller <mattmuelle@gmail.com>
Martin Redmond <mrtodo@gmail.com>
Maxim Treskin <zerthurd@gmail.com>
meejah <meejah@meejah.ca>
Michael Crosby <crosby.michael@gmail.com>
Michael Gorsuch <gorsuch@github.com>
Miguel Angel Fernández <elmendalerenda@gmail.com>
Mike Gaffney <mike@uberu.com>
Mikhail Sobolev <mss@mawhrin.net>
Mohit Soni <mosoni@ebay.com>
Morten Siebuhr <sbhr@sbhr.dk>
Nan Monnand Deng <monnand@gmail.com>
Nate Jones <nate@endot.org>
Nelson Chen <crazysim@gmail.com>
Niall O'Higgins <niallo@unworkable.org>
Nick Payne <nick@kurai.co.uk>
Nick Stenning <nick.stenning@digital.cabinet-office.gov.uk>
Nick Stinemates <nick@stinemates.org>
Nolan Darilek <nolan@thewordnerd.info>
odk- <github@odkurzacz.org>
Pascal Borreli <pascal@borreli.com>
Paul Bowsher <pbowsher@globalpersonals.co.uk>
Paul Hammond <paul@paulhammond.org>
Paul Nasrat <pnasrat@gmail.com>
Phil Spitler <pspitler@gmail.com>
Piotr Bogdan <ppbogdan@gmail.com>
pysqz <randomq@126.com>
Ramon van Alteren <ramon@vanalteren.nl>
Renato Riccieri Santos Zannon <renato.riccieri@gmail.com>
Rhys Hiltner <rhys@twitch.tv>
Robert Obryk <robryk@gmail.com>
@@ -154,22 +100,14 @@ Roberto Hashioka <roberto_hashioka@hotmail.com>
Ryan Fowler <rwfowler@gmail.com>
Sam Alba <sam.alba@gmail.com>
Sam J Sharpe <sam.sharpe@digital.cabinet-office.gov.uk>
Scott Bessler <scottbessler@gmail.com>
Sean P. Kane <skane@newrelic.com>
Shawn Siefkas <shawn.siefkas@meredith.com>
Shih-Yuan Lee <fourdollars@gmail.com>
Silas Sewell <silas@sewell.org>
Solomon Hykes <solomon@dotcloud.com>
Song Gao <song@gao.io>
Sridatta Thatipamala <sthatipamala@gmail.com>
Sridhar Ratnakumar <sridharr@activestate.com>
Steeve Morin <steeve.morin@gmail.com>
Stefan Praszalowicz <stefan@greplin.com>
Thatcher Peskens <thatcher@dotcloud.com>
Thermionix <bond711@gmail.com>
Thijs Terlouw <thijsterlouw@gmail.com>
Thomas Bikeev <thomas.bikeev@mac.com>
Thomas Frössman <thomasf@jossystem.se>
Thomas Hansen <thomas.hansen@gmail.com>
Tianon Gravi <admwiggin@gmail.com>
Tim Terhorst <mynamewastaken+git@gmail.com>
@@ -177,17 +115,8 @@ Tobias Bieniek <Tobias.Bieniek@gmx.de>
Tobias Schmidt <ts@soundcloud.com>
Tobias Schwab <tobias.schwab@dynport.de>
Tom Hulihan <hulihan.tom159@gmail.com>
Tommaso Visconti <tommaso.visconti@gmail.com>
Tyler Brock <tyler.brock@gmail.com>
unclejack <unclejacksons@gmail.com>
Victor Coisne <victor.coisne@dotcloud.com>
Victor Lyuboslavsky <victor@victoreda.com>
Victor Vieux <victor.vieux@dotcloud.com>
Vincent Bernat <bernat@luffy.cx>
Vivek Agarwal <me@vivek.im>
Vladimir Kirillov <proger@wilab.org.ua>
Walter Stanish <walter@pratyeka.org>
Wes Morgan <cap10morgan@gmail.com>
Will Dietz <w@wdtz.org>
Yang Bai <hamo.by@gmail.com>
Zaiste! <oh@zaiste.net>
+331 -707
View File
File diff suppressed because it is too large Load Diff
+2 -19
View File
@@ -3,10 +3,6 @@
Want to hack on Docker? Awesome! Here are instructions to get you started. They are probably not perfect, please let us know if anything feels
wrong or incomplete.
## Build Environment
For instructions on setting up your development environment, please see our dedicated [dev environment setup docs](http://docs.docker.io/en/latest/contributing/devenvironment/).
## Contribution guidelines
### Pull requests are always welcome
@@ -59,10 +55,8 @@ Submit unit tests for your changes. Go has a great test framework built in; use
it! Take a look at existing tests for inspiration. Run the full test suite on
your branch before submitting a pull request.
Update the documentation when creating or modifying features. Test
your documentation changes for clarity, concision, and correctness, as
well as a clean docmuent build. See ``docs/README.md`` for more
information on building the docs and how docs get released.
Make sure you include relevant updates or additions to documentation when
creating or modifying features.
Write clean code. Universally formatted code promotes ease of writing, reading,
and maintenance. Always run `go fmt` before committing your changes. Most
@@ -95,17 +89,6 @@ name and email address match your git configuration. The AUTHORS file is
regenerated occasionally from the git commit history, so a mismatch may result
in your changes being overwritten.
### Approval
Docker maintainers use LGTM (looks good to me) in comments on the code review
to indicate acceptance.
A change requires LGTMs from an absolute majority of the maintainers of each
component affected. For example, if a change affects docs/ and registry/, it
needs an absolute majority from the maintainers of docs/ AND, separately, an
absolute majority of the maintainers of registry
For more details see [MAINTAINERS.md](hack/MAINTAINERS.md)
### How can I become a maintainer?
+9 -10
View File
@@ -4,24 +4,24 @@
#
# # Assemble the full dev environment. This is slow the first time.
# docker build -t docker .
# # Apparmor messes with privileged mode: disable it
# /etc/init.d/apparmor stop ; /etc/init.d/apparmor teardown
#
# # Mount your source in an interactive container for quick testing:
# docker run -v `pwd`:/go/src/github.com/dotcloud/docker -privileged -i -t docker bash
# docker run -v `pwd`:/go/src/github.com/dotcloud/docker -privileged -lxc-conf=lxc.aa_profile=unconfined -i -t docker bash
#
#
# # Run the test suite:
# docker run -privileged docker hack/make.sh test
# docker run -privileged -lxc-conf=lxc.aa_profile=unconfined docker go test -v
#
# # Publish a release:
# docker run -privileged \
# docker run -privileged -lxc-conf=lxc.aa_profile=unconfined \
# -e AWS_S3_BUCKET=baz \
# -e AWS_ACCESS_KEY=foo \
# -e AWS_SECRET_KEY=bar \
# -e GPG_PASSPHRASE=gloubiboulga \
# docker hack/release.sh
#
# Note: Apparmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore.
#
docker-version 0.6.1
from ubuntu:12.04
@@ -36,11 +36,11 @@ run apt-get install -y -q mercurial
run apt-get install -y -q build-essential libsqlite3-dev
# Install Go
run curl -s https://go.googlecode.com/files/go1.2rc3.src.tar.gz | tar -v -C /usr/local -xz
run curl -s https://go.googlecode.com/files/go1.2rc1.src.tar.gz | tar -v -C /usr/local -xz
run cd /usr/local/go/src && ./make.bash && go install -ldflags '-w -linkmode external -extldflags "-static -Wl,--unresolved-symbols=ignore-in-shared-libs"' -tags netgo -a std
env PATH /usr/local/go/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
env GOPATH /go:/go/src/github.com/dotcloud/docker/vendor
run cd /usr/local/go/src && ./make.bash && go install -ldflags '-w -linkmode external -extldflags "-static -Wl,--unresolved-symbols=ignore-in-shared-libs"' -tags netgo -a std
run cd /tmp && echo 'package main' > t.go && go test -a -i -v
# Ubuntu stuff
run apt-get install -y -q ruby1.9.3 rubygems libffi-dev
run gem install --no-rdoc --no-ri fpm
@@ -55,7 +55,6 @@ run /bin/echo -e '[default]\naccess_key=$AWS_ACCESS_KEY\nsecret_key=$AWS_SECRET_
# Runtime dependencies
run apt-get install -y -q iptables
run apt-get install -y -q lxc
run apt-get install -y -q aufs-tools
volume /var/lib/docker
workdir /go/src/github.com/dotcloud/docker
+10 -3
View File
@@ -15,16 +15,23 @@ to put them - so we put them here :)
* Run linter on codebase
* Unify build commands and regular commands
* Move source code into src/ subdir for clarity
* Clean up the Makefile, it's a mess
* docker build: on non-existent local path for ADD, don't show full absolute path on the host
* mount into /dockerinit rather than /sbin/init
* docker tag foo REPO:TAG
* use size header for progress bar in pull
* Clean up context upload in build!!!
* Parallel pull
* Ensure /proc/sys/net/ipv4/ip_forward is 1
* Force DNS to public!
* Always generate a resolv.conf per container, to avoid changing resolv.conf under thne container's feet
* Save metadata with import/export (#1974)
* Save metadata with import/export
* Upgrade dockerd without stopping containers
* Simple command to remove all untagged images (`docker rmi $(docker images | awk '/^<none>/ { print $3 }')`)
* bring back git revision info, looks like it was lost
* Simple command to remove all untagged images
* Simple command to clean up containers for disk space
* Caching after an ADD (#880)
* Caching after an ADD
* entry point config
* bring back git revision info, looks like it was lost
* Clean up the ProgressReader api, it's a PITA to use
* Use netlink instead of iproute2/iptables (#925)
+3 -2
View File
@@ -1,7 +1,8 @@
Docker
Copyright 2012-2013 Docker, Inc.
Copyright 2012-2013 dotCloud, inc.
This product includes software developed at Docker, Inc. (http://www.docker.com).
This product includes software developed at dotCloud,
inc. (http://www.dotcloud.com).
This product contains software (https://github.com/kr/pty) developed
by Keith Rarick, licensed under the MIT License.
+6 -6
View File
@@ -193,10 +193,10 @@ wrong or incomplete.
*Brought to you courtesy of our legal counsel. For more context,
please see the Notice document.*
Transfers of Docker shall be in accordance with applicable export controls
of any country and all other applicable legal requirements. Without limiting the
foregoing, Docker shall not be distributed or downloaded to any individual or
location if such distribution or download would violate the applicable US
government export regulations.
Transfers of Docker shall be in accordance with applicable export
controls of any country and all other applicable legal requirements.
Docker shall not be distributed or downloaded to or in Cuba, Iran,
North Korea, Sudan or Syria and shall not be distributed or downloaded
to any person on the Denied Persons List administered by the U.S.
Department of Commerce.
For more information, please see http://www.bis.doc.gov
+1 -1
View File
@@ -1 +1 @@
0.6.6
0.6.3-dev
Vendored
-4
View File
@@ -39,8 +39,6 @@ Vagrant::Config.run do |config|
"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
# Add vagrant user to the docker group
pkg_cmd << "usermod -a -G docker vagrant; "
# Activate new kernel
pkg_cmd << "shutdown -r +1; "
config.vm.provision :shell, :inline => pkg_cmd
@@ -80,8 +78,6 @@ Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
config.vm.provider :virtualbox do |vb|
config.vm.box = BOX_NAME
config.vm.box_url = BOX_URI
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
end
+86 -43
View File
@@ -5,8 +5,8 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/gograph"
"github.com/dotcloud/docker/utils"
"github.com/gorilla/mux"
"io"
@@ -15,6 +15,7 @@ import (
"mime"
"net"
"net/http"
"net/url"
"os"
"os/exec"
"regexp"
@@ -43,9 +44,6 @@ func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
//If we don't do this, POST method without Content-type (even with empty body) will fail
func parseForm(r *http.Request) error {
if r == nil {
return nil
}
if err := r.ParseForm(); err != nil && !strings.HasPrefix(err.Error(), "mime:") {
return err
}
@@ -74,11 +72,8 @@ func httpError(w http.ResponseWriter, err error) {
} else if strings.Contains(err.Error(), "hasn't been activated") {
statusCode = http.StatusForbidden
}
if err != nil {
utils.Errorf("HTTP Error: statusCode=%d %s", statusCode, err.Error())
http.Error(w, err.Error(), statusCode)
}
utils.Debugf("[error %d] %s", statusCode, err)
http.Error(w, err.Error(), statusCode)
}
func writeJSON(w http.ResponseWriter, code int, v interface{}) error {
@@ -109,7 +104,7 @@ func getBoolParam(value string) (bool, error) {
func matchesContentType(contentType, expectedType string) bool {
mimetype, _, err := mime.ParseMediaType(contentType)
if err != nil {
utils.Errorf("Error parsing media type: %s error: %s", contentType, err.Error())
utils.Debugf("Error parsing media type: %s error: %s", contentType, err.Error())
}
return err == nil && mimetype == expectedType
}
@@ -139,23 +134,9 @@ func postContainersKill(srv *Server, version float64, w http.ResponseWriter, r *
if vars == nil {
return fmt.Errorf("Missing parameter")
}
if err := parseForm(r); err != nil {
return err
}
name := vars["name"]
signal := 0
if r != nil {
s := r.Form.Get("signal")
if s != "" {
if s, err := strconv.Atoi(s); err != nil {
return err
} else {
signal = s
}
}
}
if err := srv.ContainerKill(name, signal); err != nil {
name = decodeName(name)
if err := srv.ContainerKill(name); err != nil {
return err
}
w.WriteHeader(http.StatusNoContent)
@@ -167,9 +148,10 @@ func getContainersExport(srv *Server, version float64, w http.ResponseWriter, r
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
name = decodeName(name)
if err := srv.ContainerExport(name, w); err != nil {
utils.Errorf("%s", err)
utils.Debugf("%s", err)
return err
}
return nil
@@ -214,7 +196,7 @@ func getEvents(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
_, err = wf.Write(b)
if err != nil {
// On error, evict the listener
utils.Errorf("%s", err)
utils.Debugf("%s", err)
srv.Lock()
delete(srv.listeners, r.RemoteAddr)
srv.Unlock()
@@ -236,7 +218,6 @@ func getEvents(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
}
w.Header().Set("Content-Type", "application/json")
wf := utils.NewWriteFlusher(w)
wf.Flush()
if since != 0 {
// If since, send previous events that happened after the timestamp
for _, event := range srv.events {
@@ -369,8 +350,8 @@ func postCommit(srv *Server, version float64, w http.ResponseWriter, r *http.Req
return err
}
config := &Config{}
if err := json.NewDecoder(r.Body).Decode(config); err != nil && err != io.EOF {
utils.Errorf("%s", err)
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
utils.Debugf("%s", err)
}
repo := r.Form.Get("repo")
tag := r.Form.Get("tag")
@@ -523,12 +504,8 @@ func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http
}
func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return nil
}
config := &Config{}
out := &APIRun{}
name := r.Form.Get("name")
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
return err
@@ -544,7 +521,7 @@ func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r
config.Dns = defaultDns
}
id, warnings, err := srv.ContainerCreate(config, name)
id, warnings, err := srv.ContainerCreate(config)
if err != nil {
return err
}
@@ -582,6 +559,7 @@ func postContainersRestart(srv *Server, version float64, w http.ResponseWriter,
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
name = decodeName(name)
if err := srv.ContainerRestart(name, t); err != nil {
return err
}
@@ -597,6 +575,7 @@ func deleteContainers(srv *Server, version float64, w http.ResponseWriter, r *ht
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
name = decodeName(name)
removeVolume, err := getBoolParam(r.Form.Get("v"))
if err != nil {
@@ -653,9 +632,10 @@ func postContainersStart(srv *Server, version float64, w http.ResponseWriter, r
if vars == nil {
return fmt.Errorf("Missing parameter")
}
var err error
name := vars["name"]
// Register any links from the host config before starting the container
if err := srv.RegisterLinks(name, hostConfig); err != nil {
name = decodeName(name)
if err != nil {
return err
}
if err := srv.ContainerStart(name, hostConfig); err != nil {
@@ -678,6 +658,7 @@ func postContainersStop(srv *Server, version float64, w http.ResponseWriter, r *
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
name = decodeName(name)
if err := srv.ContainerStop(name, t); err != nil {
return err
@@ -691,6 +672,7 @@ func postContainersWait(srv *Server, version float64, w http.ResponseWriter, r *
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
name = decodeName(name)
status, err := srv.ContainerWait(name)
if err != nil {
@@ -751,6 +733,7 @@ func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r
return fmt.Errorf("Missing parameter")
}
name := vars["name"]
name = decodeName(name)
c, err := srv.ContainerInspect(name)
if err != nil {
@@ -832,7 +815,7 @@ func wsContainersAttach(srv *Server, version float64, w http.ResponseWriter, r *
defer ws.Close()
if err := srv.ContainerAttach(name, logs, stream, stdin, stdout, stderr, ws, ws, ws); err != nil {
utils.Errorf("Error: %s", err)
utils.Debugf("Error: %s", err)
}
})
h.ServeHTTP(w, r)
@@ -907,7 +890,7 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
}
c, err := archive.Tar(root, archive.Bzip2)
c, err := Tar(root, Bzip2)
if err != nil {
return err
}
@@ -945,7 +928,8 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
b := NewBuildFile(srv, utils.NewWriteFlusher(w), !suppressOutput, !noCache, rm)
id, err := b.Build(context)
if err != nil {
return fmt.Errorf("Error build: %s", err)
fmt.Fprintf(w, "Error build: %s\n", err)
return err
}
if repoName != "" {
srv.runtime.repositories.Set(repoName, tag, id, false)
@@ -977,7 +961,7 @@ func postContainersCopy(srv *Server, version float64, w http.ResponseWriter, r *
}
if err := srv.ContainerCopy(name, copyData.Resource, w); err != nil {
utils.Errorf("%s", err.Error())
utils.Debugf("%s", err.Error())
return err
}
return nil
@@ -1022,12 +1006,69 @@ func makeHttpHandler(srv *Server, logging bool, localMethod string, localRoute s
}
if err := handlerFunc(srv, version, w, r, mux.Vars(r)); err != nil {
utils.Errorf("Error: %s", err)
utils.Debugf("Error: %s", err)
httpError(w, err)
}
}
}
func getContainersLinks(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
runtime := srv.runtime
out := []APILink{}
err := runtime.containerGraph.Walk("/", func(p string, e *gograph.Entity) error {
if container := runtime.Get(e.ID()); container != nil {
out = append(out, APILink{
Path: p,
ContainerID: container.ID,
Image: runtime.repositories.ImageName(container.Image),
})
}
return nil
}, -1)
if err != nil {
return err
}
return writeJSON(w, http.StatusOK, out)
}
func postContainerLink(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
values := make(map[string]string)
if matchesContentType(r.Header.Get("Content-Type"), "application/json") && r.Body != nil {
defer r.Body.Close()
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&values); err != nil {
return err
}
} else {
return fmt.Errorf("Invalid json body")
}
currentName := values["currentName"]
newName := values["newName"]
if currentName == "" {
return fmt.Errorf("currentName cannot be empty")
}
if newName == "" {
return fmt.Errorf("newName cannot be empty")
}
if err := srv.runtime.RenameLink(currentName, newName); err != nil {
return err
}
return nil
}
func decodeName(name string) string {
s, _ := url.QueryUnescape(name)
return s
}
func createRouter(srv *Server, logging bool) (*mux.Router, error) {
r := mux.NewRouter()
@@ -1048,6 +1089,7 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) {
"/containers/{name:.*}/json": getContainersByName,
"/containers/{name:.*}/top": getContainersTop,
"/containers/{name:.*}/attach/ws": wsContainersAttach,
"/containers/links": getContainersLinks,
},
"POST": {
"/auth": postAuth,
@@ -1066,6 +1108,7 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) {
"/containers/{name:.*}/resize": postContainersResize,
"/containers/{name:.*}/attach": postContainersAttach,
"/containers/{name:.*}/copy": postContainersCopy,
"/containers/link": postContainerLink,
},
"DELETE": {
"/containers/{name:.*}": deleteContainers,
+11 -1
View File
@@ -5,7 +5,6 @@ type APIHistory struct {
Tags []string `json:",omitempty"`
Created int64
CreatedBy string `json:",omitempty"`
Size int64
}
type APIImages struct {
@@ -78,6 +77,11 @@ type APIContainersOld struct {
SizeRootFs int64
}
type APISearch struct {
Name string
Description string
}
type APIID struct {
ID string `json:"Id"`
}
@@ -117,3 +121,9 @@ type APICopy struct {
Resource string
HostPath string
}
type APILink struct {
Path string
ContainerID string
Image string
}
+25 -58
View File
@@ -5,7 +5,6 @@ import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"github.com/dotcloud/docker/utils"
"io"
"net"
@@ -13,7 +12,6 @@ import (
"net/http/httptest"
"os"
"path"
"strings"
"testing"
"time"
)
@@ -42,25 +40,6 @@ func TestGetBoolParam(t *testing.T) {
}
}
func TesthttpError(t *testing.T) {
r := httptest.NewRecorder()
httpError(r, fmt.Errorf("No such method"))
if r.Code != http.StatusNotFound {
t.Fatalf("Expected %d, got %d", http.StatusNotFound, r.Code)
}
httpError(r, fmt.Errorf("This accound hasn't been activated"))
if r.Code != http.StatusForbidden {
t.Fatalf("Expected %d, got %d", http.StatusForbidden, r.Code)
}
httpError(r, fmt.Errorf("Some error"))
if r.Code != http.StatusInternalServerError {
t.Fatalf("Expected %d, got %d", http.StatusInternalServerError, r.Code)
}
}
func TestGetVersion(t *testing.T) {
var err error
runtime := mkRuntime(t)
@@ -112,7 +91,6 @@ func TestGetInfo(t *testing.T) {
func TestGetEvents(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
srv := &Server{
runtime: runtime,
events: make([]utils.JSONMessage, 0, 64),
@@ -265,11 +243,7 @@ func TestGetImagesJSON(t *testing.T) {
t.Fatalf("Error expected, received none")
}
if !strings.HasPrefix(err.Error(), "Bad parameter") {
t.Fatalf("Error should starts with \"Bad parameter\"")
}
http.Error(r4, err.Error(), http.StatusBadRequest)
httpError(r4, err)
if r4.Code != http.StatusBadRequest {
t.Fatalf("%d Bad Request expected, received %d\n", http.StatusBadRequest, r4.Code)
}
@@ -347,12 +321,10 @@ func TestGetContainersJSON(t *testing.T) {
srv := &Server{runtime: runtime}
beginLen := runtime.containers.Len()
container, _, err := runtime.Create(&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"echo", "test"},
}, "")
})
if err != nil {
t.Fatal(err)
}
@@ -371,8 +343,8 @@ func TestGetContainersJSON(t *testing.T) {
if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
t.Fatal(err)
}
if len(containers) != beginLen+1 {
t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers), beginLen)
if len(containers) != 1 {
t.Fatalf("Expected %d container, %d found", 1, len(containers))
}
if containers[0].ID != container.ID {
t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.ID, containers[0].ID)
@@ -391,7 +363,6 @@ func TestGetContainersExport(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"touch", "/test"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -442,7 +413,6 @@ func TestGetContainersChanges(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/rm", "/etc/passwd"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -476,7 +446,10 @@ func TestGetContainersChanges(t *testing.T) {
func TestGetContainersTop(t *testing.T) {
t.Skip("Fixme. Skipping test for now. Reported error when testing using dind: 'api_test.go:527: Expected 2 processes, found 0.'")
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{runtime: runtime}
@@ -487,7 +460,6 @@ func TestGetContainersTop(t *testing.T) {
Cmd: []string{"/bin/sh", "-c", "cat"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -499,7 +471,8 @@ func TestGetContainersTop(t *testing.T) {
container.WaitTimeout(2 * time.Second)
}()
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -568,7 +541,6 @@ func TestGetContainersByName(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"echo", "test"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -600,7 +572,6 @@ func TestPostCommit(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"touch", "/test"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -696,14 +667,14 @@ func TestPostContainersKill(t *testing.T) {
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -735,17 +706,17 @@ func TestPostContainersRestart(t *testing.T) {
container, _, err := runtime.Create(
&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/top"},
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -792,7 +763,6 @@ func TestPostContainersStart(t *testing.T) {
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -806,8 +776,6 @@ func TestPostContainersStart(t *testing.T) {
t.Fatal(err)
}
req.Header.Set("Content-Type", "application/json")
r := httptest.NewRecorder()
if err := postContainersStart(srv, APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
t.Fatal(err)
@@ -842,17 +810,17 @@ func TestPostContainersStop(t *testing.T) {
container, _, err := runtime.Create(
&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/top"},
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -892,14 +860,14 @@ func TestPostContainersWait(t *testing.T) {
Cmd: []string{"/bin/sleep", "1"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -934,7 +902,6 @@ func TestPostContainersAttach(t *testing.T) {
Cmd: []string{"/bin/cat"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -942,7 +909,8 @@ func TestPostContainersAttach(t *testing.T) {
defer runtime.Destroy(container)
// Start the process
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -1023,7 +991,6 @@ func TestPostContainersAttachStderr(t *testing.T) {
Cmd: []string{"/bin/sh", "-c", "/bin/cat >&2"},
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1031,7 +998,8 @@ func TestPostContainersAttachStderr(t *testing.T) {
defer runtime.Destroy(container)
// Start the process
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -1112,7 +1080,7 @@ func TestDeleteContainers(t *testing.T) {
container, _, err := runtime.Create(&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"touch", "/test"},
}, "")
})
if err != nil {
t.Fatal(err)
}
@@ -1304,7 +1272,6 @@ func TestPostContainersCopy(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"touch", "/test.txt"},
},
"",
)
if err != nil {
t.Fatal(err)
+1 -1
View File
@@ -1,4 +1,4 @@
package archive
package docker
import (
"archive/tar"
-1
View File
@@ -1 +0,0 @@
Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
+1 -1
View File
@@ -1,4 +1,4 @@
package archive
package docker
import (
"bytes"
+11 -90
View File
@@ -75,33 +75,21 @@ func TestCreateAccount(t *testing.T) {
}
}
func setupTempConfigFile() (*ConfigFile, error) {
root, err := ioutil.TempDir("", "docker-test-auth")
if err != nil {
return nil, err
}
configFile := &ConfigFile{
rootPath: root,
Configs: make(map[string]AuthConfig),
}
for _, registry := range []string{"testIndex", IndexServerAddress()} {
configFile.Configs[registry] = AuthConfig{
Username: "docker-user",
Password: "docker-pass",
Email: "docker@docker.io",
}
}
return configFile, nil
}
func TestSameAuthDataPostSave(t *testing.T) {
configFile, err := setupTempConfigFile()
root, err := ioutil.TempDir("", "docker-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(configFile.rootPath)
configFile := &ConfigFile{
rootPath: root,
Configs: make(map[string]AuthConfig, 1),
}
configFile.Configs["testIndex"] = AuthConfig{
Username: "docker-user",
Password: "docker-pass",
Email: "docker@docker.io",
}
err = SaveConfig(configFile)
if err != nil {
@@ -122,70 +110,3 @@ func TestSameAuthDataPostSave(t *testing.T) {
t.Fail()
}
}
func TestResolveAuthConfigIndexServer(t *testing.T) {
configFile, err := setupTempConfigFile()
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(configFile.rootPath)
for _, registry := range []string{"", IndexServerAddress()} {
resolved := configFile.ResolveAuthConfig(registry)
if resolved != configFile.Configs[IndexServerAddress()] {
t.Fail()
}
}
}
func TestResolveAuthConfigFullURL(t *testing.T) {
configFile, err := setupTempConfigFile()
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(configFile.rootPath)
registryAuth := AuthConfig{
Username: "foo-user",
Password: "foo-pass",
Email: "foo@example.com",
}
localAuth := AuthConfig{
Username: "bar-user",
Password: "bar-pass",
Email: "bar@example.com",
}
configFile.Configs["https://registry.example.com/v1/"] = registryAuth
configFile.Configs["http://localhost:8000/v1/"] = localAuth
validRegistries := map[string][]string{
"https://registry.example.com/v1/": {
"https://registry.example.com/v1/",
"http://registry.example.com/v1/",
"registry.example.com",
"registry.example.com/v1/",
},
"http://localhost:8000/v1/": {
"https://localhost:8000/v1/",
"http://localhost:8000/v1/",
"localhost:8000",
"localhost:8000/v1/",
},
}
for configKey, registries := range validRegistries {
for _, registry := range registries {
var (
configured AuthConfig
ok bool
)
resolved := configFile.ResolveAuthConfig(registry)
if configured, ok = configFile.Configs[configKey]; !ok {
t.Fail()
}
if resolved.Email != configured.Email {
t.Errorf("%s -> %q != %q\n", registry, resolved.Email, configured.Email)
}
}
}
}
+17 -26
View File
@@ -3,7 +3,6 @@ package docker
import (
"encoding/json"
"fmt"
"github.com/dotcloud/docker/archive"
"github.com/dotcloud/docker/utils"
"io"
"io/ioutil"
@@ -65,9 +64,6 @@ func (b *buildFile) CmdFrom(name string) error {
}
b.image = image.ID
b.config = &Config{}
if image.Config != nil {
b.config = image.Config
}
if b.config.Env == nil || len(b.config.Env) == 0 {
b.config.Env = append(b.config.Env, "HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
}
@@ -191,6 +187,9 @@ func (b *buildFile) CmdCmd(args string) error {
}
func (b *buildFile) CmdExpose(args string) error {
if strings.Contains(args, ":") {
return fmt.Errorf("EXPOSE cannot be used to bind to a host ip or port")
}
ports := strings.Split(args, " ")
b.config.PortSpecs = append(ports, b.config.PortSpecs...)
return b.commit("", b.config.Cmd, fmt.Sprintf("EXPOSE %v", ports))
@@ -295,17 +294,17 @@ func (b *buildFile) addContext(container *Container, orig, dest string) error {
return fmt.Errorf("%s: no such file or directory", orig)
}
if fi.IsDir() {
if err := archive.CopyWithTar(origPath, destPath); err != nil {
if err := CopyWithTar(origPath, destPath); err != nil {
return err
}
// First try to unpack the source as an archive
} else if err := archive.UntarPath(origPath, destPath); err != nil {
} else if err := UntarPath(origPath, destPath); err != nil {
utils.Debugf("Couldn't untar %s to %s: %s", origPath, destPath, err)
// If that fails, just copy it as a regular file
if err := os.MkdirAll(path.Dir(destPath), 0755); err != nil {
return err
}
if err := archive.CopyWithTar(origPath, destPath); err != nil {
if err := CopyWithTar(origPath, destPath); err != nil {
return err
}
}
@@ -336,7 +335,7 @@ func (b *buildFile) CmdAdd(args string) error {
b.config.Image = b.image
// Create the container and start it
container, _, err := b.runtime.Create(b.config, "")
container, _, err := b.runtime.Create(b.config)
if err != nil {
return err
}
@@ -371,7 +370,7 @@ func (b *buildFile) run() (string, error) {
b.config.Image = b.image
// Create the container and start it
c, _, err := b.runtime.Create(b.config, "")
c, _, err := b.runtime.Create(b.config)
if err != nil {
return "", err
}
@@ -382,21 +381,15 @@ func (b *buildFile) run() (string, error) {
c.Path = b.config.Cmd[0]
c.Args = b.config.Cmd[1:]
var errCh chan error
if b.verbose {
errCh = utils.Go(func() error {
return <-c.Attach(nil, nil, b.out, b.out)
})
}
//start the container
if err := c.Start(); err != nil {
hostConfig := &HostConfig{}
if err := c.Start(hostConfig); err != nil {
return "", err
}
if errCh != nil {
if err := <-errCh; err != nil {
if b.verbose {
err = <-c.Attach(nil, nil, b.out, b.out)
if err != nil {
return "", err
}
}
@@ -433,13 +426,10 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
}
}
container, warnings, err := b.runtime.Create(b.config, "")
container, _, err := b.runtime.Create(b.config)
if err != nil {
return err
}
for _, warning := range warnings {
fmt.Fprintf(b.out, " ---> [Warning] %s\n", warning)
}
b.tmpContainers[container.ID] = struct{}{}
fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
id = container.ID
@@ -471,12 +461,13 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
var lineContinuation = regexp.MustCompile(`\s*\\\s*\n`)
func (b *buildFile) Build(context io.Reader) (string, error) {
// FIXME: @creack any reason for using /tmp instead of ""?
// FIXME: @creack "name" is a terrible variable name
name, err := ioutil.TempDir("", "docker-build")
name, err := ioutil.TempDir("/tmp", "docker-build")
if err != nil {
return "", err
}
if err := archive.Untar(context, name); err != nil {
if err := Untar(context, name); err != nil {
return "", err
}
defer os.RemoveAll(name)
+25 -44
View File
@@ -2,7 +2,6 @@ package docker
import (
"fmt"
"github.com/dotcloud/docker/archive"
"io/ioutil"
"net"
"net/http"
@@ -13,7 +12,7 @@ import (
// mkTestContext generates a build context from the contents of the provided dockerfile.
// This context is suitable for use as an argument to BuildFile.Build()
func mkTestContext(dockerfile string, files [][2]string, t *testing.T) archive.Archive {
func mkTestContext(dockerfile string, files [][2]string, t *testing.T) Archive {
context, err := mkBuildContext(dockerfile, files)
if err != nil {
t.Fatal(err)
@@ -230,7 +229,10 @@ func TestBuild(t *testing.T) {
func buildImage(context testContextTemplate, t *testing.T, srv *Server, useCache bool) *Image {
if srv == nil {
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv = &Server{
@@ -368,7 +370,10 @@ func TestBuildEntrypoint(t *testing.T) {
// testing #1405 - config.Cmd does not get cleaned up if
// utilizing cache
func TestBuildEntrypointRunCleanup(t *testing.T) {
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{
@@ -397,7 +402,10 @@ func TestBuildEntrypointRunCleanup(t *testing.T) {
}
func TestBuildImageWithCache(t *testing.T) {
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{
@@ -425,7 +433,10 @@ func TestBuildImageWithCache(t *testing.T) {
}
func TestBuildImageWithoutCache(t *testing.T) {
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{
@@ -453,7 +464,10 @@ func TestBuildImageWithoutCache(t *testing.T) {
}
func TestForbiddenContextPath(t *testing.T) {
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{
@@ -499,7 +513,10 @@ func TestForbiddenContextPath(t *testing.T) {
}
func TestBuildADDFileNotFound(t *testing.T) {
runtime := mkRuntime(t)
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{
@@ -542,39 +559,3 @@ func TestBuildADDFileNotFound(t *testing.T) {
t.Fail()
}
}
func TestBuildInheritance(t *testing.T) {
runtime, err := newTestRuntime("")
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
srv := &Server{
runtime: runtime,
pullingPool: make(map[string]struct{}),
pushingPool: make(map[string]struct{}),
}
img := buildImage(testContextTemplate{`
from {IMAGE}
expose 4243
`,
nil, nil}, t, srv, true)
img2 := buildImage(testContextTemplate{fmt.Sprintf(`
from %s
entrypoint ["/bin/echo"]
`, img.ID),
nil, nil}, t, srv, true)
// from child
if img2.Config.Entrypoint[0] != "/bin/echo" {
t.Fail()
}
// from parent
if img.Config.PortSpecs[0] != "4243" {
t.Fail()
}
}
+222 -342
View File
File diff suppressed because it is too large Load Diff
+18 -138
View File
@@ -84,24 +84,10 @@ func TestRunHostname(t *testing.T) {
}
})
container := globalRuntime.List()[0]
setTimeout(t, "CmdRun timed out", 10*time.Second, func() {
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
<-c
go func() {
cli.CmdWait(container.ID)
}()
if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil {
t.Fatal(err)
}
})
// Cleanup pipes
if err := closeWrap(stdout, stdoutPipe); err != nil {
t.Fatal(err)
}
}
// TestRunWorkdir checks that 'docker run -w' correctly sets a custom working directory
@@ -129,24 +115,10 @@ func TestRunWorkdir(t *testing.T) {
}
})
container := globalRuntime.List()[0]
setTimeout(t, "CmdRun timed out", 10*time.Second, func() {
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
<-c
go func() {
cli.CmdWait(container.ID)
}()
if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil {
t.Fatal(err)
}
})
// Cleanup pipes
if err := closeWrap(stdout, stdoutPipe); err != nil {
t.Fatal(err)
}
}
// TestRunWorkdirExists checks that 'docker run -w' correctly sets a custom working directory, even if it exists
@@ -174,24 +146,10 @@ func TestRunWorkdirExists(t *testing.T) {
}
})
container := globalRuntime.List()[0]
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
<-c
go func() {
cli.CmdWait(container.ID)
}()
if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil {
t.Fatal(err)
}
})
// Cleanup pipes
if err := closeWrap(stdout, stdoutPipe); err != nil {
t.Fatal(err)
}
}
func TestRunExit(t *testing.T) {
@@ -304,7 +262,7 @@ func TestRunDisconnectTty(t *testing.T) {
// We're simulating a disconnect so the return value doesn't matter. What matters is the
// fact that CmdRun returns.
if err := cli.CmdRun("-i", "-t", unitTestImageID, "/bin/cat"); err != nil {
utils.Debugf("Error CmdRun: %s", err)
utils.Debugf("Error CmdRun: %s\n", err)
}
close(c1)
@@ -435,16 +393,14 @@ func TestRunDetach(t *testing.T) {
container := globalRuntime.List()[0]
setTimeout(t, "Escape sequence timeout", 5*time.Second, func() {
stdinPipe.Write([]byte{16, 17})
stdinPipe.Write([]byte{'', ''})
if err := stdinPipe.Close(); err != nil {
t.Fatal(err)
}
})
closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
// wait for CmdRun to return
setTimeout(t, "Waiting for CmdRun timed out", 15*time.Second, func() {
setTimeout(t, "Waiting for CmdRun timed out", 5*time.Second, func() {
<-ch
})
@@ -455,6 +411,7 @@ func TestRunDetach(t *testing.T) {
setTimeout(t, "Waiting for container to die timed out", 20*time.Second, func() {
container.Kill()
container.Wait()
})
}
@@ -466,65 +423,42 @@ func TestAttachDetach(t *testing.T) {
cli := NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
defer cleanup(globalRuntime)
ch := make(chan struct{})
go func() {
defer close(ch)
go stdout.Read(make([]byte, 1024))
setTimeout(t, "Starting container timed out", 2*time.Second, func() {
if err := cli.CmdRun("-i", "-t", "-d", unitTestImageID, "cat"); err != nil {
t.Fatal(err)
}
}()
var container *Container
setTimeout(t, "Reading container's id timed out", 10*time.Second, func() {
buf := make([]byte, 1024)
n, err := stdout.Read(buf)
if err != nil {
t.Fatal(err)
}
container = globalRuntime.List()[0]
if strings.Trim(string(buf[:n]), " \r\n") != container.ShortID() {
t.Fatalf("Wrong ID received. Expect %s, received %s", container.ShortID(), buf[:n])
}
})
setTimeout(t, "Starting container timed out", 10*time.Second, func() {
<-ch
})
container := globalRuntime.List()[0]
stdin, stdinPipe = io.Pipe()
stdout, stdoutPipe = io.Pipe()
cli = NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
ch = make(chan struct{})
ch := make(chan struct{})
go func() {
defer close(ch)
if err := cli.CmdAttach(container.ShortID()); err != nil {
if err != io.ErrClosedPipe {
t.Fatal(err)
}
t.Fatal(err)
}
}()
setTimeout(t, "First read/write assertion timed out", 2*time.Second, func() {
if err := assertPipe("hello\n", "hello", stdout, stdinPipe, 15); err != nil {
if err != io.ErrClosedPipe {
t.Fatal(err)
}
t.Fatal(err)
}
})
setTimeout(t, "Escape sequence timeout", 5*time.Second, func() {
stdinPipe.Write([]byte{16, 17})
stdinPipe.Write([]byte{'', ''})
if err := stdinPipe.Close(); err != nil {
t.Fatal(err)
}
})
closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
// wait for CmdRun to return
setTimeout(t, "Waiting for CmdAttach timed out", 15*time.Second, func() {
setTimeout(t, "Waiting for CmdAttach timed out", 5*time.Second, func() {
<-ch
})
@@ -535,6 +469,7 @@ func TestAttachDetach(t *testing.T) {
setTimeout(t, "Waiting for container to die timedout", 5*time.Second, func() {
container.Kill()
container.Wait()
})
}
@@ -549,7 +484,7 @@ func TestAttachDisconnect(t *testing.T) {
go func() {
// Start a process in daemon mode
if err := cli.CmdRun("-d", "-i", unitTestImageID, "/bin/cat"); err != nil {
utils.Debugf("Error CmdRun: %s", err)
utils.Debugf("Error CmdRun: %s\n", err)
}
}()
@@ -610,7 +545,6 @@ func TestAttachDisconnect(t *testing.T) {
// Expected behaviour: container gets deleted automatically after exit
func TestRunAutoRemove(t *testing.T) {
t.Skip("Fixme. Skipping test for now, race condition")
stdout, stdoutPipe := io.Pipe()
cli := NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
defer cleanup(globalRuntime)
@@ -635,7 +569,7 @@ func TestRunAutoRemove(t *testing.T) {
}
})
setTimeout(t, "CmdRun timed out", 10*time.Second, func() {
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
<-c
})
@@ -645,57 +579,3 @@ func TestRunAutoRemove(t *testing.T) {
t.Fatalf("failed to remove container automatically: container %s still exists", temporaryContainerID)
}
}
func TestCmdLogs(t *testing.T) {
cli := NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr)
defer cleanup(globalRuntime)
if err := cli.CmdRun(unitTestImageID, "sh", "-c", "ls -l"); err != nil {
t.Fatal(err)
}
if err := cli.CmdRun("-t", unitTestImageID, "sh", "-c", "ls -l"); err != nil {
t.Fatal(err)
}
if err := cli.CmdLogs(globalRuntime.List()[0].ID); err != nil {
t.Fatal(err)
}
}
// Expected behaviour: using / as a bind mount source should throw an error
func TestRunErrorBindMountRootSource(t *testing.T) {
cli := NewDockerCli(nil, nil, ioutil.Discard, testDaemonProto, testDaemonAddr)
defer cleanup(globalRuntime)
c := make(chan struct{})
go func() {
defer close(c)
if err := cli.CmdRun("-v", "/:/tmp", unitTestImageID, "echo 'should fail'"); err == nil {
t.Fatal("should have failed to run when using / as a source for the bind mount")
}
}()
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
<-c
})
}
// Expected behaviour: error out when attempting to bind mount non-existing source paths
func TestRunErrorBindNonExistingSource(t *testing.T) {
cli := NewDockerCli(nil, nil, ioutil.Discard, testDaemonProto, testDaemonAddr)
defer cleanup(globalRuntime)
c := make(chan struct{})
go func() {
defer close(c)
if err := cli.CmdRun("-v", "/i/dont/exist:/tmp", unitTestImageID, "echo 'should fail'"); err == nil {
t.Fatal("should have failed to run when using /i/dont/exist as a source for the bind mount")
}
}()
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
<-c
})
}
+9 -35
View File
@@ -2,42 +2,16 @@ package docker
import (
"net"
"github.com/dotcloud/docker/engine"
)
// FIXME: separate runtime configuration from http api configuration
type DaemonConfig struct {
Pidfile string
Root string
ProtoAddresses []string
AutoRestart bool
EnableCors bool
Dns []string
EnableIptables bool
BridgeIface string
DefaultIp net.IP
InterContainerCommunication bool
}
// ConfigFromJob creates and returns a new DaemonConfig object
// by parsing the contents of a job's environment.
func ConfigFromJob(job *engine.Job) *DaemonConfig {
var config DaemonConfig
config.Pidfile = job.Getenv("Pidfile")
config.Root = job.Getenv("Root")
config.AutoRestart = job.GetenvBool("AutoRestart")
config.EnableCors = job.GetenvBool("EnableCors")
if dns := job.Getenv("Dns"); dns != "" {
config.Dns = []string{dns}
}
config.EnableIptables = job.GetenvBool("EnableIptables")
if br := job.Getenv("BridgeIface"); br != "" {
config.BridgeIface = br
} else {
config.BridgeIface = DefaultNetworkBridge
}
config.ProtoAddresses = job.GetenvList("ProtoAddresses")
config.DefaultIp = net.ParseIP(job.Getenv("DefaultIp"))
config.InterContainerCommunication = job.GetenvBool("InterContainerCommunication")
return &config
Pidfile string
GraphPath string
ProtoAddresses []string
AutoRestart bool
EnableCors bool
Dns []string
EnableIptables bool
BridgeIface string
DefaultIp net.IP
}
+188 -319
View File
File diff suppressed because it is too large Load Diff
+53 -132
View File
@@ -23,7 +23,6 @@ func TestIDFormat(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/sh", "-c", "echo hello world"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -40,7 +39,7 @@ func TestIDFormat(t *testing.T) {
func TestMultipleAttachRestart(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container, _ := mkContainer(
container, hostConfig, _ := mkContainer(
runtime,
[]string{"_", "/bin/sh", "-c", "i=1; while [ $i -le 5 ]; do i=`expr $i + 1`; echo hello; done"},
t,
@@ -61,7 +60,7 @@ func TestMultipleAttachRestart(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
l1, err := bufio.NewReader(stdout1).ReadString('\n')
@@ -102,7 +101,7 @@ func TestMultipleAttachRestart(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -136,7 +135,7 @@ func TestDiff(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
// Create a container and remove a file
container1, _ := mkContainer(runtime, []string{"_", "/bin/rm", "/etc/passwd"}, t)
container1, _, _ := mkContainer(runtime, []string{"_", "/bin/rm", "/etc/passwd"}, t)
defer runtime.Destroy(container1)
// The changelog should be empty and not fail before run. See #1705
@@ -178,7 +177,7 @@ func TestDiff(t *testing.T) {
}
// Create a new container from the commited image
container2, _ := mkContainer(runtime, []string{img.ID, "cat", "/etc/passwd"}, t)
container2, _, _ := mkContainer(runtime, []string{img.ID, "cat", "/etc/passwd"}, t)
defer runtime.Destroy(container2)
if err := container2.Run(); err != nil {
@@ -197,7 +196,7 @@ func TestDiff(t *testing.T) {
}
// Create a new container
container3, _ := mkContainer(runtime, []string{"_", "rm", "/bin/httpd"}, t)
container3, _, _ := mkContainer(runtime, []string{"_", "rm", "/bin/httpd"}, t)
defer runtime.Destroy(container3)
if err := container3.Run(); err != nil {
@@ -223,7 +222,7 @@ func TestDiff(t *testing.T) {
func TestCommitAutoRun(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container1, _ := mkContainer(runtime, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
container1, _, _ := mkContainer(runtime, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
defer runtime.Destroy(container1)
if container1.State.Running {
@@ -246,7 +245,7 @@ func TestCommitAutoRun(t *testing.T) {
}
// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
container2, _ := mkContainer(runtime, []string{img.ID}, t)
container2, hostConfig, _ := mkContainer(runtime, []string{img.ID}, t)
defer runtime.Destroy(container2)
stdout, err := container2.StdoutPipe()
if err != nil {
@@ -256,7 +255,7 @@ func TestCommitAutoRun(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container2.Start(); err != nil {
if err := container2.Start(hostConfig); err != nil {
t.Fatal(err)
}
container2.Wait()
@@ -283,7 +282,7 @@ func TestCommitRun(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container1, _ := mkContainer(runtime, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
container1, hostConfig, _ := mkContainer(runtime, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
defer runtime.Destroy(container1)
if container1.State.Running {
@@ -306,7 +305,7 @@ func TestCommitRun(t *testing.T) {
}
// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
container2, _ := mkContainer(runtime, []string{img.ID, "cat", "/world"}, t)
container2, hostConfig, _ := mkContainer(runtime, []string{img.ID, "cat", "/world"}, t)
defer runtime.Destroy(container2)
stdout, err := container2.StdoutPipe()
if err != nil {
@@ -316,7 +315,7 @@ func TestCommitRun(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container2.Start(); err != nil {
if err := container2.Start(hostConfig); err != nil {
t.Fatal(err)
}
container2.Wait()
@@ -342,7 +341,7 @@ func TestCommitRun(t *testing.T) {
func TestStart(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container, _ := mkContainer(runtime, []string{"-m", "33554432", "-c", "1000", "-i", "_", "/bin/cat"}, t)
container, hostConfig, _ := mkContainer(runtime, []string{"-m", "33554432", "-c", "1000", "-i", "_", "/bin/cat"}, t)
defer runtime.Destroy(container)
cStdin, err := container.StdinPipe()
@@ -350,7 +349,7 @@ func TestStart(t *testing.T) {
t.Fatal(err)
}
if err := container.Start(); err != nil {
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -360,7 +359,7 @@ func TestStart(t *testing.T) {
if !container.State.Running {
t.Errorf("Container should be running")
}
if err := container.Start(); err == nil {
if err := container.Start(hostConfig); err == nil {
t.Fatalf("A running container should be able to be started")
}
@@ -372,7 +371,7 @@ func TestStart(t *testing.T) {
func TestRun(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container, _ := mkContainer(runtime, []string{"_", "ls", "-al"}, t)
container, _, _ := mkContainer(runtime, []string{"_", "ls", "-al"}, t)
defer runtime.Destroy(container)
if container.State.Running {
@@ -394,7 +393,6 @@ func TestOutput(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"echo", "-n", "foobar"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -409,28 +407,6 @@ func TestOutput(t *testing.T) {
}
}
func TestContainerNetwork(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container, _, err := runtime.Create(
&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"ping", "-c", "1", "127.0.0.1"},
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
if err := container.Run(); err != nil {
t.Fatal(err)
}
if container.State.ExitCode != 0 {
t.Errorf("Unexpected ping 127.0.0.1 exit code %d (expected 0)", container.State.ExitCode)
}
}
func TestKillDifferentUser(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
@@ -441,7 +417,6 @@ func TestKillDifferentUser(t *testing.T) {
OpenStdin: true,
User: "daemon",
},
"",
)
if err != nil {
t.Fatal(err)
@@ -452,7 +427,7 @@ func TestKillDifferentUser(t *testing.T) {
if container.State.Running {
t.Errorf("Container shouldn't be running")
}
if err := container.Start(); err != nil {
if err := container.Start(&HostConfig{}); err != nil {
t.Fatal(err)
}
@@ -496,13 +471,12 @@ func TestCreateVolume(t *testing.T) {
if err != nil {
t.Fatal(err)
}
c, _, err := runtime.Create(config, "")
c, _, err := runtime.Create(config)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(c)
c.hostConfig = hc
if err := c.Start(); err != nil {
if err := c.Start(hc); err != nil {
t.Fatal(err)
}
c.WaitTimeout(500 * time.Millisecond)
@@ -516,7 +490,6 @@ func TestKill(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"sleep", "2"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -526,7 +499,8 @@ func TestKill(t *testing.T) {
if container.State.Running {
t.Errorf("Container shouldn't be running")
}
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -559,7 +533,7 @@ func TestExitCode(t *testing.T) {
trueContainer, _, err := runtime.Create(&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/true", ""},
}, "")
})
if err != nil {
t.Fatal(err)
}
@@ -574,7 +548,7 @@ func TestExitCode(t *testing.T) {
falseContainer, _, err := runtime.Create(&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/false", ""},
}, "")
})
if err != nil {
t.Fatal(err)
}
@@ -594,7 +568,6 @@ func TestRestart(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"echo", "-n", "foobar"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -627,7 +600,6 @@ func TestRestartStdin(t *testing.T) {
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -642,7 +614,8 @@ func TestRestartStdin(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
if _, err := io.WriteString(stdin, "hello world"); err != nil {
@@ -672,7 +645,7 @@ func TestRestartStdin(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
if _, err := io.WriteString(stdin, "hello world #2"); err != nil {
@@ -703,7 +676,6 @@ func TestUser(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"id"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -724,7 +696,6 @@ func TestUser(t *testing.T) {
User: "root",
},
"",
)
if err != nil {
t.Fatal(err)
@@ -745,7 +716,6 @@ func TestUser(t *testing.T) {
User: "0",
},
"",
)
if err != nil || container.State.ExitCode != 0 {
t.Fatal(err)
@@ -766,7 +736,6 @@ func TestUser(t *testing.T) {
User: "1",
},
"",
)
if err != nil {
t.Fatal(err)
@@ -789,7 +758,6 @@ func TestUser(t *testing.T) {
User: "daemon",
},
"",
)
if err != nil {
t.Fatal(err)
@@ -810,7 +778,6 @@ func TestUser(t *testing.T) {
User: "unknownuser",
},
"",
)
if err != nil {
t.Fatal(err)
@@ -830,7 +797,6 @@ func TestMultipleContainers(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"sleep", "2"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -841,7 +807,6 @@ func TestMultipleContainers(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"sleep", "2"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -849,10 +814,11 @@ func TestMultipleContainers(t *testing.T) {
defer runtime.Destroy(container2)
// Start both containers
if err := container1.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container1.Start(hostConfig); err != nil {
t.Fatal(err)
}
if err := container2.Start(); err != nil {
if err := container2.Start(hostConfig); err != nil {
t.Fatal(err)
}
@@ -887,7 +853,6 @@ func TestStdin(t *testing.T) {
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -902,7 +867,8 @@ func TestStdin(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
defer stdin.Close()
@@ -932,7 +898,6 @@ func TestTty(t *testing.T) {
OpenStdin: true,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -947,7 +912,8 @@ func TestTty(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
defer stdin.Close()
@@ -969,15 +935,13 @@ func TestTty(t *testing.T) {
}
func TestEnv(t *testing.T) {
os.Setenv("TRUE", "false")
os.Setenv("TRICKY", "tri\ncky\n")
runtime := mkRuntime(t)
defer nuke(runtime)
config, _, _, err := ParseRun([]string{"-e=FALSE=true", "-e=TRUE", "-e=TRICKY", GetTestImage(runtime).ID, "env"}, nil)
if err != nil {
t.Fatal(err)
}
container, _, err := runtime.Create(config, "")
container, _, err := runtime.Create(&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"env"},
},
)
if err != nil {
t.Fatal(err)
}
@@ -988,7 +952,8 @@ func TestEnv(t *testing.T) {
t.Fatal(err)
}
defer stdout.Close()
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
t.Fatal(err)
}
container.Wait()
@@ -1006,11 +971,6 @@ func TestEnv(t *testing.T) {
"HOME=/",
"container=lxc",
"HOSTNAME=" + container.ShortID(),
"FALSE=true",
"TRUE=false",
"TRICKY=tri",
"cky",
"",
}
sort.Strings(goodEnv)
if len(goodEnv) != len(actualEnv) {
@@ -1032,7 +992,6 @@ func TestEntrypoint(t *testing.T) {
Entrypoint: []string{"/bin/echo"},
Cmd: []string{"-n", "foobar"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1055,7 +1014,6 @@ func TestEntrypointNoCmd(t *testing.T) {
Image: GetTestImage(runtime).ID,
Entrypoint: []string{"/bin/echo", "foobar"},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1110,13 +1068,12 @@ func TestLXCConfig(t *testing.T) {
Memory: int64(mem),
CpuShares: int64(cpu),
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
container.generateLXCConfig()
container.generateLXCConfig(nil)
grepFile(t, container.lxcConfigPath(), "lxc.utsname = foobar")
grepFile(t, container.lxcConfigPath(),
fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem))
@@ -1133,13 +1090,12 @@ func TestCustomLxcConfig(t *testing.T) {
Hostname: "foobar",
},
"",
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
container.hostConfig = &HostConfig{LxcConf: []KeyValuePair{
hostConfig := &HostConfig{LxcConf: []KeyValuePair{
{
Key: "lxc.utsname",
Value: "docker",
@@ -1150,7 +1106,7 @@ func TestCustomLxcConfig(t *testing.T) {
},
}}
container.generateLXCConfig()
container.generateLXCConfig(hostConfig)
grepFile(t, container.lxcConfigPath(), "lxc.utsname = docker")
grepFile(t, container.lxcConfigPath(), "lxc.cgroup.cpuset.cpus = 0,1")
}
@@ -1163,7 +1119,6 @@ func BenchmarkRunSequencial(b *testing.B) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"echo", "-n", "foo"},
},
"",
)
if err != nil {
b.Fatal(err)
@@ -1196,14 +1151,14 @@ func BenchmarkRunParallel(b *testing.B) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"echo", "-n", "foo"},
},
"",
)
if err != nil {
complete <- err
return
}
defer runtime.Destroy(container)
if err := container.Start(); err != nil {
hostConfig := &HostConfig{}
if err := container.Start(hostConfig); err != nil {
complete <- err
return
}
@@ -1234,7 +1189,7 @@ func BenchmarkRunParallel(b *testing.B) {
}
func tempDir(t *testing.T) string {
tmpDir, err := ioutil.TempDir("", "docker-test-container")
tmpDir, err := ioutil.TempDir("", "docker-test")
if err != nil {
t.Fatal(err)
}
@@ -1247,7 +1202,7 @@ func TestCopyVolumeUidGid(t *testing.T) {
defer nuke(r)
// Add directory not owned by root
container1, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && touch /hello/test.txt && chown daemon.daemon /hello"}, t)
container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && touch /hello/test.txt && chown daemon.daemon /hello"}, t)
defer r.Destroy(container1)
if container1.State.Running {
@@ -1284,7 +1239,7 @@ func TestCopyVolumeContent(t *testing.T) {
defer nuke(r)
// Put some content in a directory of a container and commit it
container1, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello/local && echo hello > /hello/local/world"}, t)
container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello/local && echo hello > /hello/local/world"}, t)
defer r.Destroy(container1)
if container1.State.Running {
@@ -1348,7 +1303,6 @@ func TestVolumesFromReadonlyMount(t *testing.T) {
Cmd: []string{"/bin/echo", "-n", "foobar"},
Volumes: map[string]struct{}{"/test": {}},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1368,7 +1322,6 @@ func TestVolumesFromReadonlyMount(t *testing.T) {
Cmd: []string{"/bin/echo", "-n", "foobar"},
VolumesFrom: container.ID,
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1404,7 +1357,6 @@ func TestRestartWithVolumes(t *testing.T) {
Cmd: []string{"echo", "-n", "foobar"},
Volumes: map[string]struct{}{"/test": {}},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1448,7 +1400,6 @@ func TestVolumesFromWithVolumes(t *testing.T) {
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
Volumes: map[string]struct{}{"/test": {}},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1478,7 +1429,6 @@ func TestVolumesFromWithVolumes(t *testing.T) {
VolumesFrom: container.ID,
Volumes: map[string]struct{}{"/test": {}},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1513,7 +1463,7 @@ func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
if err != nil {
t.Fatal(err)
}
c, _, err := runtime.Create(config, "")
c, _, err := runtime.Create(config)
if err != nil {
t.Fatal(err)
}
@@ -1521,9 +1471,9 @@ func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(c)
c.hostConfig = hc
if err := c.Start(); err != nil {
if err := c.Start(hc); err != nil {
t.Fatal(err)
}
c.WaitTimeout(500 * time.Millisecond)
@@ -1584,7 +1534,6 @@ func TestMultipleVolumesFrom(t *testing.T) {
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
Volumes: map[string]struct{}{"/test": {}},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1613,7 +1562,6 @@ func TestMultipleVolumesFrom(t *testing.T) {
Cmd: []string{"sh", "-c", "echo -n bar > /other/foo"},
Volumes: map[string]struct{}{"/other": {}},
},
"",
)
if err != nil {
t.Fatal(err)
@@ -1634,7 +1582,7 @@ func TestMultipleVolumesFrom(t *testing.T) {
Image: GetTestImage(runtime).ID,
Cmd: []string{"/bin/echo", "-n", "foobar"},
VolumesFrom: strings.Join([]string{container.ID, container2.ID}, ","),
}, "")
})
if err != nil {
t.Fatal(err)
@@ -1645,6 +1593,7 @@ func TestMultipleVolumesFrom(t *testing.T) {
t.Fatal(err)
}
t.Log(container3.Volumes)
if container3.Volumes["/test"] != container.Volumes["/test"] {
t.Fail()
}
@@ -1652,31 +1601,3 @@ func TestMultipleVolumesFrom(t *testing.T) {
t.Fail()
}
}
func TestRestartGhost(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container, _, err := runtime.Create(
&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
Volumes: map[string]struct{}{"/test": {}},
},
"",
)
if err != nil {
t.Fatal(err)
}
if err := container.Kill(); err != nil {
t.Fatal(err)
}
container.State.Ghost = true
_, err = container.Output()
if err != nil {
t.Fatal(err)
}
}
@@ -1,23 +0,0 @@
# [PackageDev] target_format: plist, ext: tmLanguage
---
name: Dockerfile
scopeName: source.dockerfile
uuid: a39d8795-59d2-49af-aa00-fe74ee29576e
patterns:
# Keywords
- name: keyword.control.dockerfile
match: ^\s*(FROM|MAINTAINER|RUN|CMD|EXPOSE|ENV|ADD)\s
- name: keyword.operator.dockerfile
match: ^\s*(ENTRYPOINT|VOLUME|USER|WORKDIR)\s
# String
- name: string.quoted.double.dockerfile
begin: "\""
end: "\""
patterns:
- name: constant.character.escaped.dockerfile
match: \\.
# Comment
- name: comment.block.dockerfile
match: ^\s*#.*$
...
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>Dockerfile</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>^\s*(FROM|MAINTAINER|RUN|CMD|EXPOSE|ENV|ADD)\s</string>
<key>name</key>
<string>keyword.control.dockerfile</string>
</dict>
<dict>
<key>match</key>
<string>^\s*(ENTRYPOINT|VOLUME|USER|WORKDIR)\s</string>
<key>name</key>
<string>keyword.operator.dockerfile</string>
</dict>
<dict>
<key>begin</key>
<string>"</string>
<key>end</key>
<string>"</string>
<key>name</key>
<string>string.quoted.double.dockerfile</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escaped.dockerfile</string>
</dict>
</array>
</dict>
<dict>
<key>match</key>
<string>^\s*#.*$</string>
<key>name</key>
<string>comment.block.dockerfile</string>
</dict>
</array>
<key>scopeName</key>
<string>source.dockerfile</string>
<key>uuid</key>
<string>a39d8795-59d2-49af-aa00-fe74ee29576e</string>
</dict>
</plist>
@@ -1 +0,0 @@
Asbjorn Enge <asbjorn@hanafjedle.net> (@asbjornenge)
-9
View File
@@ -1,9 +0,0 @@
# Dockerfile.tmLanguage
Pretty basic Dockerfile.tmLanguage for Sublime Text syntax highlighting.
PR's with syntax updates, suggestions etc. are all very much appreciated!
I'll get to making this installable via Package Control soon!
enjoy.
+1
View File
@@ -1 +1,2 @@
Kawsar Saiyeed <kawsar.saiyeed@projiris.com> (@KSid)
Tianon Gravi <admwiggin@gmail.com> (@tianon)
+1
View File
@@ -0,0 +1 @@
*.pyc
+78
View File
@@ -0,0 +1,78 @@
# docker-brew
docker-brew is a command-line tool used to build the docker standard library.
## Install instructions
1. Install python if it isn't already available on your OS of choice
1. Install the easy_install tool (`sudo apt-get install python-setuptools`
for Debian)
1. Install the python package manager, `pip` (`easy_install pip`)
1. Run the following command: `sudo pip install -r requirements.txt`
1. You should now be able to use the `docker-brew` script as such.
## Basics
./docker-brew -h
Display usage and help.
./docker-brew
Default build from the default repo/branch. Images will be created under the
`library/` namespace. Does not perform a remote push.
./docker-brew -n mycorp.com -b stable --push git://github.com/mycorp/docker
Will fetch the library definition files in the `stable` branch of the
`git://github.com/mycorp/docker` repository and create images under the
`mycorp.com` namespace (e.g. `mycorp.com/ubuntu`). Created images will then
be pushed to the official docker repository (pending: support for private
repositories)
## Library definition files
The library definition files are plain text files found in the `library/`
subfolder of the docker repository.
### File names
The name of a definition file will determine the name of the image(s) it
creates. For example, the `library/ubuntu` file will create images in the
`<namespace>/ubuntu` repository. If multiple instructions are present in
a single file, all images are expected to be created under a different tag.
### Instruction format
Each line represents a build instruction.
There are different formats that `docker-brew` is able to parse.
<git-url>
git://github.com/dotcloud/hipache
https://github.com/dotcloud/docker.git
The simplest format. `docker-brew` will fetch data from the provided git
repository from the `HEAD`of its `master` branch. Generated image will be
tagged as `latest`. Use of this format is discouraged because there is no
way to ensure stability.
<docker-tag> <git-url>
bleeding-edge git://github.com/dotcloud/docker
unstable https://github.com/dotcloud/docker-redis.git
A more advanced format. `docker-brew` will fetch data from the provided git
repository from the `HEAD`of its `master` branch. Generated image will be
tagged as `<docker-tag>`. Recommended if we always want to provide a snapshot
of the latest development. Again, no way to ensure stability.
<docker-tag> <git-url> T:<git-tag>
2.4.0 git://github.com/dotcloud/docker-redis T:2.4.0
<docker-tag> <git-url> B:<git-branch>
zfs git://github.com/dotcloud/docker B:zfs-support
<docker-tag> <git-url> C:<git-commit-id>
2.2.0 https://github.com/dotcloud/docker-redis.git C:a4bf8923ee4ec566d3ddc212
The most complete format. `docker-brew` will fetch data from the provided git
repository from the provided reference (if it's a branch, brew will fetch its
`HEAD`). Generated image will be tagged as `<docker-tag>`. Recommended whenever
possible.
+1
View File
@@ -0,0 +1 @@
from brew import build_library, DEFAULT_REPOSITORY, DEFAULT_BRANCH
+185
View File
@@ -0,0 +1,185 @@
import os
import logging
from shutil import rmtree
import docker
import git
DEFAULT_REPOSITORY = 'git://github.com/dotcloud/docker'
DEFAULT_BRANCH = 'master'
logger = logging.getLogger(__name__)
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
level='INFO')
client = docker.Client()
processed = {}
processed_folders = []
def build_library(repository=None, branch=None, namespace=None, push=False,
debug=False, prefill=True, registry=None):
dst_folder = None
summary = Summary()
if repository is None:
repository = DEFAULT_REPOSITORY
if branch is None:
branch = DEFAULT_BRANCH
if debug:
logger.setLevel('DEBUG')
if not (repository.startswith('https://') or repository.startswith('git://')):
logger.info('Repository provided assumed to be a local path')
dst_folder = repository
try:
client.version()
except Exception as e:
logger.error('Could not reach the docker daemon. Please make sure it '
'is running.')
logger.warning('Also make sure you have access to the docker UNIX '
'socket (use sudo)')
return
#FIXME: set destination folder and only pull latest changes instead of
# cloning the whole repo everytime
if not dst_folder:
logger.info('Cloning docker repo from {0}, branch: {1}'.format(
repository, branch))
try:
rep, dst_folder = git.clone_branch(repository, branch)
except Exception as e:
logger.exception(e)
logger.error('Source repository could not be fetched. Check '
'that the address is correct and the branch exists.')
return
try:
dirlist = os.listdir(os.path.join(dst_folder, 'library'))
except OSError as e:
logger.error('The path provided ({0}) could not be found or didn\'t'
'contain a library/ folder.'.format(dst_folder))
return
for buildfile in dirlist:
if buildfile == 'MAINTAINERS':
continue
f = open(os.path.join(dst_folder, 'library', buildfile))
linecnt = 0
for line in f:
linecnt = linecnt + 1
logger.debug('{0} ---> {1}'.format(buildfile, line))
args = line.split()
try:
if len(args) > 3:
raise RuntimeError('Incorrect line format, '
'please refer to the docs')
url = None
ref = 'refs/heads/master'
tag = None
if len(args) == 1: # Just a URL, simple mode
url = args[0]
elif len(args) == 2 or len(args) == 3: # docker-tag url
url = args[1]
tag = args[0]
if len(args) == 3: # docker-tag url B:branch or T:tag
ref = None
if args[2].startswith('B:'):
ref = 'refs/heads/' + args[2][2:]
elif args[2].startswith('T:'):
ref = 'refs/tags/' + args[2][2:]
elif args[2].startswith('C:'):
ref = args[2][2:]
else:
raise RuntimeError('Incorrect line format, '
'please refer to the docs')
if prefill:
logger.debug('Pulling {0} from official repository (cache '
'fill)'.format(buildfile))
client.pull(buildfile)
img = build_repo(url, ref, buildfile, tag, namespace, push,
registry)
summary.add_success(buildfile, (linecnt, line), img)
processed['{0}@{1}'.format(url, ref)] = img
except Exception as e:
logger.exception(e)
summary.add_exception(buildfile, (linecnt, line), e)
f.close()
if dst_folder != repository:
rmtree(dst_folder, True)
for d in processed_folders:
rmtree(d, True)
summary.print_summary(logger)
def build_repo(repository, ref, docker_repo, docker_tag, namespace, push, registry):
docker_repo = '{0}/{1}'.format(namespace or 'library', docker_repo)
img_id = None
dst_folder = None
if '{0}@{1}'.format(repository, ref) not in processed.keys():
logger.info('Cloning {0} (ref: {1})'.format(repository, ref))
if repository not in processed:
rep, dst_folder = git.clone(repository, ref)
processed[repository] = rep
processed_folders.append(dst_folder)
else:
dst_folder = git.checkout(processed[repository], ref)
if not 'Dockerfile' in os.listdir(dst_folder):
raise RuntimeError('Dockerfile not found in cloned repository')
logger.info('Building using dockerfile...')
img_id, logs = client.build(path=dst_folder, quiet=True)
else:
img_id = processed['{0}@{1}'.format(repository, ref)]
logger.info('Committing to {0}:{1}'.format(docker_repo,
docker_tag or 'latest'))
client.tag(img_id, docker_repo, docker_tag)
if push:
logger.info('Pushing result to registry {0}'.format(
registry or "default"))
if registry is not None:
docker_repo = '{0}/{1}'.format(registry, docker_repo)
logger.info('Also tagging {0}'.format(docker_repo))
client.tag(img_id, docker_repo, docker_tag)
client.push(docker_repo)
return img_id
class Summary(object):
def __init__(self):
self._summary = {}
self._has_exc = False
def _add_data(self, image, linestr, data):
if image not in self._summary:
self._summary[image] = { linestr: data }
else:
self._summary[image][linestr] = data
def add_exception(self, image, line, exc):
lineno, linestr = line
self._add_data(image, linestr, { 'line': lineno, 'exc': str(exc) })
self._has_exc = True
def add_success(self, image, line, img_id):
lineno, linestr = line
self._add_data(image, linestr, { 'line': lineno, 'id': img_id })
def print_summary(self, logger=None):
linesep = ''.center(61, '-') + '\n'
s = 'BREW BUILD SUMMARY\n' + linesep
success = 'OVERALL SUCCESS: {}\n'.format(not self._has_exc)
details = linesep
for image, lines in self._summary.iteritems():
details = details + '{}\n{}'.format(image, linesep)
for linestr, data in lines.iteritems():
details = details + '{0:2} | {1} | {2:50}\n'.format(
data['line'],
'KO' if 'exc' in data else 'OK',
data['exc'] if 'exc' in data else data['id']
)
details = details + linesep
if logger:
logger.info(s + success + details)
else:
print s, success, details
+63
View File
@@ -0,0 +1,63 @@
import tempfile
import logging
from dulwich import index
from dulwich.client import get_transport_and_path
from dulwich.repo import Repo
logger = logging.getLogger(__name__)
def clone_branch(repo_url, branch="master", folder=None):
return clone(repo_url, 'refs/heads/' + branch, folder)
def clone_tag(repo_url, tag, folder=None):
return clone(repo_url, 'refs/tags/' + tag, folder)
def checkout(rep, ref=None):
is_commit = False
if ref is None:
ref = 'refs/heads/master'
elif not ref.startswith('refs/'):
is_commit = True
if is_commit:
rep['HEAD'] = rep.commit(ref)
else:
rep['HEAD'] = rep.refs[ref]
indexfile = rep.index_path()
tree = rep["HEAD"].tree
index.build_index_from_tree(rep.path, indexfile, rep.object_store, tree)
return rep.path
def clone(repo_url, ref=None, folder=None):
is_commit = False
if ref is None:
ref = 'refs/heads/master'
elif not ref.startswith('refs/'):
is_commit = True
logger.debug("clone repo_url={0}, ref={1}".format(repo_url, ref))
if folder is None:
folder = tempfile.mkdtemp()
logger.debug("folder = {0}".format(folder))
rep = Repo.init(folder)
client, relative_path = get_transport_and_path(repo_url)
logger.debug("client={0}".format(client))
remote_refs = client.fetch(relative_path, rep)
for k, v in remote_refs.iteritems():
try:
rep.refs.add_if_new(k, v)
except:
pass
if is_commit:
rep['HEAD'] = rep.commit(ref)
else:
rep['HEAD'] = remote_refs[ref]
indexfile = rep.index_path()
tree = rep["HEAD"].tree
index.build_index_from_tree(rep.path, indexfile, rep.object_store, tree)
logger.debug("done")
return rep, folder
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env python
import argparse
import sys
try:
import brew
except ImportError as e:
print str(e)
print 'Please install the required dependencies first'
print 'sudo pip install -r requirements.txt'
sys.exit(1)
if __name__ == '__main__':
parser = argparse.ArgumentParser('Build the docker standard library')
parser.add_argument('--push', action='store_true', default=False,
help='Push generated repositories')
parser.add_argument('--debug', default=False, action='store_true',
help='Enable debugging output')
parser.add_argument('--noprefill', default=True, action='store_false',
dest='prefill', help='Disable cache prefill')
parser.add_argument('-n', metavar='NAMESPACE', default='library',
help='Namespace used for generated repositories.'
' Default is library')
parser.add_argument('-b', metavar='BRANCH', default=brew.DEFAULT_BRANCH,
help='Branch in the repository where the library definition'
' files will be fetched. Default is ' + brew.DEFAULT_BRANCH)
parser.add_argument('repository', default=brew.DEFAULT_REPOSITORY,
nargs='?', help='git repository containing the library definition'
' files. Default is ' + brew.DEFAULT_REPOSITORY)
parser.add_argument('--reg', default=None, help='Registry address to'
' push build results to. Also sets push to true.')
args = parser.parse_args()
brew.build_library(args.repository, args.b, args.n,
args.push or args.reg is not None, args.debug, args.prefill, args.reg)
+2
View File
@@ -0,0 +1,2 @@
dulwich==0.9.0
-e git://github.com/dotcloud/docker-py.git#egg=docker-py
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
from setuptools import setup
ROOT_DIR = os.path.dirname(__file__)
SOURCE_DIR = os.path.join(ROOT_DIR)
test_requirements = []
setup(
name="docker-brew",
version='0.0.1',
description="-",
packages=['dockerbrew'],
install_requires=['dulwich', 'docker'] + test_requirements,
zip_safe=False,
classifiers=['Development Status :: 3 - Alpha',
'Environment :: Other Environment',
'Intended Audience :: Developers',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Utilities'],
)
-242
View File
@@ -1,242 +0,0 @@
#compdef docker
#
# zsh completion for docker (http://docker.io)
#
# version: 0.2.2
# author: Felix Riedel
# license: BSD License
# github: https://github.com/felixr/docker-zsh-completion
#
__parse_docker_list() {
sed -e '/^ID/d' -e 's/[ ]\{2,\}/|/g' -e 's/ \([hdwm]\)\(inutes\|ays\|ours\|eeks\)/\1/' | awk ' BEGIN {FS="|"} { printf("%s:%7s, %s\n", $1, $4, $2)}'
}
__docker_stoppedcontainers() {
local expl
declare -a stoppedcontainers
stoppedcontainers=(${(f)"$(docker ps -a | grep --color=never 'Exit' | __parse_docker_list )"})
_describe -t containers-stopped "Stopped Containers" stoppedcontainers
}
__docker_runningcontainers() {
local expl
declare -a containers
containers=(${(f)"$(docker ps | __parse_docker_list)"})
_describe -t containers-active "Running Containers" containers
}
__docker_containers () {
__docker_stoppedcontainers
__docker_runningcontainers
}
__docker_images () {
local expl
declare -a images
images=(${(f)"$(docker images | awk '(NR > 1){printf("%s\\:%s\n", $1,$2)}')"})
images=($images ${(f)"$(docker images | awk '(NR > 1){printf("%s:%-15s in %s\n", $3,$2,$1)}')"})
_describe -t docker-images "Images" images
}
__docker_tags() {
local expl
declare -a tags
tags=(${(f)"$(docker images | awk '(NR>1){print $2}'| sort | uniq)"})
_describe -t docker-tags "tags" tags
}
__docker_search() {
# declare -a dockersearch
local cache_policy
zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
if [[ -z "$cache_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
fi
local searchterm cachename
searchterm="${words[$CURRENT]%/}"
cachename=_docker-search-$searchterm
local expl
local -a result
if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
&& ! _retrieve_cache ${cachename#_}; then
_message "Searching for ${searchterm}..."
result=(${(f)"$(docker search ${searchterm} | awk '(NR>2){print $1}')"})
_store_cache ${cachename#_} result
fi
_wanted dockersearch expl 'Available images' compadd -a result
}
__docker_caching_policy()
{
# oldp=( "$1"(Nmh+24) ) # 24 hour
oldp=( "$1"(Nmh+1) ) # 24 hour
(( $#oldp ))
}
__docker_repositories () {
local expl
declare -a repos
repos=(${(f)"$(docker images | sed -e '1d' -e 's/[ ].*//' | sort | uniq)"})
_describe -t docker-repos "Repositories" repos
}
__docker_commands () {
# local -a _docker_subcommands
local cache_policy
zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
if [[ -z "$cache_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
fi
if ( [[ ${+_docker_subcommands} -eq 0 ]] || _cache_invalid docker_subcommands) \
&& ! _retrieve_cache docker_subcommands;
then
_docker_subcommands=(${${(f)"$(_call_program commands
docker 2>&1 | sed -e '1,6d' -e '/^[ ]*$/d' -e 's/[ ]*\([^ ]\+\)\s*\([^ ].*\)/\1:\2/' )"}})
_docker_subcommands=($_docker_subcommands 'help:Show help for a command')
_store_cache docker_subcommands _docker_subcommands
fi
_describe -t docker-commands "docker command" _docker_subcommands
}
__docker_subcommand () {
local -a _command_args
case "$words[1]" in
(attach|wait)
_arguments ':containers:__docker_runningcontainers'
;;
(build)
_arguments \
'-t=-:repository:__docker_repositories' \
':path or URL:_directories'
;;
(commit)
_arguments \
':container:__docker_containers' \
':repository:__docker_repositories' \
':tag: '
;;
(diff|export|logs)
_arguments '*:containers:__docker_containers'
;;
(history)
_arguments '*:images:__docker_images'
;;
(images)
_arguments \
'-a[Show all images]' \
':repository:__docker_repositories'
;;
(inspect)
_arguments '*:containers:__docker_containers'
;;
(history)
_arguments ':images:__docker_images'
;;
(insert)
_arguments '1:containers:__docker_containers' \
'2:URL:(http:// file://)' \
'3:file:_files'
;;
(kill)
_arguments '*:containers:__docker_runningcontainers'
;;
(port)
_arguments '1:containers:__docker_runningcontainers'
;;
(start)
_arguments '*:containers:__docker_stoppedcontainers'
;;
(rm)
_arguments '-v[Remove the volumes associated to the container]' \
'*:containers:__docker_stoppedcontainers'
;;
(rmi)
_arguments '-v[Remove the volumes associated to the container]' \
'*:images:__docker_images'
;;
(top)
_arguments '1:containers:__docker_runningcontainers'
;;
(restart|stop)
_arguments '-t=-[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)' \
'*:containers:__docker_runningcontainers'
;;
(top)
_arguments ':containers:__docker_runningcontainers'
;;
(ps)
_arguments '-a[Show all containers. Only running containers are shown by default]' \
'-h[Show help]' \
'-beforeId=-[Show only container created before Id, include non-running one]:containers:__docker_containers' \
'-n=-[Show n last created containers, include non-running one]:n:(1 5 10 25 50)'
;;
(tag)
_arguments \
'-f[force]'\
':image:__docker_images'\
':repository:__docker_repositories' \
':tag:__docker_tags'
;;
(run)
_arguments \
'-a=-[Attach to stdin, stdout or stderr]:toggle:(true false)' \
'-c=-[CPU shares (relative weight)]:CPU shares: ' \
'-d[Detached mode: leave the container running in the background]' \
'*-dns=[Set custom dns servers]:dns server: ' \
'*-e=[Set environment variables]:environment variable: ' \
'-entrypoint=-[Overwrite the default entrypoint of the image]:entry point: ' \
'-h=-[Container host name]:hostname:_hosts' \
'-i[Keep stdin open even if not attached]' \
'-m=-[Memory limit (in bytes)]:limit: ' \
'*-p=-[Expose a container''s port to the host]:port:_ports' \
'-t=-[Allocate a pseudo-tty]:toggle:(true false)' \
'-u=-[Username or UID]:user:_users' \
'*-v=-[Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)]:volume: '\
'-volumes-from=-[Mount volumes from the specified container]:volume: ' \
'(-):images:__docker_images' \
'(-):command: _command_names -e' \
'*::arguments: _normal'
;;
(pull|search)
_arguments ':name:__docker_search'
;;
(help)
_arguments ':subcommand:__docker_commands'
;;
(*)
_message 'Unknown sub command'
esac
}
_docker () {
local curcontext="$curcontext" state line
typeset -A opt_args
_arguments -C \
'-H=-[tcp://host:port to bind/connect to]:socket: ' \
'(-): :->command' \
'(-)*:: :->option-or-argument'
if (( CURRENT == 1 )); then
fi
case $state in
(command)
__docker_commands
;;
(option-or-argument)
curcontext=${curcontext%:*:*}:docker-$words[1]:
__docker_subcommand
;;
esac
}
_docker "$@"
-11
View File
@@ -1,11 +0,0 @@
Desktop Integration
===================
The ./contrib/desktop-integration contains examples of typical dockerized
desktop applications.
Examples
========
* Data container: ./data/Dockerfile creates a data image sharing /data volume
* Firefox: ./firefox/Dockerfile shows a way to dockerize a common multimedia application
@@ -1,38 +0,0 @@
# VERSION: 0.1
# DESCRIPTION: Create data image sharing /data volume
# AUTHOR: Daniel Mizyrycki <daniel@dotcloud.com>
# COMMENTS:
# This image is used as base for all data containers.
# /data volume is owned by sysadmin.
# USAGE:
# # Download data Dockerfile
# wget http://raw.github.com/dotcloud/docker/master/contrib/desktop-integration/data/Dockerfile
#
# # Build data image
# docker build -t data -rm .
#
# # Create a data container. (eg: firefox-data)
# docker run -name firefox-data data true
#
# # List data from it
# docker run -volumes-from firefox-data busybox ls -al /data
docker-version 0.6.5
# Smallest base image, just to launch a container
from busybox
maintainer Daniel Mizyrycki <daniel@docker.com>
# Create a regular user
run echo 'sysadmin:x:1000:1000::/data:/bin/sh' >> /etc/passwd
run echo 'sysadmin:x:1000:' >> /etc/group
# Create directory for that user
run mkdir /data
run chown sysadmin.sysadmin /data
# Add content to /data. This will keep sysadmin ownership
run touch /data/init_volume
# Create /data volume
VOLUME /data
@@ -1,49 +0,0 @@
# VERSION: 0.7
# DESCRIPTION: Create firefox container with its dependencies
# AUTHOR: Daniel Mizyrycki <daniel@dotcloud.com>
# COMMENTS:
# This file describes how to build a Firefox container with all
# dependencies installed. It uses native X11 unix socket and alsa
# sound devices. Tested on Debian 7.2
# USAGE:
# # Download Firefox Dockerfile
# wget http://raw.github.com/dotcloud/docker/master/contrib/desktop-integration/firefox/Dockerfile
#
# # Build firefox image
# docker build -t firefox -rm .
#
# # Run stateful data-on-host firefox. For ephemeral, remove -v /data/firefox:/data
# docker run -v /data/firefox:/data -v /tmp/.X11-unix:/tmp/.X11-unix \
# -v /dev/snd:/dev/snd -lxc-conf='lxc.cgroup.devices.allow = c 116:* rwm' \
# -e DISPLAY=unix$DISPLAY firefox
#
# # To run stateful dockerized data containers
# docker run -volumes-from firefox-data -v /tmp/.X11-unix:/tmp/.X11-unix \
# -v /dev/snd:/dev/snd -lxc-conf='lxc.cgroup.devices.allow = c 116:* rwm' \
# -e DISPLAY=unix$DISPLAY firefox
docker-version 0.6.5
# Base docker image
from tianon/debian:wheezy
maintainer Daniel Mizyrycki <daniel@docker.com>
# Install firefox dependencies
run echo "deb http://ftp.debian.org/debian/ wheezy main contrib" > /etc/apt/sources.list
run apt-get update
run DEBIAN_FRONTEND=noninteractive apt-get install -y libXrender1 libasound2 \
libdbus-glib-1-2 libgtk2.0-0 libpango1.0-0 libxt6 wget bzip2 sudo
# Install Firefox
run mkdir /application
run cd /application; wget -O - \
http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/25.0/linux-x86_64/en-US/firefox-25.0.tar.bz2 | tar jx
# create sysadmin account
run useradd -m -d /data -p saIVpsc0EVTwA sysadmin
run sed -Ei 's/sudo:x:27:/sudo:x:27:sysadmin/' /etc/group
run sed -Ei 's/(\%sudo\s+ALL=\(ALL\:ALL\) )ALL/\1 NOPASSWD:ALL/' /etc/sudoers
# Autorun firefox. -no-remote is necessary to create a new container, as firefox
# appears to communicate with itself through X11.
cmd ["/bin/sh", "-c", "/usr/bin/sudo -u sysadmin -H -E /application/firefox/firefox -no-remote"]
+2 -2
View File
@@ -341,7 +341,7 @@ _docker_pull()
_docker_push()
{
__docker_image_repos
return
}
_docker_restart()
@@ -426,7 +426,7 @@ _docker_run()
_docker_search()
{
COMPREPLY=( $( compgen -W "-notrunc" "-stars" "-trusted" -- "$cur" ) )
COMPREPLY=( $( compgen -W "-notrunc" -- "$cur" ) )
}
_docker_start()
-27
View File
@@ -1,27 +0,0 @@
#
# This Dockerfile will create an image that allows to generate upstart and
# systemd scripts (more to come)
#
# docker-version 0.6.2
#
FROM ubuntu:12.10
MAINTAINER Guillaume J. Charmes <guillaume@dotcloud.com>
RUN apt-get update && apt-get install -y wget git mercurial
# Install Go
RUN wget --no-check-certificate https://go.googlecode.com/files/go1.1.2.linux-amd64.tar.gz -O go-1.1.2.tar.gz
RUN tar -xzvf go-1.1.2.tar.gz && mv /go /goroot
RUN mkdir /go
ENV GOROOT /goroot
ENV GOPATH /go
ENV PATH $GOROOT/bin:$PATH
RUN go get github.com/dotcloud/docker && cd /go/src/github.com/dotcloud/docker && git checkout v0.6.3
ADD manager.go /manager/
RUN cd /manager && go build -o /usr/bin/manager
ENTRYPOINT ["/usr/bin/manager"]
-4
View File
@@ -1,4 +0,0 @@
FROM busybox
MAINTAINER Guillaume J. Charmes <guillaume@dotcloud.com>
ADD manager /usr/bin/
ENTRYPOINT ["/usr/bin/manager"]
-130
View File
@@ -1,130 +0,0 @@
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"github.com/dotcloud/docker"
"os"
"strings"
"text/template"
)
var templates = map[string]string{
"upstart": `description "{{.description}}"
author "{{.author}}"
start on filesystem and started lxc-net and started docker
stop on runlevel [!2345]
respawn
exec /home/vagrant/goroot/bin/docker start -a {{.container_id}}
`,
"systemd": `[Unit]
Description={{.description}}
Author={{.author}}
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a {{.container_id}}
ExecStop=/usr/bin/docker stop -t 2 {{.container_id}}
[Install]
WantedBy=local.target
`,
}
func main() {
// Parse command line for custom options
kind := flag.String("t", "upstart", "Type of manager requested")
author := flag.String("a", "<none>", "Author of the image")
description := flag.String("d", "<none>", "Description of the image")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "\nUsage: manager <container id>\n\n")
flag.PrintDefaults()
}
flag.Parse()
// We require at least the container ID
if flag.NArg() != 1 {
println(flag.NArg())
flag.Usage()
return
}
// Check that the requested process manager is supported
if _, exists := templates[*kind]; !exists {
panic("Unkown script template")
}
// Load the requested template
tpl, err := template.New("processManager").Parse(templates[*kind])
if err != nil {
panic(err)
}
// Create stdout/stderr buffers
bufOut := bytes.NewBuffer(nil)
bufErr := bytes.NewBuffer(nil)
// Instanciate the Docker CLI
cli := docker.NewDockerCli(nil, bufOut, bufErr, "unix", "/var/run/docker.sock")
// Retrieve the container info
if err := cli.CmdInspect(flag.Arg(0)); err != nil {
// As of docker v0.6.3, CmdInspect always returns nil
panic(err)
}
// If there is nothing in the error buffer, then the Docker daemon is there and the container has been found
if bufErr.Len() == 0 {
// Unmarshall the resulting container data
c := []*docker.Container{{}}
if err := json.Unmarshal(bufOut.Bytes(), &c); err != nil {
panic(err)
}
// Reset the buffers
bufOut.Reset()
bufErr.Reset()
// Retrieve the info of the linked image
if err := cli.CmdInspect(c[0].Image); err != nil {
panic(err)
}
// If there is nothing in the error buffer, then the image has been found.
if bufErr.Len() == 0 {
// Unmarshall the resulting image data
img := []*docker.Image{{}}
if err := json.Unmarshal(bufOut.Bytes(), &img); err != nil {
panic(err)
}
// If no author has been set, use the one from the image
if *author == "<none>" && img[0].Author != "" {
*author = strings.Replace(img[0].Author, "\"", "", -1)
}
// If no description has been set, use the comment from the image
if *description == "<none>" && img[0].Comment != "" {
*description = strings.Replace(img[0].Comment, "\"", "", -1)
}
}
}
/// Old version: Wrtie the resulting script to file
// f, err := os.OpenFile(kind, os.O_CREATE|os.O_WRONLY, 0755)
// if err != nil {
// panic(err)
// }
// defer f.Close()
// Create a map with needed data
data := map[string]string{
"author": *author,
"description": *description,
"container_id": flag.Arg(0),
}
// Process the template and output it on Stdout
if err := tpl.Execute(os.Stdout, data); err != nil {
panic(err)
}
}
-53
View File
@@ -1,53 +0,0 @@
#!/bin/sh
set -e
usage() {
echo >&2 "usage: $0 [-a author] [-d description] container [manager]"
echo >&2 " ie: $0 -a 'John Smith' 4ec9612a37cd systemd"
echo >&2 " ie: $0 -d 'Super Cool System' 4ec9612a37cd # defaults to upstart"
exit 1
}
auth='<none>'
desc='<none>'
have_auth=
have_desc=
while getopts a:d: opt; do
case "$opt" in
a)
auth="$OPTARG"
have_auth=1
;;
d)
desc="$OPTARG"
have_desc=1
;;
esac
done
shift $(($OPTIND - 1))
[ $# -ge 1 -a $# -le 2 ] || usage
cid="$1"
script="${2:-upstart}"
if [ ! -e "manager/$script" ]; then
echo >&2 "Error: manager type '$script' is unknown (PRs always welcome!)."
echo >&2 'The currently supported types are:'
echo >&2 " $(cd manager && echo *)"
exit 1
fi
# TODO https://github.com/dotcloud/docker/issues/734 (docker inspect formatting)
#if command -v docker > /dev/null 2>&1; then
# image="$(docker inspect -f '{{.Image}}' "$cid")"
# if [ "$image" ]; then
# if [ -z "$have_auth" ]; then
# auth="$(docker inspect -f '{{.Author}}' "$image")"
# fi
# if [ -z "$have_desc" ]; then
# desc="$(docker inspect -f '{{.Comment}}' "$image")"
# fi
# fi
#fi
exec "manager/$script" "$cid" "$auth" "$desc"
-20
View File
@@ -1,20 +0,0 @@
#!/bin/sh
set -e
cid="$1"
auth="$2"
desc="$3"
cat <<-EOF
[Unit]
Description=$desc
Author=$auth
After=docker.service
[Service]
ExecStart=/usr/bin/docker start -a $cid
ExecStop=/usr/bin/docker stop -t 2 $cid
[Install]
WantedBy=local.target
EOF
-15
View File
@@ -1,15 +0,0 @@
#!/bin/sh
set -e
cid="$1"
auth="$2"
desc="$3"
cat <<-EOF
description "$(echo "$desc" | sed 's/"/\\"/g')"
author "$(echo "$auth" | sed 's/"/\\"/g')"
start on filesystem and started lxc-net and started docker
stop on runlevel [!2345]
respawn
exec /usr/bin/docker start -a "$cid"
EOF
-13
View File
@@ -1,13 +0,0 @@
# /etc/conf.d/docker: config file for /etc/init.d/docker
# where the docker daemon output gets piped
#DOCKER_LOGFILE="/var/log/docker.log"
# where docker's pid get stored
#DOCKER_PIDFILE="/run/docker.pid"
# where the docker daemon itself is run from
#DOCKER_BINARY="/usr/bin/docker"
# any other random options you want to pass to docker
DOCKER_OPTS=""
-31
View File
@@ -1,31 +0,0 @@
#!/sbin/runscript
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
DOCKER_LOGFILE=${DOCKER_LOGFILE:-/var/log/${SVCNAME}.log}
DOCKER_PIDFILE=${DOCKER_PIDFILE:-/run/${SVCNAME}.pid}
DOCKER_BINARY=${DOCKER_BINARY:-/usr/bin/docker}
DOCKER_OPTS=${DOCKER_OPTS:-}
start() {
checkpath -f -m 0644 -o root:docker "$DOCKER_LOGFILE"
ebegin "Starting docker daemon"
start-stop-daemon --start --background \
--exec "$DOCKER_BINARY" \
--pidfile "$DOCKER_PIDFILE" \
--stdout "$DOCKER_LOGFILE" \
--stderr "$DOCKER_LOGFILE" \
-- -d -p "$DOCKER_PIDFILE" \
$DOCKER_OPTS
eend $?
}
stop() {
ebegin "Stopping docker daemon"
start-stop-daemon --stop \
--exec "$DOCKER_BINARY" \
--pidfile "$DOCKER_PIDFILE"
eend $?
}
-13
View File
@@ -1,13 +0,0 @@
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.io
Requires=network.target
After=multi-user.target
[Service]
Type=simple
ExecStartPre=/bin/mount --make-rprivate /
ExecStart=/usr/bin/docker -d
[Install]
WantedBy=multi-user.target
-94
View File
@@ -1,94 +0,0 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: docker
# Required-Start: $syslog $remote_fs
# Required-Stop: $syslog $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Create lightweight, portable, self-sufficient containers.
# Description:
# Docker is an open-source project to easily create lightweight, portable,
# self-sufficient containers from any application. The same container that a
# developer builds and tests on a laptop can run at scale, in production, on
# VMs, bare metal, OpenStack clusters, public clouds and more.
### END INIT INFO
BASE=$(basename $0)
DOCKER=/usr/bin/$BASE
DOCKER_PIDFILE=/var/run/$BASE.pid
DOCKER_OPTS=
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
# Get lsb functions
. /lib/lsb/init-functions
if [ -f /etc/default/$BASE ]; then
. /etc/default/$BASE
fi
if [ "$1" = start ] && which initctl >/dev/null && initctl version | grep -q upstart; then
exit 1
fi
# Check docker is present
if [ ! -x $DOCKER ]; then
log_failure_msg "$DOCKER not present or not executable"
exit 1
fi
fail_unless_root() {
if [ "$(id -u)" != '0' ]; then
log_failure_msg "Docker must be run as root"
exit 1
fi
}
case "$1" in
start)
fail_unless_root
log_begin_msg "Starting Docker: $BASE"
mount | grep cgroup >/dev/null || mount -t cgroup none /sys/fs/cgroup 2>/dev/null
start-stop-daemon --start --background \
--exec "$DOCKER" \
--pidfile "$DOCKER_PIDFILE" \
-- -d -p "$DOCKER_PIDFILE" \
$DOCKER_OPTS
log_end_msg $?
;;
stop)
fail_unless_root
log_begin_msg "Stopping Docker: $BASE"
start-stop-daemon --stop \
--pidfile "$DOCKER_PIDFILE"
log_end_msg $?
;;
restart)
fail_unless_root
docker_pid=`cat "$DOCKER_PIDFILE" 2>/dev/null`
[ -n "$docker_pid" ] \
&& ps -p $docker_pid > /dev/null 2>&1 \
&& $0 stop
$0 start
;;
force-reload)
fail_unless_root
$0 restart
;;
status)
status_of_proc -p "$DOCKER_PIDFILE" "$DOCKER" docker
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
+61
View File
@@ -0,0 +1,61 @@
#!/bin/sh
# This script is meant for quick & easy install via 'curl URL-OF-SCRIPT | sh'
# Original version by Jeff Lindsay <progrium@gmail.com>
# Revamped by Jerome Petazzoni <jerome@dotcloud.com>
#
# This script canonical location is https://get.docker.io/; to update it, run:
# s3cmd put -m text/x-shellscript -P install.sh s3://get.docker.io/index
echo "Ensuring basic dependencies are installed..."
apt-get -qq update
apt-get -qq install lxc wget
echo "Looking in /proc/filesystems to see if we have AUFS support..."
if grep -q aufs /proc/filesystems
then
echo "Found."
else
echo "Ahem, it looks like the current kernel does not support AUFS."
echo "Let's see if we can load the AUFS module with modprobe..."
if modprobe aufs
then
echo "Module loaded."
else
echo "Ahem, things didn't turn out as expected."
KPKG=linux-image-extra-$(uname -r)
echo "Trying to install $KPKG..."
if apt-get -qq install $KPKG
then
echo "Installed."
else
echo "Oops, we couldn't install the -extra kernel."
echo "Are you sure you are running a supported version of Ubuntu?"
echo "Proceeding anyway, but Docker will probably NOT WORK!"
fi
fi
fi
echo "Downloading docker binary to /usr/local/bin..."
curl -s https://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-latest \
> /usr/local/bin/docker
chmod +x /usr/local/bin/docker
if [ -f /etc/init/dockerd.conf ]
then
echo "Upstart script already exists."
else
echo "Creating /etc/init/dockerd.conf..."
cat >/etc/init/dockerd.conf <<EOF
description "Docker daemon"
start on filesystem and started lxc-net
stop on runlevel [!2345]
respawn
exec /usr/local/bin/docker -d
EOF
fi
echo "Starting dockerd..."
start dockerd > /dev/null
echo "Done."
echo
-67
View File
@@ -1,67 +0,0 @@
#!/bin/bash
# Generate a minimal filesystem for archlinux and load it into the local
# docker as "archlinux"
# requires root
set -e
PACSTRAP=$(which pacstrap)
[ "$PACSTRAP" ] || {
echo "Could not find pacstrap. Run pacman -S arch-install-scripts"
exit 1
}
EXPECT=$(which expect)
[ "$EXPECT" ] || {
echo "Could not find expect. Run pacman -S expect"
exit 1
}
ROOTFS=~/rootfs-arch-$$-$RANDOM
mkdir $ROOTFS
#packages to ignore for space savings
PKGIGNORE=linux,jfsutils,lvm2,cryptsetup,groff,man-db,man-pages,mdadm,pciutils,pcmciautils,reiserfsprogs,s-nail,xfsprogs
expect <<EOF
set timeout 60
set send_slow {1 1}
spawn pacstrap -c -d -G -i $ROOTFS base haveged --ignore $PKGIGNORE
expect {
"Install anyway?" { send n\r; exp_continue }
"(default=all)" { send \r; exp_continue }
"Proceed with installation?" { send "\r"; exp_continue }
"skip the above package" {send "y\r"; exp_continue }
"checking" { exp_continue }
"loading" { exp_continue }
"installing" { exp_continue }
}
EOF
arch-chroot $ROOTFS /bin/sh -c "haveged -w 1024; pacman-key --init; pkill haveged; pacman -Rs --noconfirm haveged; pacman-key --populate archlinux"
arch-chroot $ROOTFS /bin/sh -c "ln -s /usr/share/zoneinfo/UTC /etc/localtime"
cat > $ROOTFS/etc/locale.gen <<DELIM
en_US.UTF-8 UTF-8
en_US ISO-8859-1
DELIM
arch-chroot $ROOTFS locale-gen
arch-chroot $ROOTFS /bin/sh -c 'echo "Server = http://mirrors.kernel.org/archlinux/\$repo/os/\$arch" > /etc/pacman.d/mirrorlist'
# udev doesn't work in containers, rebuild /dev
DEV=${ROOTFS}/dev
mv ${DEV} ${DEV}.old
mkdir -p ${DEV}
mknod -m 666 ${DEV}/null c 1 3
mknod -m 666 ${DEV}/zero c 1 5
mknod -m 666 ${DEV}/random c 1 8
mknod -m 666 ${DEV}/urandom c 1 9
mkdir -m 755 ${DEV}/pts
mkdir -m 1777 ${DEV}/shm
mknod -m 666 ${DEV}/tty c 5 0
mknod -m 600 ${DEV}/console c 5 1
mknod -m 666 ${DEV}/tty0 c 4 0
mknod -m 666 ${DEV}/full c 1 7
mknod -m 600 ${DEV}/initctl p
mknod -m 666 ${DEV}/ptmx c 5 2
tar --numeric-owner -C $ROOTFS -c . | docker import - archlinux
docker run -i -t archlinux echo Success.
rm -rf $ROOTFS
+1 -1
View File
@@ -35,5 +35,5 @@ do
cp -a /dev/$X dev
done
tar --numeric-owner -cf- . | docker import - busybox
tar -cf- . | docker import - busybox
docker run -i -u root busybox /bin/echo Success.
+66
View File
@@ -0,0 +1,66 @@
#!/bin/bash
set -e
# these should match the names found at http://www.debian.org/releases/
stableSuite='wheezy'
testingSuite='jessie'
unstableSuite='sid'
variant='minbase'
include='iproute,iputils-ping'
repo="$1"
suite="${2:-$stableSuite}"
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"
# prevent init scripts from running during install/update
echo $'#!/bin/sh\nexit 101' | sudo tee usr/sbin/policy-rc.d > /dev/null
sudo chmod +x usr/sbin/policy-rc.d
# see https://github.com/dotcloud/docker/issues/446#issuecomment-16953173
# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB)
sudo chroot . apt-get clean
# while we're at it, apt is unnecessarily slow inside containers
# this forces dpkg not to call sync() after package extraction and speeds up install
echo 'force-unsafe-io' | sudo tee etc/dpkg/dpkg.cfg.d/02apt-speedup > /dev/null
# we don't need an apt cache in a container
echo 'Acquire::http {No-Cache=True;};' | sudo tee etc/apt/apt.conf.d/no-cache > /dev/null
# create the image (and tag $repo:$suite)
sudo tar -c . | docker import - $repo $suite
# test the image
docker run -i -t $repo:$suite echo success
if [ "$suite" = "$stableSuite" -o "$suite" = 'stable' ]; then
# tag latest
docker tag $repo:$suite $repo latest
# tag the specific debian release version
ver=$(docker run $repo:$suite cat /etc/debian_version)
docker tag $repo:$suite $repo $ver
fi
# cleanup
cd "$returnTo"
sudo rm -rf "$target"
-233
View File
@@ -1,233 +0,0 @@
#!/bin/bash
set -e
variant='minbase'
include='iproute,iputils-ping'
arch='amd64' # intentionally undocumented for now
skipDetection=
strictDebootstrap=
justTar=
usage() {
echo >&2
echo >&2 "usage: $0 [options] repo suite [mirror]"
echo >&2
echo >&2 'options: (not recommended)'
echo >&2 " -p set an http_proxy for debootstrap"
echo >&2 " -v $variant # change default debootstrap variant"
echo >&2 " -i $include # change default package includes"
echo >&2 " -d # strict debootstrap (do not apply any docker-specific tweaks)"
echo >&2 " -s # skip version detection and tagging (ie, precise also tagged as 12.04)"
echo >&2 " # note that this will also skip adding universe and/or security/updates to sources.list"
echo >&2 " -t # just create a tarball, especially for dockerbrew (uses repo as tarball name)"
echo >&2
echo >&2 " ie: $0 username/debian squeeze"
echo >&2 " $0 username/debian squeeze http://ftp.uk.debian.org/debian/"
echo >&2
echo >&2 " ie: $0 username/ubuntu precise"
echo >&2 " $0 username/ubuntu precise http://mirrors.melbourne.co.uk/ubuntu/"
echo >&2
echo >&2 " ie: $0 -t precise.tar.bz2 precise"
echo >&2 " $0 -t wheezy.tgz wheezy"
echo >&2 " $0 -t wheezy-uk.tar.xz wheezy http://ftp.uk.debian.org/debian/"
echo >&2
}
# these should match the names found at http://www.debian.org/releases/
debianStable=wheezy
debianUnstable=sid
# this should match the name found at http://releases.ubuntu.com/
ubuntuLatestLTS=precise
while getopts v:i:a:p:dst name; do
case "$name" in
p)
http_proxy="$OPTARG"
;;
v)
variant="$OPTARG"
;;
i)
include="$OPTARG"
;;
a)
arch="$OPTARG"
;;
d)
strictDebootstrap=1
;;
s)
skipDetection=1
;;
t)
justTar=1
;;
?)
usage
exit 0
;;
esac
done
shift $(($OPTIND - 1))
repo="$1"
suite="$2"
mirror="${3:-}" # stick to the default debootstrap mirror if one is not provided
if [ ! "$repo" ] || [ ! "$suite" ]; then
usage
exit 1
fi
# some rudimentary detection for whether we need to "sudo" our docker calls
docker=''
if docker version > /dev/null 2>&1; then
docker='docker'
elif sudo docker version > /dev/null 2>&1; then
docker='sudo docker'
elif command -v docker > /dev/null 2>&1; then
docker='docker'
else
echo >&2 "warning: either docker isn't installed, or your current user cannot run it;"
echo >&2 " this script is not likely to work as expected"
sleep 3
docker='docker' # give us a command-not-found later
fi
# make sure we have an absolute path to our final tarball so we can still reference it properly after we change directory
if [ "$justTar" ]; then
if [ ! -d "$(dirname "$repo")" ]; then
echo >&2 "error: $(dirname "$repo") does not exist"
exit 1
fi
repo="$(cd "$(dirname "$repo")" && pwd -P)/$(basename "$repo")"
fi
# will be filled in later, if [ -z "$skipDetection" ]
lsbDist=''
target="/tmp/docker-rootfs-debootstrap-$suite-$$-$RANDOM"
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
returnTo="$(pwd -P)"
set -x
# bootstrap
mkdir -p "$target"
sudo http_proxy=$http_proxy debootstrap --verbose --variant="$variant" --include="$include" --arch="$arch" "$suite" "$target" "$mirror"
cd "$target"
if [ -z "$strictDebootstrap" ]; then
# prevent init scripts from running during install/update
# policy-rc.d (for most scripts)
echo $'#!/bin/sh\nexit 101' | sudo tee usr/sbin/policy-rc.d > /dev/null
sudo chmod +x usr/sbin/policy-rc.d
# initctl (for some pesky upstart scripts)
sudo chroot . dpkg-divert --local --rename --add /sbin/initctl
sudo ln -sf /bin/true sbin/initctl
# see https://github.com/dotcloud/docker/issues/446#issuecomment-16953173
# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB)
sudo chroot . apt-get clean
# while we're at it, apt is unnecessarily slow inside containers
# this forces dpkg not to call sync() after package extraction and speeds up install
# the benefit is huge on spinning disks, and the penalty is nonexistent on SSD or decent server virtualization
echo 'force-unsafe-io' | sudo tee etc/dpkg/dpkg.cfg.d/02apt-speedup > /dev/null
# we want to effectively run "apt-get clean" after every install to keep images small
echo 'DPkg::Post-Invoke {"/bin/rm -f /var/cache/apt/archives/*.deb || true";};' | sudo tee etc/apt/apt.conf.d/no-cache > /dev/null
# helpful undo lines for each the above tweaks (for lack of a better home to keep track of them):
# rm /usr/sbin/policy-rc.d
# rm /sbin/initctl; dpkg-divert --rename --remove /sbin/initctl
# rm /etc/dpkg/dpkg.cfg.d/02apt-speedup
# rm /etc/apt/apt.conf.d/no-cache
if [ -z "$skipDetection" ]; then
# see also rudimentary platform detection in hack/install.sh
lsbDist=''
if [ -r etc/lsb-release ]; then
lsbDist="$(. etc/lsb-release && echo "$DISTRIB_ID")"
fi
if [ -z "$lsbDist" ] && [ -r etc/debian_version ]; then
lsbDist='Debian'
fi
case "$lsbDist" in
Debian)
# add the updates and security repositories
if [ "$suite" != "$debianUnstable" -a "$suite" != 'unstable' ]; then
# ${suite}-updates only applies to non-unstable
sudo sed -i "p; s/ $suite main$/ ${suite}-updates main/" etc/apt/sources.list
# same for security updates
echo "deb http://security.debian.org/ $suite/updates main" | sudo tee -a etc/apt/sources.list > /dev/null
fi
;;
Ubuntu)
# add the universe, updates, and security repositories
sudo sed -i "
s/ $suite main$/ $suite main universe/; p;
s/ $suite main/ ${suite}-updates main/; p;
s/ $suite-updates main/ ${suite}-security main/
" etc/apt/sources.list
;;
esac
fi
fi
if [ "$justTar" ]; then
# create the tarball file so it has the right permissions (ie, not root)
touch "$repo"
# fill the tarball
sudo tar --numeric-owner -caf "$repo" .
else
# create the image (and tag $repo:$suite)
sudo tar --numeric-owner -c . | $docker import - $repo $suite
# test the image
$docker run -i -t $repo:$suite echo success
if [ -z "$skipDetection" ]; then
case "$lsbDist" in
Debian)
if [ "$suite" = "$debianStable" -o "$suite" = 'stable' ] && [ -r etc/debian_version ]; then
# tag latest
$docker tag $repo:$suite $repo latest
if [ -r etc/debian_version ]; then
# tag the specific debian release version (which is only reasonable to tag on debian stable)
ver=$(cat etc/debian_version)
$docker tag $repo:$suite $repo $ver
fi
fi
;;
Ubuntu)
if [ "$suite" = "$ubuntuLatestLTS" ]; then
# tag latest
$docker tag $repo:$suite $repo latest
fi
if [ -r etc/lsb-release ]; then
lsbRelease="$(. etc/lsb-release && echo "$DISTRIB_RELEASE")"
if [ "$lsbRelease" ]; then
# tag specific Ubuntu version number, if available (12.04, etc.)
$docker tag $repo:$suite $repo $lsbRelease
fi
fi
;;
esac
fi
fi
# cleanup
cd "$returnTo"
sudo rm -rf "$target"
+1 -1
View File
@@ -44,6 +44,6 @@ do
done
chmod 0755 $ROOTFS # See #486
tar --numeric-owner -cf- . | docker import - docker-ut
tar -cf- . | docker import - docker-ut
docker run -i -u root docker-ut /bin/echo Success.
rm -rf $ROOTFS
-22
View File
@@ -1,22 +0,0 @@
Copyright (c) 2013 Honza Pokorny
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-23
View File
@@ -1,23 +0,0 @@
dockerfile.vim
==============
Syntax highlighting for Dockerfiles
Installation
------------
Via pathogen, the usual way...
Features
--------
The syntax highlighting includes:
* The directives (e.g. `FROM`)
* Strings
* Comments
License
-------
BSD, short and sweet
-18
View File
@@ -1,18 +0,0 @@
*dockerfile.txt* Syntax highlighting for Dockerfiles
Author: Honza Pokorny <http://honza.ca>
License: BSD
INSTALLATION *installation*
Drop it on your Pathogen path and you're all set.
FEATURES *features*
The syntax highlighting includes:
* The directives (e.g. FROM)
* Strings
* Comments
vim:tw=78:et:ft=help:norl:
@@ -1 +0,0 @@
au BufNewFile,BufRead Dockerfile set filetype=dockerfile
-24
View File
@@ -1,24 +0,0 @@
" dockerfile.vim - Syntax highlighting for Dockerfiles
" Maintainer: Honza Pokorny <http://honza.ca>
" Version: 0.5
if exists("b:current_syntax")
finish
endif
let b:current_syntax = "dockerfile"
syntax case ignore
syntax match dockerfileKeyword /\v^\s*(FROM|MAINTAINER|RUN|CMD|EXPOSE|ENV|ADD)\s/
syntax match dockerfileKeyword /\v^\s*(ENTRYPOINT|VOLUME|USER|WORKDIR)\s/
highlight link dockerfileKeyword Keyword
syntax region dockerfileString start=/\v"/ skip=/\v\\./ end=/\v"/
highlight link dockerfileString String
syntax match dockerfileComment "\v^\s*#.*$"
highlight link dockerfileComment Comment
set commentstring=#\ %s
+106 -28
View File
@@ -4,12 +4,15 @@ import (
"flag"
"fmt"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/sysinit"
"github.com/dotcloud/docker/utils"
"github.com/dotcloud/docker/engine"
"io/ioutil"
"log"
"net"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
)
var (
@@ -20,24 +23,23 @@ var (
func main() {
if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" {
// Running in init mode
sysinit.SysInit()
docker.SysInit()
return
}
// FIXME: Switch d and D ? (to be more sshd like)
flVersion := flag.Bool("v", false, "Print version information and quit")
flDaemon := flag.Bool("d", false, "Daemon mode")
flDebug := flag.Bool("D", false, "Debug mode")
flAutoRestart := flag.Bool("r", true, "Restart previously running containers")
flAutoRestart := flag.Bool("r", false, "Restart previously running containers")
bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge. Use 'none' to disable container networking")
pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID")
flRoot := flag.String("g", "/var/lib/docker", "Path to use as the root of the docker runtime.")
flGraphPath := flag.String("g", "/var/lib/docker", "Path to graph storage base dir.")
flEnableCors := flag.Bool("api-enable-cors", false, "Enable CORS requests in the remote api.")
flDns := flag.String("dns", "", "Set custom dns servers")
flHosts := utils.ListOpts{fmt.Sprintf("unix://%s", docker.DEFAULTUNIXSOCKET)}
flHosts := docker.ListOpts{fmt.Sprintf("unix://%s", docker.DEFAULTUNIXSOCKET)}
flag.Var(&flHosts, "H", "tcp://host:port to bind/connect to or unix://path/to/socket to use")
flEnableIptables := flag.Bool("iptables", true, "Disable iptables within docker")
flDefaultIp := flag.String("ip", "0.0.0.0", "Default ip address to use when binding a containers ports")
flInterContainerComm := flag.Bool("icc", true, "Enable inter-container communication")
flag.Parse()
@@ -49,14 +51,13 @@ func main() {
flHosts = flHosts[1:] //trick to display a nice default value in the usage
}
for i, flHost := range flHosts {
host, err := utils.ParseHost(docker.DEFAULTHTTPHOST, docker.DEFAULTHTTPPORT, flHost)
if err == nil {
flHosts[i] = host
} else {
log.Fatal(err)
}
flHosts[i] = utils.ParseHost(docker.DEFAULTHTTPHOST, docker.DEFAULTHTTPPORT, flHost)
}
bridge := docker.DefaultNetworkBridge
if *bridgeName != "" {
bridge = *bridgeName
}
if *flDebug {
os.Setenv("DEBUG", "1")
}
@@ -67,27 +68,32 @@ func main() {
flag.Usage()
return
}
eng, err := engine.New(*flRoot)
if err != nil {
log.Fatal(err)
var dns []string
if *flDns != "" {
dns = []string{*flDns}
}
job := eng.Job("serveapi")
job.Setenv("Pidfile", *pidfile)
job.Setenv("Root", *flRoot)
job.SetenvBool("AutoRestart", *flAutoRestart)
job.SetenvBool("EnableCors", *flEnableCors)
job.Setenv("Dns", *flDns)
job.SetenvBool("EnableIptables", *flEnableIptables)
job.Setenv("BridgeIface", *bridgeName)
job.SetenvList("ProtoAddresses", flHosts)
job.Setenv("DefaultIp", *flDefaultIp)
job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
if err := job.Run(); err != nil {
ip := net.ParseIP(*flDefaultIp)
config := &docker.DaemonConfig{
Pidfile: *pidfile,
GraphPath: *flGraphPath,
AutoRestart: *flAutoRestart,
EnableCors: *flEnableCors,
Dns: dns,
EnableIptables: *flEnableIptables,
BridgeIface: bridge,
ProtoAddresses: flHosts,
DefaultIp: ip,
}
if err := daemon(config); err != nil {
log.Fatal(err)
os.Exit(-1)
}
} else {
if len(flHosts) > 1 {
log.Fatal("Please specify only one -H")
return
}
protoAddrParts := strings.SplitN(flHosts[0], "://", 2)
if err := docker.ParseCommands(protoAddrParts[0], protoAddrParts[1], flag.Args()...); err != nil {
@@ -95,6 +101,7 @@ func main() {
os.Exit(sterr.Status)
}
log.Fatal(err)
os.Exit(-1)
}
}
}
@@ -102,3 +109,74 @@ func main() {
func showVersion() {
fmt.Printf("Docker version %s, build %s\n", VERSION, GITCOMMIT)
}
func createPidFile(pidfile string) error {
if pidString, err := ioutil.ReadFile(pidfile); err == nil {
pid, err := strconv.Atoi(string(pidString))
if err == nil {
if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil {
return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile)
}
}
}
file, err := os.Create(pidfile)
if err != nil {
return err
}
defer file.Close()
_, err = fmt.Fprintf(file, "%d", os.Getpid())
return err
}
func removePidFile(pidfile string) {
if err := os.Remove(pidfile); err != nil {
log.Printf("Error removing %s: %s", pidfile, err)
}
}
func daemon(config *docker.DaemonConfig) error {
if err := createPidFile(config.Pidfile); err != nil {
log.Fatal(err)
}
defer removePidFile(config.Pidfile)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM))
go func() {
sig := <-c
log.Printf("Received signal '%v', exiting\n", sig)
removePidFile(config.Pidfile)
os.Exit(0)
}()
server, err := docker.NewServer(config)
if err != nil {
return err
}
chErrors := make(chan error, len(config.ProtoAddresses))
for _, protoAddr := range config.ProtoAddresses {
protoAddrParts := strings.SplitN(protoAddr, "://", 2)
if protoAddrParts[0] == "unix" {
syscall.Unlink(protoAddrParts[1])
} else if protoAddrParts[0] == "tcp" {
if !strings.HasPrefix(protoAddrParts[1], "127.0.0.1") {
log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
}
} else {
log.Fatal("Invalid protocol format.")
os.Exit(-1)
}
go func() {
chErrors <- docker.ListenAndServe(protoAddrParts[0], protoAddrParts[1], server, true)
}()
}
for i := 0; i < len(config.ProtoAddresses); i += 1 {
err := <-chErrors
if err != nil {
return err
}
}
return nil
}
-16
View File
@@ -1,16 +0,0 @@
package main
import (
"github.com/dotcloud/docker/sysinit"
)
var (
GITCOMMIT string
VERSION string
)
func main() {
// Running in init mode
sysinit.SysInit()
return
}
+1 -6
View File
@@ -1,16 +1,11 @@
from ubuntu:12.04
maintainer Nick Stinemates
#
# docker build -t docker:docs . && docker run -p 8000:8000 docker:docs
#
run apt-get update
run apt-get install -y python-setuptools make
run easy_install pip
#from docs/requirements.txt, but here to increase cacheability
run pip install Sphinx==1.1.3
run pip install sphinxcontrib-httpdomain==1.1.8
add . /docs
run pip install -r /docs/requirements.txt
run cd /docs; make docs
expose 8000
+24 -87
View File
@@ -1,94 +1,38 @@
Docker Documentation
====================
Overview
--------
Documentation
-------------
This is your definite place to contribute to the docker documentation. After each push to master the documentation
is automatically generated and made available on [docs.docker.io](http://docs.docker.io)
The source for Docker documentation is here under ``sources/`` in the
form of .rst files. These files use
[reStructuredText](http://docutils.sourceforge.net/rst.html)
formatting with [Sphinx](http://sphinx-doc.org/) extensions for
structure, cross-linking and indexing.
Each of the .rst files under sources reflects a page on the documentation.
The HTML files are built and hosted on
[readthedocs.org](https://readthedocs.org/projects/docker/), appearing
via proxy on https://docs.docker.io. The HTML files update
automatically after each change to the master or release branch of the
[docker files on GitHub](https://github.com/dotcloud/docker) thanks to
post-commit hooks. The "release" branch maps to the "latest"
documentation and the "master" branch maps to the "master"
documentation.
**Warning**: The "master" documentation may include features not yet
part of any official docker release. "Master" docs should be used only
for understanding bleeding-edge development and "latest" should be
used for the latest official release.
If you need to manually trigger a build of an existing branch, then
you can do that through the [readthedocs
interface](https://readthedocs.org/builds/docker/). If you would like
to add new build targets, including new branches or tags, then you
must contact one of the existing maintainers and get your
readthedocs.org account added to the maintainers list, or just file an
issue on GitHub describing the branch/tag and why it needs to be added
to the docs, and one of the maintainers will add it for you.
Getting Started
---------------
To edit and test the docs, you'll need to install the Sphinx tool and
its dependencies. There are two main ways to install this tool:
###Native Installation
Installation
------------
* Work in your own fork of the code, we accept pull requests.
* Install sphinx: `pip install sphinx`
* Mac OS X: `[sudo] pip-2.7 install sphinx`
* Mac OS X: `[sudo] pip-2.7 install sphinx`)
* Install sphinx httpdomain contrib package: `pip install sphinxcontrib-httpdomain`
* Mac OS X: `[sudo] pip-2.7 install sphinxcontrib-httpdomain`
* If pip is not available you can probably install it using your favorite package manager as **python-pip**
###Alternative Installation: Docker Container
If you're running ``docker`` on your development machine then you may
find it easier and cleaner to use the Dockerfile. This installs Sphinx
in a container, adds the local ``docs/`` directory and builds the HTML
docs inside the container, even starting a simple HTTP server on port
8000 so that you can connect and see your changes. Just run ``docker
build .`` and run the resulting image. This is the equivalent to
``make clean server`` since each container starts clean.
In the ``docs/`` directory, run:
```docker build -t docker:docs . && docker run -p 8000:8000 docker:docs```
Usage
-----
* Follow the contribution guidelines (``../CONTRIBUTING.md``)
* Work in your own fork of the code, we accept pull requests.
* Change the ``.rst`` files with your favorite editor -- try to keep the
lines short and respect RST and Sphinx conventions.
* Run ``make clean docs`` to clean up old files and generate new ones,
or just ``make docs`` to update after small changes.
* Your static website can now be found in the ``_build`` directory.
* To preview what you have generated run ``make server`` and open
http://localhost:8000/ in your favorite browser.
``make clean docs`` must complete without any warnings or errors.
* Change the `.rst` files with your favorite editor to your liking.
* Run `make docs` to clean up old files and generate new ones.
* Your static website can now be found in the `_build` directory.
* To preview what you have generated run `make server` and open http://localhost:8000/ in your favorite browser.
Working using GitHub's file editor
----------------------------------
Alternatively, for small changes and typos you might want to use
GitHub's built in file editor. It allows you to preview your changes
right online (though there can be some differences between GitHub
markdown and Sphinx RST). Just be careful not to create many commits.
Alternatively, for small changes and typo's you might want to use GitHub's built in file editor. It allows
you to preview your changes right online. Just be careful not to create many commits.
Images
------
When you need to add images, try to make them as small as possible
(e.g. as gif). Usually images should go in the same directory as the
.rst file which references them, or in a subdirectory if one already
exists.
When you need to add images, try to make them as small as possible (e.g. as gif).
Notes
-----
@@ -97,7 +41,7 @@ lessc ``lessc main.less`` or watched using watch-lessc ``watch-lessc -i main.les
Guides on using sphinx
----------------------
* To make links to certain sections create a link target like so:
* To make links to certain pages create a link target like so:
```
.. _hello_world:
@@ -108,10 +52,7 @@ Guides on using sphinx
This is.. (etc.)
```
The ``_hello_world:`` will make it possible to link to this position
(page and section heading) from all other pages. See the [Sphinx
docs](http://sphinx-doc.org/markup/inline.html#role-ref) for more
information and examples.
The ``_hello_world:`` will make it possible to link to this position (page and marker) from all other pages.
* Notes, warnings and alarms
@@ -127,17 +68,13 @@ Guides on using sphinx
* Code examples
* Start without $, so it's easy to copy and paste.
* Use "sudo" with docker to ensure that your command is runnable
even if they haven't [used the *docker*
group](http://docs.docker.io/en/latest/use/basics/#why-sudo).
Start without $, so it's easy to copy and paste.
Manpages
--------
* To make the manpages, run ``make man``. Please note there is a bug
in spinx 1.1.3 which makes this fail. Upgrade to the latest version
of Sphinx.
* Then preview the manpage by running ``man _build/man/docker.1``,
where ``_build/man/docker.1`` is the path to the generated manfile
* To make the manpages, simply run 'make man'. Please note there is a bug in spinx 1.1.3 which makes this fail.
Upgrade to the latest version of sphinx.
* Then preview the manpage by running `man _build/man/docker.1`, where _build/man/docker.1 is the path to the generated
manfile
* The manpages are also autogenerated by our hosted readthedocs here: http://docs-docker.dotcloud.com/projects/docker/downloads/
+12 -46
View File
@@ -34,13 +34,8 @@ Calling /images/<name>/insert is the same as calling
You can still call an old version of the api using
/v1.0/images/<name>/insert
v1.6
****
Full Documentation
------------------
:doc:`docker_remote_api_v1.6`
*****************************
What's new
----------
@@ -54,13 +49,8 @@ What's new
stderr are merged.
v1.5
****
Full Documentation
------------------
:doc:`docker_remote_api_v1.5`
*****************************
What's new
----------
@@ -81,13 +71,8 @@ What's new
dicts each containing `PublicPort`, `PrivatePort` and `Type` describing a
port mapping.
v1.4
****
Full Documentation
------------------
:doc:`docker_remote_api_v1.4`
*****************************
What's new
----------
@@ -104,16 +89,11 @@ What's new
**New!** Image's name added in the events
v1.3
****
:doc:`docker_remote_api_v1.3`
*****************************
docker v0.5.0 51f6c4a_
Full Documentation
------------------
:doc:`docker_remote_api_v1.3`
What's new
----------
@@ -146,16 +126,11 @@ Start containers (/containers/<id>/start):
- You can now pass host-specific configuration (e.g. bind mounts) in
the POST body for start calls
v1.2
****
:doc:`docker_remote_api_v1.2`
*****************************
docker v0.4.2 2e7649b_
Full Documentation
------------------
:doc:`docker_remote_api_v1.2`
What's new
----------
@@ -181,16 +156,11 @@ The client should send it's authConfig as POST on each call of
deleted/untagged.
v1.1
****
:doc:`docker_remote_api_v1.1`
*****************************
docker v0.4.0 a8ae398_
Full Documentation
------------------
:doc:`docker_remote_api_v1.1`
What's new
----------
@@ -210,15 +180,11 @@ What's new
{"error":"Invalid..."}
...
v1.0
****
docker v0.3.4 8d73740_
Full Documentation
------------------
:doc:`docker_remote_api_v1.0`
*****************************
docker v0.3.4 8d73740_
What's new
----------
+16 -21
View File
@@ -970,33 +970,28 @@ Create a new image from a container's changes
**Example request**:
.. sourcecode:: http
.. sourcecode:: http
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
**Example response**:
**Example response**:
.. sourcecode:: http
.. sourcecode:: http
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
{"Id":"596069db4bf5"}
{"Id":"596069db4bf5"}
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]})
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
3. Going further
+23 -28
View File
@@ -977,37 +977,32 @@ Create a new image from a container's changes
.. http:post:: /commit
Create a new image from a container's changes
Create a new image from a container's changes
**Example request**:
.. sourcecode:: http
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
**Example request**:
{"Id":"596069db4bf5"}
.. sourcecode:: http
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
**Example response**:
.. sourcecode:: http
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
{"Id":"596069db4bf5"}
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]})
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
3. Going further
+17 -22
View File
@@ -985,37 +985,32 @@ Create a new image from a container's changes
.. http:post:: /commit
Create a new image from a container's changes
Create a new image from a container's changes
**Example request**:
**Example request**:
.. sourcecode:: http
.. sourcecode:: http
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
**Example response**:
**Example response**:
.. sourcecode:: http
.. sourcecode:: http
HTTP/1.1 201 OK
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
{"Id":"596069db4bf5"}
{"Id":"596069db4bf5"}
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]})
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
3. Going further
+17 -22
View File
@@ -1034,37 +1034,32 @@ Create a new image from a container's changes
.. http:post:: /commit
Create a new image from a container's changes
Create a new image from a container's changes
**Example request**:
**Example request**:
.. sourcecode:: http
.. sourcecode:: http
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
**Example response**:
**Example response**:
.. sourcecode:: http
.. sourcecode:: http
HTTP/1.1 201 OK
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
{"Id":"596069db4bf5"}
{"Id":"596069db4bf5"}
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]})
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
Monitor Docker's events
+24 -29
View File
@@ -943,36 +943,36 @@ Build an image from Dockerfile via stdin
.. http:post:: /build
Build an image from Dockerfile via stdin
Build an image from Dockerfile via stdin
**Example request**:
**Example request**:
.. sourcecode:: http
.. sourcecode:: http
POST /build HTTP/1.1
POST /build HTTP/1.1
{{ STREAM }}
{{ STREAM }}
**Example response**:
**Example response**:
.. sourcecode:: http
.. sourcecode:: http
HTTP/1.1 200 OK
HTTP/1.1 200 OK
{{ STREAM }}
{{ STREAM }}
The stream must be a tar archive compressed with one of the following algorithms:
identity (no compression), gzip, bzip2, xz. The archive must include a file called
`Dockerfile` at its root. It may include any number of other files, which will be
accessible in the build context (See the ADD build command).
The stream must be a tar archive compressed with one of the following algorithms:
identity (no compression), gzip, bzip2, xz. The archive must include a file called
`Dockerfile` at its root. It may include any number of other files, which will be
accessible in the build context (See the ADD build command).
The Content-type header should be set to "application/tar".
The Content-type header should be set to "application/tar".
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success
:query q: suppress verbose build output
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success
:query q: suppress verbose build output
:query nocache: do not use the cache when building the image
:statuscode 200: no error
:statuscode 200: no error
:statuscode 500: server error
@@ -1069,8 +1069,8 @@ Show the docker version information
"GoVersion":"go1.0.3"
}
:statuscode 200: no error
:statuscode 500: server error
:statuscode 200: no error
:statuscode 500: server error
Create a new image from a container's changes
@@ -1084,28 +1084,23 @@ Create a new image from a container's changes
.. sourcecode:: http
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
**Example response**:
.. sourcecode:: http
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
{"Id":"596069db4bf5"}
{"Id":"596069db4bf5"}
:query container: source container
:query repo: repository
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]})
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
File diff suppressed because it is too large Load Diff
+24 -34
View File
@@ -13,12 +13,9 @@ Docker Remote API v1.6
1. Brief introduction
=====================
- The Remote API has replaced rcli
- The daemon listens on ``unix:///var/run/docker.sock``, but you can
:ref:`bind_docker`.
- The API tends to be REST, but for some complex commands, like
``attach`` or ``pull``, the HTTP connection is hijacked to transport
``stdout, stdin`` and ``stderr``
- The Remote API is replacing rcli
- Default port in the docker daemon is 4243
- The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr
2. Endpoints
============
@@ -151,7 +148,6 @@ Create a container
}
:jsonparam config: the container's configuration
:query name: container name to use
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 406: impossible to attach (container not running)
@@ -446,8 +442,7 @@ Kill a container
.. sourcecode:: http
HTTP/1.1 204 OK
:query signal: Signal to send to the container (integer). When not set, SIGKILL is assumed and the call will waits for the container to exit.
:statuscode 204: no error
:statuscode 404: no such container
:statuscode 500: server error
@@ -995,36 +990,36 @@ Build an image from Dockerfile via stdin
.. http:post:: /build
Build an image from Dockerfile via stdin
Build an image from Dockerfile via stdin
**Example request**:
**Example request**:
.. sourcecode:: http
.. sourcecode:: http
POST /build HTTP/1.1
POST /build HTTP/1.1
{{ STREAM }}
{{ STREAM }}
**Example response**:
**Example response**:
.. sourcecode:: http
.. sourcecode:: http
HTTP/1.1 200 OK
HTTP/1.1 200 OK
{{ STREAM }}
{{ STREAM }}
The stream must be a tar archive compressed with one of the following algorithms:
identity (no compression), gzip, bzip2, xz. The archive must include a file called
`Dockerfile` at its root. It may include any number of other files, which will be
accessible in the build context (See the ADD build command).
The Content-type header should be set to "application/tar".
The stream must be a tar archive compressed with one of the following algorithms:
identity (no compression), gzip, bzip2, xz. The archive must include a file called
`Dockerfile` at its root. It may include any number of other files, which will be
accessible in the build context (See the ADD build command).
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success
:query q: suppress verbose build output
The Content-type header should be set to "application/tar".
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success
:query q: suppress verbose build output
:query nocache: do not use the cache when building the image
:statuscode 200: no error
:statuscode 200: no error
:statuscode 500: server error
@@ -1136,13 +1131,7 @@ Create a new image from a container's changes
.. sourcecode:: http
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
**Example response**:
@@ -1158,6 +1147,7 @@ Create a new image from a container's changes
:query tag: tag
:query m: commit message
:query author: author (eg. "John Hannibal Smith <hannibal@a-team.com>")
:query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]})
:statuscode 201: no error
:statuscode 404: no such container
:statuscode 500: server error
+1 -1
View File
@@ -14,5 +14,5 @@ Your programs and scripts can access Docker's functionality via these interfaces
registry_api
index_api
docker_remote_api
remote_api_client_libraries
+4 -1
View File
@@ -463,7 +463,7 @@ Ancestry
2.4 Status
----------
.. http:get:: /v1/_ping
.. http:get /v1/_ping
Check status of the registry. This endpoint is also used to determine if
the registry supports SSL.
@@ -479,6 +479,9 @@ Ancestry
""
:parameter namespace: namespace for the repo
:parameter repository: name for the repo
**Example Response**:
.. sourcecode:: http
+40 -721
View File
@@ -4,8 +4,11 @@
.. _cli:
Command Line Help
-----------------
Overview
======================
Docker Usage
~~~~~~~~~~~~~~~~~~
To list available commands, either run ``docker`` with no parameters or execute
``docker help``::
@@ -18,759 +21,75 @@ To list available commands, either run ``docker`` with no parameters or execute
...
.. _cli_attach:
``attach``
----------
::
Available Commands
~~~~~~~~~~~~~~~~~~
Usage: docker attach CONTAINER
.. include:: command/attach.rst
Attach to a running container.
.. include:: command/build.rst
-nostdin=false: Do not attach stdin
-sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)
.. include:: command/commit.rst
You can detach from the container again (and leave it running) with
``CTRL-c`` (for a quiet exit) or ``CTRL-\`` to get a stacktrace of
the Docker client when it quits.
.. include:: command/cp.rst
To stop a container, use ``docker stop``
.. include:: command/diff.rst
To kill the container, use ``docker kill``
.. include:: command/events.rst
.. _cli_attach_examples:
.. include:: command/export.rst
Examples:
~~~~~~~~~
.. include:: command/history.rst
.. code-block:: bash
.. include:: command/images.rst
$ ID=$(sudo docker run -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
top - 02:05:52 up 3:05, 0 users, load average: 0.01, 0.02, 0.05
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.1%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 373572k total, 355560k used, 18012k free, 27872k buffers
Swap: 786428k total, 0k used, 786428k free, 221740k cached
.. include:: command/import.rst
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 17200 1116 912 R 0 0.3 0:00.03 top
.. include:: command/info.rst
top - 02:05:55 up 3:05, 0 users, load average: 0.01, 0.02, 0.05
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 373572k total, 355244k used, 18328k free, 27872k buffers
Swap: 786428k total, 0k used, 786428k free, 221776k cached
.. include:: command/insert.rst
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 17208 1144 932 R 0 0.3 0:00.03 top
.. include:: command/inspect.rst
.. include:: command/kill.rst
top - 02:05:58 up 3:06, 0 users, load average: 0.01, 0.02, 0.05
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 0.3%sy, 0.0%ni, 99.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 373572k total, 355780k used, 17792k free, 27880k buffers
Swap: 786428k total, 0k used, 786428k free, 221776k cached
.. include:: command/link.rst
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 17208 1144 932 R 0 0.3 0:00.03 top
^C$
$ sudo docker stop $ID
.. include:: command/login.rst
.. _cli_build:
.. include:: command/logs.rst
``build``
---------
.. include:: command/ls.rst
::
.. include:: command/port.rst
Usage: docker build [OPTIONS] PATH | URL | -
Build a new container image from the source code at PATH
-t="": Repository name (and optionally a tag) to be applied to the resulting image in case of success.
-q=false: Suppress verbose build output.
-no-cache: Do not use the cache when building the image.
-rm: Remove intermediate containers after a successful build
When a single Dockerfile is given as URL, then no context is set. When a git repository is set as URL, the repository is used as context
.. include:: command/ps.rst
.. _cli_build_examples:
.. include:: command/pull.rst
Examples:
~~~~~~~~~
.. include:: command/push.rst
.. code-block:: bash
.. include:: command/restart.rst
sudo docker build .
.. include:: command/rm.rst
This will read the ``Dockerfile`` from the current directory. It will
also send any other files and directories found in the current
directory to the ``docker`` daemon.
.. include:: command/rmi.rst
The contents of this directory would be used by ``ADD`` commands found
within the ``Dockerfile``. This will send a lot of data to the
``docker`` daemon if the current directory contains a lot of data. If
the absolute path is provided instead of ``.`` then only the files and
directories required by the ADD commands from the ``Dockerfile`` will be
added to the context and transferred to the ``docker`` daemon.
.. include:: command/run.rst
.. code-block:: bash
.. include:: command/search.rst
sudo docker build -t vieux/apache:2.0 .
.. include:: command/start.rst
This will build like the previous example, but it will then tag the
resulting image. The repository name will be ``vieux/apache`` and the
tag will be ``2.0``
.. include:: command/stop.rst
.. include:: command/tag.rst
.. code-block:: bash
.. include:: command/top.rst
sudo docker build - < Dockerfile
.. include:: command/version.rst
This will read a ``Dockerfile`` from *stdin* without context. Due to
the lack of a context, no contents of any local directory will be sent
to the ``docker`` daemon. ``ADD`` doesn't work when running in this
mode because the absence of the context provides no source files to
copy to the container.
.. include:: command/wait.rst
.. code-block:: bash
sudo docker build github.com/creack/docker-firefox
This will clone the Github repository and use it as context. The
``Dockerfile`` at the root of the repository is used as
``Dockerfile``. Note that you can specify an arbitrary git repository
by using the ``git://`` schema.
.. _cli_commit:
``commit``
----------
::
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
-m="": Commit message
-author="": Author (eg. "John Hannibal Smith <hannibal@a-team.com>"
-run="": Configuration to be applied when the image is launched with `docker run`.
(ex: '{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}')
Simple commit of an existing container
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
$ docker ps
ID IMAGE COMMAND CREATED STATUS PORTS
c3f279d17e0a ubuntu:12.04 /bin/bash 7 days ago Up 25 hours
197387f1b436 ubuntu:12.04 /bin/bash 7 days ago Up 25 hours
$ docker commit c3f279d17e0a SvenDowideit/testimage:version3
f5283438590d
$ docker images | head
REPOSITORY TAG ID CREATED SIZE
SvenDowideit/testimage version3 f5283438590d 16 seconds ago 204.2 MB (virtual 335.7 MB)
S
Full -run example
.................
(multiline is ok within a single quote ``'``)
::
$ sudo docker commit -run='
{
"Entrypoint" : null,
"Privileged" : false,
"User" : "",
"VolumesFrom" : "",
"Cmd" : ["cat", "-e", "/etc/resolv.conf"],
"Dns" : ["8.8.8.8", "8.8.4.4"],
"MemorySwap" : 0,
"AttachStdin" : false,
"AttachStderr" : false,
"CpuShares" : 0,
"OpenStdin" : false,
"Volumes" : null,
"Hostname" : "122612f45831",
"PortSpecs" : ["22", "80", "443"],
"Image" : "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"Tty" : false,
"Env" : [
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"StdinOnce" : false,
"Domainname" : "",
"WorkingDir" : "/",
"NetworkDisabled" : false,
"Memory" : 0,
"AttachStdout" : false
}' $CONTAINER_ID
.. _cli_cp:
``cp``
------
::
Usage: docker cp CONTAINER:RESOURCE HOSTPATH
Copy files/folders from the containers filesystem to the host
path. Paths are relative to the root of the filesystem.
.. _cli_diff:
``diff``
--------
::
Usage: docker diff CONTAINER [OPTIONS]
Inspect changes on a container's filesystem
.. _cli_events:
``events``
----------
::
Usage: docker events
Get real time events from the server
.. _cli_events_example:
Examples
~~~~~~~~
You'll need two shells for this example.
Shell 1: Listening for events
.............................
.. code-block:: bash
$ sudo docker events
Shell 2: Start and Stop a Container
...................................
.. code-block:: bash
$ sudo docker start 4386fb97867d
$ sudo docker stop 4386fb97867d
Shell 1: (Again .. now showing events)
......................................
.. code-block:: bash
[2013-09-03 15:49:26 +0200 CEST] 4386fb97867d: (from 12de384bfb10) start
[2013-09-03 15:49:29 +0200 CEST] 4386fb97867d: (from 12de384bfb10) die
[2013-09-03 15:49:29 +0200 CEST] 4386fb97867d: (from 12de384bfb10) stop
.. _cli_export:
``export``
----------
::
Usage: docker export CONTAINER
Export the contents of a filesystem as a tar archive
.. _cli_history:
``history``
-----------
::
Usage: docker history [OPTIONS] IMAGE
Show the history of an image
-notrunc=false: Don't truncate output
-q=false: only show numeric IDs
.. _cli_images:
``images``
----------
::
Usage: docker images [OPTIONS] [NAME]
List images
-a=false: show all images
-q=false: only show numeric IDs
-viz=false: output in graphviz format
Displaying images visually
~~~~~~~~~~~~~~~~~~~~~~~~~~
::
sudo docker images -viz | dot -Tpng -o docker.png
.. image:: docker_images.gif
:alt: Example inheritance graph of Docker images.
.. _cli_import:
``import``
----------
::
Usage: docker import URL|- [REPOSITORY[:TAG]]
Create a new filesystem image from the contents of a tarball
At this time, the URL must start with ``http`` and point to a single
file archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) containing a
root filesystem. If you would like to import from a local directory or
archive, you can use the ``-`` parameter to take the data from
standard in.
Examples
~~~~~~~~
Import from a remote location
.............................
This will create a new untagged image.
``$ sudo docker import http://example.com/exampleimage.tgz``
Import from a local file
........................
Import to docker via pipe and standard in
``$ cat exampleimage.tgz | sudo docker import - exampleimagelocal:new``
Import from a local directory
.............................
``$ sudo tar -c . | docker import - exampleimagedir``
Note the ``sudo`` in this example -- you must preserve the ownership
of the files (especially root ownership) during the archiving with
tar. If you are not root (or sudo) when you tar, then the ownerships
might not get preserved.
.. _cli_info:
``info``
--------
::
Usage: docker info
Display system-wide information.
.. _cli_insert:
``insert``
----------
::
Usage: docker insert IMAGE URL PATH
Insert a file from URL in the IMAGE at PATH
Examples
~~~~~~~~
Insert file from github
.......................
.. code-block:: bash
$ sudo docker insert 8283e18b24bc https://raw.github.com/metalivedev/django/master/postinstall /tmp/postinstall.sh
.. _cli_inspect:
``inspect``
-----------
::
Usage: docker inspect [OPTIONS] CONTAINER
Return low-level information on a container
.. _cli_kill:
``kill``
--------
::
Usage: docker kill CONTAINER [CONTAINER...]
Kill a running container (Send SIGKILL)
The main process inside the container will be sent SIGKILL.
.. _cli_login:
``login``
---------
::
Usage: docker login [OPTIONS] [SERVER]
Register or Login to the docker registry server
-e="": email
-p="": password
-u="": username
If you want to login to a private registry you can
specify this by adding the server name.
example:
docker login localhost:8080
.. _cli_logs:
``logs``
--------
::
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
.. _cli_port:
``port``
--------
::
Usage: docker port [OPTIONS] CONTAINER PRIVATE_PORT
Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
.. _cli_ps:
``ps``
------
::
Usage: docker ps [OPTIONS]
List containers
-a=false: Show all containers. Only running containers are shown by default.
-notrunc=false: Don't truncate output
-q=false: Only display numeric IDs
.. _cli_pull:
``pull``
--------
::
Usage: docker pull NAME
Pull an image or a repository from the registry
.. _cli_push:
``push``
--------
::
Usage: docker push NAME
Push an image or a repository to the registry
.. _cli_restart:
``restart``
-----------
::
Usage: docker restart [OPTIONS] NAME
Restart a running container
.. _cli_rm:
``rm``
------
::
Usage: docker rm [OPTIONS] CONTAINER
Remove one or more containers
-link="": Remove the link instead of the actual container
Examples:
~~~~~~~~~
.. code-block:: bash
$ docker rm /redis
/redis
This will remove the container referenced under the link ``/redis``.
.. code-block:: bash
$ docker rm -link /webapp/redis
/webapp/redis
This will remove the underlying link between ``/webapp`` and the ``/redis`` containers removing all
network communication.
.. _cli_rmi:
``rmi``
-------
::
Usage: docker rmi IMAGE [IMAGE...]
Remove one or more images
.. _cli_run:
``run``
-------
::
Usage: docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
Run a command in a new container
-a=map[]: Attach to stdin, stdout or stderr
-c=0: CPU shares (relative weight)
-cidfile="": Write the container ID to the file
-d=false: Detached mode: Run container in the background, print new container id
-e=[]: Set environment variables
-h="": Container host name
-i=false: Keep stdin open even if not attached
-privileged=false: Give extended privileges to this container
-m=0: Memory limit (in bytes)
-n=true: Enable networking for this container
-p=[]: Map a network port to the container
-rm=false: Automatically remove the container when it exits (incompatible with -d)
-t=false: Allocate a pseudo-tty
-u="": Username or UID
-dns=[]: Set custom dns servers for the container
-v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro]. If "container-dir" is missing, then docker creates a new volume.
-volumes-from="": Mount all volumes from the given container
-entrypoint="": Overwrite the default entrypoint set by the image
-w="": Working directory inside the container
-lxc-conf=[]: Add custom lxc options -lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
-sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)
-expose=[]: Expose a port from the container without publishing it to your host
-link="": Add link to another container (name:alias)
-name="": Assign the specified name to the container. If no name is specific docker will generate a random name
-P=false: Publish all exposed ports to the host interfaces
Examples
--------
.. code-block:: bash
sudo docker run -cidfile /tmp/docker_test.cid ubuntu echo "test"
This will create a container and print "test" to the console. The
``cidfile`` flag makes docker attempt to create a new file and write the
container ID to it. If the file exists already, docker will return an
error. Docker will close this file when docker run exits.
.. code-block:: bash
docker run mount -t tmpfs none /var/spool/squid
This will *not* work, because by default, most potentially dangerous
kernel capabilities are dropped; including ``cap_sys_admin`` (which is
required to mount filesystems). However, the ``-privileged`` flag will
allow it to run:
.. code-block:: bash
docker run -privileged mount -t tmpfs none /var/spool/squid
The ``-privileged`` flag gives *all* capabilities to the container,
and it also lifts all the limitations enforced by the ``device``
cgroup controller. In other words, the container can then do almost
everything that the host can do. This flag exists to allow special
use-cases, like running Docker within Docker.
.. code-block:: bash
docker run -w /path/to/dir/ -i -t ubuntu pwd
The ``-w`` lets the command being executed inside directory given,
here /path/to/dir/. If the path does not exists it is created inside the
container.
.. code-block:: bash
docker run -v `pwd`:`pwd` -w `pwd` -i -t ubuntu pwd
The ``-v`` flag mounts the current working directory into the container.
The ``-w`` lets the command being executed inside the current
working directory, by changing into the directory to the value
returned by ``pwd``. So this combination executes the command
using the container, but inside the current working directory.
.. code-block:: bash
docker run -p 127.0.0.1:80:8080 ubuntu bash
This binds port ``8080`` of the container to port ``80`` on 127.0.0.1 of the
host machine. :ref:`port_redirection` explains in detail how to manipulate ports
in Docker.
.. code-block:: bash
docker run -expose 80 ubuntu bash
This exposes port ``80`` of the container for use within a link without
publishing the port to the host system's interfaces. :ref:`port_redirection`
explains in detail how to manipulate ports in Docker.
.. code-block:: bash
docker run -name console -t -i ubuntu bash
This will create and run a new container with the container name
being ``console``.
.. code-block:: bash
docker run -link /redis:redis -name console ubuntu bash
The ``-link`` flag will link the container named ``/redis`` into the
newly created container with the alias ``redis``. The new container
can access the network and environment of the redis container via
environment variables. The ``-name`` flag will assign the name ``console``
to the newly created container.
.. _cli_search:
``search``
----------
::
Usage: docker search TERM
Search the docker index for images
-notrunc=false: Don't truncate output
-stars=0: Only displays with at least xxx stars
-trusted=false: Only show trusted builds
.. _cli_start:
``start``
---------
::
Usage: docker start [OPTIONS] NAME
Start a stopped container
-a=false: Attach container's stdout/stderr and forward all signals to the process
-i=false: Attach container's stdin
.. _cli_stop:
``stop``
--------
::
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
Stop a running container (Send SIGTERM, and then SIGKILL after grace period)
-t=10: Number of seconds to wait for the container to stop before killing it.
The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL
.. _cli_tag:
``tag``
-------
::
Usage: docker tag [OPTIONS] IMAGE REPOSITORY[:TAG]
Tag an image into a repository
-f=false: Force
.. _cli_top:
``top``
-------
::
Usage: docker top CONTAINER [ps OPTIONS]
Lookup the running processes of a container
.. _cli_version:
``version``
-----------
Show the version of the docker client, daemon, and latest released version.
.. _cli_wait:
``wait``
--------
::
Usage: docker wait [OPTIONS] NAME
Block until a container stops, then print its exit code.
@@ -0,0 +1,59 @@
:title: Attach Command
:description: Attach to a running container
:keywords: attach, container, docker, documentation
===========================================
``attach`` -- Attach to a running container
===========================================
::
Usage: docker attach CONTAINER
Attach to a running container.
You can detach from the container again (and leave it running) with
``CTRL-c`` (for a quiet exit) or ``CTRL-\`` to get a stacktrace of
the Docker client when it quits.
To stop a container, use ``docker stop``
To kill the container, use ``docker kill``
Examples:
---------
.. code-block:: bash
$ ID=$(sudo docker run -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
top - 02:05:52 up 3:05, 0 users, load average: 0.01, 0.02, 0.05
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.1%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 373572k total, 355560k used, 18012k free, 27872k buffers
Swap: 786428k total, 0k used, 786428k free, 221740k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 17200 1116 912 R 0 0.3 0:00.03 top
top - 02:05:55 up 3:05, 0 users, load average: 0.01, 0.02, 0.05
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 373572k total, 355244k used, 18328k free, 27872k buffers
Swap: 786428k total, 0k used, 786428k free, 221776k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 17208 1144 932 R 0 0.3 0:00.03 top
top - 02:05:58 up 3:06, 0 users, load average: 0.01, 0.02, 0.05
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 0.3%sy, 0.0%ni, 99.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 373572k total, 355780k used, 17792k free, 27880k buffers
Swap: 786428k total, 0k used, 786428k free, 221776k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 17208 1144 932 R 0 0.3 0:00.03 top
^C$
$ sudo docker stop $ID
@@ -0,0 +1,65 @@
:title: Build Command
:description: Build a new image from the Dockerfile passed via stdin
:keywords: build, docker, container, documentation
================================================
``build`` -- Build a container from a Dockerfile
================================================
::
Usage: docker build [OPTIONS] PATH | URL | -
Build a new container image from the source code at PATH
-t="": Repository name (and optionally a tag) to be applied to the resulting image in case of success.
-q=false: Suppress verbose build output.
-no-cache: Do not use the cache when building the image.
-rm: Remove intermediate containers after a successful build
When a single Dockerfile is given as URL, then no context is set. When a git repository is set as URL, the repository is used as context
Examples
--------
.. code-block:: bash
sudo docker build .
This will read the ``Dockerfile`` from the current directory. It will
also send any other files and directories found in the current
directory to the ``docker`` daemon.
The contents of this directory would be used by ``ADD`` commands found
within the ``Dockerfile``. This will send a lot of data to the
``docker`` daemon if the current directory contains a lot of data. If
the absolute path is provided instead of ``.`` then only the files and
directories required by the ADD commands from the ``Dockerfile`` will be
added to the context and transferred to the ``docker`` daemon.
.. code-block:: bash
sudo docker build -t vieux/apache:2.0 .
This will build like the previous example, but it will then tag the
resulting image. The repository name will be ``vieux/apache`` and the
tag will be ``2.0``
.. code-block:: bash
sudo docker build - < Dockerfile
This will read a ``Dockerfile`` from *stdin* without context. Due to
the lack of a context, no contents of any local directory will be sent
to the ``docker`` daemon. ``ADD`` doesn't work when running in this
mode because the absence of the context provides no source files to
copy to the container.
.. code-block:: bash
sudo docker build github.com/creack/docker-firefox
This will clone the Github repository and use it as context. The
``Dockerfile`` at the root of the repository is used as
``Dockerfile``. Note that you can specify an arbitrary git repository
by using the ``git://`` schema.
@@ -0,0 +1,52 @@
: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
===========================================================
::
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY [TAG]]
Create a new image from a container's changes
-m="": Commit message
-author="": Author (eg. "John Hannibal Smith <hannibal@a-team.com>"
-run="": Configuration to be applied when the image is launched with `docker run`.
(ex: '{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}')
Full -run example (multiline is ok within a single quote ``'``)
::
$ sudo docker commit -run='
{
"Entrypoint" : null,
"Privileged" : false,
"User" : "",
"VolumesFrom" : "",
"Cmd" : ["cat", "-e", "/etc/resolv.conf"],
"Dns" : ["8.8.8.8", "8.8.4.4"],
"MemorySwap" : 0,
"AttachStdin" : false,
"AttachStderr" : false,
"CpuShares" : 0,
"OpenStdin" : false,
"Volumes" : null,
"Hostname" : "122612f45831",
"PortSpecs" : ["22", "80", "443"],
"Image" : "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"Tty" : false,
"Env" : [
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"StdinOnce" : false,
"Domainname" : "",
"WorkingDir" : "/",
"NetworkDisabled" : false,
"Memory" : 0,
"AttachStdout" : false
}' $CONTAINER_ID
+14
View File
@@ -0,0 +1,14 @@
:title: Cp Command
:description: Copy files/folders from the containers filesystem to the host path
:keywords: cp, docker, container, documentation, copy
============================================================================
``cp`` -- Copy files/folders from the containers filesystem to the host path
============================================================================
::
Usage: docker cp CONTAINER:RESOURCE HOSTPATH
Copy files/folders from the containers filesystem to the host
path. Paths are relative to the root of the filesystem.
+13
View File
@@ -0,0 +1,13 @@
:title: Diff Command
:description: Inspect changes on a container's filesystem
:keywords: diff, docker, container, documentation
=======================================================
``diff`` -- Inspect changes on a container's filesystem
=======================================================
::
Usage: docker diff CONTAINER [OPTIONS]
Inspect changes on a container's filesystem
@@ -0,0 +1,34 @@
:title: Events Command
:description: Get real time events from the server
:keywords: events, docker, documentation
=================================================================
``events`` -- Get real time events from the server
=================================================================
::
Usage: docker events
Get real time events from the server
Examples
--------
Starting and stopping a container
.................................
.. code-block:: bash
$ sudo docker start 4386fb97867d
$ sudo docker stop 4386fb97867d
In another shell
.. code-block:: bash
$ sudo docker events
[2013-09-03 15:49:26 +0200 CEST] 4386fb97867d: (from 12de384bfb10) start
[2013-09-03 15:49:29 +0200 CEST] 4386fb97867d: (from 12de384bfb10) die
[2013-09-03 15:49:29 +0200 CEST] 4386fb97867d: (from 12de384bfb10) stop
@@ -0,0 +1,13 @@
: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
=================================================================
::
Usage: docker export CONTAINER
Export the contents of a filesystem as a tar archive
@@ -0,0 +1,13 @@
:title: History Command
:description: Show the history of an image
:keywords: history, docker, container, documentation
===========================================
``history`` -- Show the history of an image
===========================================
::
Usage: docker history [OPTIONS] IMAGE
Show the history of an image
@@ -0,0 +1,26 @@
:title: Images Command
:description: List images
:keywords: images, docker, container, documentation
=========================
``images`` -- List images
=========================
::
Usage: docker images [OPTIONS] [NAME]
List images
-a=false: show all images
-q=false: only show numeric IDs
-viz=false: output in graphviz format
Displaying images visually
--------------------------
::
sudo docker images -viz | dot -Tpng -o docker.png
.. image:: https://docs.docker.io/en/latest/_static/docker_images.gif
@@ -0,0 +1,44 @@
: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
==========================================================================
::
Usage: docker import URL|- [REPOSITORY [TAG]]
Create a new filesystem image from the contents of a tarball
At this time, the URL must start with ``http`` and point to a single
file archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) containing a
root filesystem. If you would like to import from a local directory or
archive, you can use the ``-`` parameter to take the data from
standard in.
Examples
--------
Import from a remote location
.............................
``$ sudo docker import http://example.com/exampleimage.tgz exampleimagerepo``
Import from a local file
........................
Import to docker via pipe and standard in
``$ cat exampleimage.tgz | sudo docker import - exampleimagelocal``
Import from a local directory
.............................
``$ sudo tar -c . | docker import - exampleimagedir``
Note the ``sudo`` in this example -- you must preserve the ownership
of the files (especially root ownership) during the archiving with
tar. If you are not root (or sudo) when you tar, then the ownerships
might not get preserved.
+13
View File
@@ -0,0 +1,13 @@
:title: Info Command
:description: Display system-wide information.
:keywords: info, docker, information, documentation
===========================================
``info`` -- Display system-wide information
===========================================
::
Usage: docker info
Display system-wide information.
@@ -0,0 +1,23 @@
:title: Insert Command
:description: Insert a file in an image
:keywords: insert, image, docker, documentation
==========================================================================
``insert`` -- Insert a file in an image
==========================================================================
::
Usage: docker insert IMAGE URL PATH
Insert a file from URL in the IMAGE at PATH
Examples
--------
Insert file from github
.......................
.. code-block:: bash
$ sudo docker insert 8283e18b24bc https://raw.github.com/metalivedev/django/master/postinstall /tmp/postinstall.sh
@@ -0,0 +1,13 @@
:title: Inspect Command
:description: Return low-level information on a container
:keywords: inspect, container, docker, documentation
==========================================================
``inspect`` -- Return low-level information on a container
==========================================================
::
Usage: docker inspect [OPTIONS] CONTAINER
Return low-level information on a container
+13
View File
@@ -0,0 +1,13 @@
:title: Kill Command
:description: Kill a running container
:keywords: kill, container, docker, documentation
====================================
``kill`` -- Kill a running container
====================================
::
Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
Kill a running container
+29
View File
@@ -0,0 +1,29 @@
:title: Link Command
:description: Add a link or rename the link for a container
:keywords: link, docker, container, documentation, link, links
============================================================================
``link`` -- Add a link or rename the link for a container
============================================================================
::
Usage: docker link CURRENT_NAME NEW_NAME
Link a container to a new name.
Examples:
--------
.. code-block:: bash
$ docker link /59669e088202c2ebe150b4346cb3301562d073b51261176a354a74e8f618bfbc /redis
$ docker ls
NAME ID IMAGE
/redis 59669e088202c2ebe150b4346cb3301562d073b51261176a354a74e8f618bfbc crosbymichael/redis:latest
/59669e088202c2ebe150b4346cb3301562d073b51261176a354a74e8f618bfbc 59669e088202c2ebe150b4346cb3301562d073b51261176a354a74e8f618bfbc crosbymichael/redis:latest
This will create a new link for the existing name ``/59669e088202c2ebe150b4346cb3301562d073b51261176a354a74e8f618bfbc``
with the new name ``/redis`` so that we can new reference the same container under the new name ``/redis``.
@@ -0,0 +1,24 @@
: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
============================================================
::
Usage: docker login [OPTIONS] [SERVER]
Register or Login to the docker registry server
-e="": email
-p="": password
-u="": username
If you want to login to a private registry you can
specify this by adding the server name.
example:
docker login localhost:8080
+13
View File
@@ -0,0 +1,13 @@
:title: Logs Command
:description: Fetch the logs of a container
:keywords: logs, container, docker, documentation
=========================================
``logs`` -- Fetch the logs of a container
=========================================
::
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
+29
View File
@@ -0,0 +1,29 @@
:title: Ls Command
:description: Ls all links for containers
:keywords: ls, docker, container, documentation, link, links
============================================================================
``ls`` -- List all links for containers
============================================================================
::
Usage: docker ls
List all links for containers and display the relationship between parent
and child containers.
Examples:
--------
.. code-block:: bash
$ docker ls
NAME ID IMAGE
/redis 39588b6a45100ef5b328b2c302ea085624f29e6cbab70f88be04793af02cec89 crosbymichael/redis:latest
/webapp cffb86ffa80b11cd8777d300759ee53c4e61729431c30ec9552dd9e6d3abc87d demo:latest
/webapp/redis 39588b6a45100ef5b328b2c302ea085624f29e6cbab70f88be04793af02cec89 crosbymichael/redis:latest
This will display all links and the names that you can use the reference the link. Parent child
relationships are also displayed with ls.
+13
View File
@@ -0,0 +1,13 @@
: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
=========================================================================
::
Usage: docker port [OPTIONS] CONTAINER PRIVATE_PORT
Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
+17
View File
@@ -0,0 +1,17 @@
:title: Ps Command
:description: List containers
:keywords: ps, docker, documentation, container
=========================
``ps`` -- List containers
=========================
::
Usage: docker ps [OPTIONS]
List containers
-a=false: Show all containers. Only running containers are shown by default.
-notrunc=false: Don't truncate output
-q=false: Only display numeric IDs
+13
View File
@@ -0,0 +1,13 @@
: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
=========================================================================
::
Usage: docker pull NAME
Pull an image or a repository from the registry

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