Compare commits

..

1 Commits

Author SHA1 Message Date
Jessica Frazelle 7ddecf74be Bump version to v1.7.0
Signed-off-by: Jessica Frazelle <princess@docker.com>
2015-06-04 12:14:27 -07:00
410 changed files with 2100 additions and 2505 deletions
-3
View File
@@ -30,8 +30,5 @@ docs/_build
docs/_static
docs/_templates
docs/changed-files
# generated by man/man/md2man-all.sh
man/man1
man/man5
pyenv
vendor/pkg/
+1 -1
View File
@@ -17,7 +17,7 @@
#### Quality
* Networking stack was entirely rewritten as part of the libnetwork effort
* Engine internals refactoring
* Engine internals refactoring (shout out to the contributors?)
* Volumes code was entirely rewritten to support the plugins effort
+ Sending SIGUSR1 to a daemon will dump all goroutines stacks without exiting
+26
View File
@@ -22,6 +22,11 @@ DOCKER_ENVS := \
BIND_DIR := $(if $(BINDDIR),$(BINDDIR),$(if $(DOCKER_HOST),,bundles))
DOCKER_MOUNT := $(if $(BIND_DIR),-v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/docker/docker/$(BIND_DIR)")
# to allow `make DOCSDIR=docs docs-shell` (to create a bind mount in docs)
DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR)/$(DOCSDIR):/$(DOCSDIR))
# to allow `make DOCSPORT=9000 docs`
DOCSPORT := 8000
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
DOCKER_IMAGE := docker-dev$(if $(GIT_BRANCH),:$(GIT_BRANCH))
@@ -45,6 +50,19 @@ binary: build
cross: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross
docs: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" mkdocs serve
docs-shell: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" bash
docs-release: docs-build
$(DOCKER_RUN_DOCS) -e OPTIONS -e BUILD_ROOT -e DISTRIBUTION_ID \
-v $(CURDIR)/docs/awsconfig:/docs/awsconfig \
"$(DOCKER_DOCS_IMAGE)" ./release.sh
docs-test: docs-build
$(DOCKER_RUN_DOCS) "$(DOCKER_DOCS_IMAGE)" ./test.sh
test: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross test-unit test-integration-cli test-docker-py
@@ -67,5 +85,13 @@ shell: build
build: bundles
docker build -t "$(DOCKER_IMAGE)" .
docs-build:
cp ./VERSION docs/VERSION
echo "$(GIT_BRANCH)" > docs/GIT_BRANCH
# echo "$(AWS_S3_BUCKET)" > docs/AWS_S3_BUCKET
echo "$(GITCOMMIT)" > docs/GITCOMMIT
docker pull docs/base
docker build -t "$(DOCKER_DOCS_IMAGE)" docs
bundles:
mkdir bundles
+1 -1
View File
@@ -30,7 +30,7 @@ security@docker.com and not by creating a github issue.
A common method for distributing applications and sandboxing their
execution is to use virtual machines, or VMs. Typical VM formats are
VMware's vmdk, Oracle Virtualbox's vdi, and Amazon EC2's ami. In theory
VMWare's vmdk, Oracle Virtualbox's vdi, and Amazon EC2's ami. In theory
these formats should allow every developer to automatically package
their application into a "machine" for easy distribution and deployment.
In practice, that almost never happens, for a few reasons:
+1 -1
View File
@@ -1 +1 @@
1.7.0-rc4
1.7.0-rc2
+33 -14
View File
@@ -36,6 +36,7 @@ import (
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
"github.com/docker/libnetwork/portallocator"
)
type ServerConfig struct {
@@ -398,7 +399,6 @@ func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *ht
}
until = u
}
timer := time.NewTimer(0)
timer.Stop()
if until > 0 {
@@ -457,9 +457,6 @@ func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *ht
}
current, l := es.Subscribe()
if since == -1 {
current = nil
}
defer es.Evict(l)
for _, ev := range current {
if ev.Time < since {
@@ -575,16 +572,7 @@ func (s *Server) getContainersStats(version version.Version, w http.ResponseWrit
return fmt.Errorf("Missing parameter")
}
stream := boolValueOrDefault(r, "stream", true)
var out io.Writer
if !stream {
w.Header().Set("Content-Type", "application/json")
out = w
} else {
out = ioutils.NewWriteFlusher(w)
}
return s.daemon.ContainerStats(vars["name"], stream, out)
return s.daemon.ContainerStats(vars["name"], boolValueOrDefault(r, "stream", true), ioutils.NewWriteFlusher(w))
}
func (s *Server) getContainersLogs(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -668,6 +656,10 @@ func (s *Server) postCommit(version version.Version, w http.ResponseWriter, r *h
return err
}
if c == nil {
c = &runconfig.Config{}
}
containerCommitConfig := &daemon.ContainerCommitConfig{
Pause: pause,
Repo: r.Form.Get("repo"),
@@ -1584,3 +1576,30 @@ func createRouter(s *Server) *mux.Router {
return r
}
func allocateDaemonPort(addr string) error {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return err
}
intPort, err := strconv.Atoi(port)
if err != nil {
return err
}
var hostIPs []net.IP
if parsedIP := net.ParseIP(host); parsedIP != nil {
hostIPs = append(hostIPs, parsedIP)
} else if hostIPs, err = net.LookupIP(host); err != nil {
return fmt.Errorf("failed to lookup %s address in host specification", host)
}
pa := portallocator.Get()
for _, hostIP := range hostIPs {
if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
return fmt.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
}
}
return nil
}
-29
View File
@@ -6,12 +6,10 @@ import (
"fmt"
"net"
"net/http"
"strconv"
"github.com/docker/docker/daemon"
"github.com/docker/docker/pkg/sockets"
"github.com/docker/docker/pkg/systemd"
"github.com/docker/libnetwork/portallocator"
)
// newServer sets up the required serverClosers and does protocol specific checking.
@@ -69,30 +67,3 @@ func (s *Server) AcceptConnections(d *daemon.Daemon) {
close(s.start)
}
}
func allocateDaemonPort(addr string) error {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return err
}
intPort, err := strconv.Atoi(port)
if err != nil {
return err
}
var hostIPs []net.IP
if parsedIP := net.ParseIP(host); parsedIP != nil {
hostIPs = append(hostIPs, parsedIP)
} else if hostIPs, err = net.LookupIP(host); err != nil {
return fmt.Errorf("failed to lookup %s address in host specification", host)
}
pa := portallocator.Get()
for _, hostIP := range hostIPs {
if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
return fmt.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
}
}
return nil
}
+1 -6
View File
@@ -11,7 +11,7 @@ import (
)
// NewServer sets up the required Server and does protocol specific checking.
func (s *Server) newServer(proto, addr string) (serverCloser, error) {
func (s *Server) newServer(proto, addr string) (Server, error) {
var (
err error
l net.Listener
@@ -22,7 +22,6 @@ func (s *Server) newServer(proto, addr string) (serverCloser, error) {
if err != nil {
return nil, err
}
default:
return nil, errors.New("Invalid protocol format. Windows only supports tcp.")
}
@@ -44,7 +43,3 @@ func (s *Server) AcceptConnections(d *daemon.Daemon) {
close(s.start)
}
}
func allocateDaemonPort(addr string) error {
return nil
}
+2 -2
View File
@@ -94,9 +94,9 @@ type ImageInspect struct {
// GET "/containers/json"
type Port struct {
IP string `json:",omitempty"`
IP string
PrivatePort int
PublicPort int `json:",omitempty"`
PublicPort int
Type string
}
-4
View File
@@ -221,10 +221,6 @@ func Commit(d *daemon.Daemon, name string, c *daemon.ContainerCommitConfig) (str
return "", err
}
if c.Config == nil {
c.Config = &runconfig.Config{}
}
newConfig, err := BuildFromConfig(d, c.Config, c.Changes)
if err != nil {
return "", err
+4 -2
View File
@@ -7,6 +7,7 @@ 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:-}
UNSHARE_BINARY=${UNSHARE_BINARY:-/usr/bin/unshare}
start() {
checkpath -f -m 0644 -o root:docker "$DOCKER_LOGFILE"
@@ -16,11 +17,12 @@ start() {
ebegin "Starting docker daemon"
start-stop-daemon --start --background \
--exec "$DOCKER_BINARY" \
--exec "$UNSHARE_BINARY" \
--pidfile "$DOCKER_PIDFILE" \
--stdout "$DOCKER_LOGFILE" \
--stderr "$DOCKER_LOGFILE" \
-- -d -p "$DOCKER_PIDFILE" \
-- --mount \
-- "$DOCKER_BINARY" -d -p "$DOCKER_PIDFILE" \
$DOCKER_OPTS
eend $?
}
+1 -1
View File
@@ -1,6 +1,6 @@
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
Documentation=http://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
+4 -3
View File
@@ -30,6 +30,7 @@ DOCKER_SSD_PIDFILE=/var/run/$BASE-ssd.pid
DOCKER_LOGFILE=/var/log/$BASE.log
DOCKER_OPTS=
DOCKER_DESC="Docker"
UNSHARE=${UNSHARE:-/usr/bin/unshare}
# Get lsb functions
. /lib/lsb/init-functions
@@ -99,11 +100,11 @@ case "$1" in
log_begin_msg "Starting $DOCKER_DESC: $BASE"
start-stop-daemon --start --background \
--no-close \
--exec "$DOCKER" \
--exec "$UNSHARE" \
--pidfile "$DOCKER_SSD_PIDFILE" \
--make-pidfile \
-- \
-d -p "$DOCKER_PIDFILE" \
-- --mount \
-- "$DOCKER" -d -p "$DOCKER_PIDFILE" \
$DOCKER_OPTS \
>> "$DOCKER_LOGFILE" 2>&1
log_end_msg $?
+1 -1
View File
@@ -39,7 +39,7 @@ script
if [ -f /etc/default/$UPSTART_JOB ]; then
. /etc/default/$UPSTART_JOB
fi
exec "$DOCKER" -d $DOCKER_OPTS
exec unshare -m -- "$DOCKER" -d $DOCKER_OPTS
end script
# Don't emit "started" event until docker.sock is ready.
+1 -1
View File
@@ -80,7 +80,7 @@ sudo mkdir -m 755 dev
# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target"
# locales
sudo rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
# docs and man pages
# docs
sudo rm -rf usr/share/{man,doc,info,gnome/help}
# cracklib
sudo rm -rf usr/share/cracklib
+1 -1
View File
@@ -10,7 +10,7 @@ shift
# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target"
# locales
rm -rf usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
# docs and man pages
# docs
rm -rf usr/share/{man,doc,info,gnome/help}
# cracklib
rm -rf usr/share/cracklib
+38 -5
View File
@@ -1,6 +1,8 @@
package daemon
import (
"net"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/runconfig"
@@ -14,7 +16,9 @@ const (
// CommonConfig defines the configuration of a docker daemon which are
// common across platforms.
type CommonConfig struct {
AutoRestart bool
AutoRestart bool
// Bridge holds bridge network specific configuration.
Bridge bridgeConfig
Context map[string][]string
CorsHeaders string
DisableNetwork bool
@@ -22,10 +26,8 @@ type CommonConfig struct {
DnsSearch []string
EnableCors bool
ExecDriver string
ExecOptions []string
ExecRoot string
GraphDriver string
GraphOptions []string
Labels []string
LogConfig runconfig.LogConfig
Mtu int
@@ -34,26 +36,57 @@ type CommonConfig struct {
TrustKeyPath string
}
// bridgeConfig stores all the bridge driver specific
// configuration.
type bridgeConfig struct {
EnableIPv6 bool
EnableIPTables bool
EnableIPForward bool
EnableIPMasq bool
EnableUserlandProxy bool
DefaultIP net.IP
Iface string
IP string
FixedCIDR string
FixedCIDRv6 string
DefaultGatewayIPv4 string
DefaultGatewayIPv6 string
InterContainerCommunication bool
}
// InstallCommonFlags adds command-line options to the top-level flag parser for
// the current process.
// Subsequent calls to `flag.Parse` will populate config with values parsed
// from the command-line.
func (config *Config) InstallCommonFlags() {
opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options")
flag.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, "Path to use for daemon PID file")
flag.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, "Root of the Docker runtime")
flag.StringVar(&config.ExecRoot, []string{"-exec-root"}, "/var/run/docker", "Root of the Docker execdriver")
flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
flag.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
flag.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
flag.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
flag.StringVar(&config.Bridge.DefaultGatewayIPv4, []string{"-default-gateway"}, "", "Container default gateway IPv4 address")
flag.StringVar(&config.Bridge.DefaultGatewayIPv6, []string{"-default-gateway-v6"}, "", "Container default gateway IPv6 address")
flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, defaultExec, "Exec driver to use")
flag.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, "Set the containers network MTU")
flag.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header")
flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API")
opts.IPVar(&config.Bridge.DefaultIP, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
// FIXME: why the inconsistency between "hosts" and "sockets"?
opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use")
opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "DNS search domains to use")
opts.LabelListVar(&config.Labels, []string{"-label"}, "Set key=value labels to the daemon")
flag.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", "Default driver for container logs")
opts.LogOptsVar(config.LogConfig.Config, []string{"-log-opt"}, "Set log driver options")
flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
}
+4 -36
View File
@@ -1,8 +1,6 @@
package daemon
import (
"net"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/ulimit"
@@ -21,32 +19,13 @@ type Config struct {
CommonConfig
// Fields below here are platform specific.
// Bridge holds bridge network specific configuration.
Bridge bridgeConfig
EnableSelinuxSupport bool
ExecOptions []string
GraphOptions []string
SocketGroup string
Ulimits map[string]*ulimit.Ulimit
}
// bridgeConfig stores all the bridge driver specific
// configuration.
type bridgeConfig struct {
EnableIPv6 bool
EnableIPTables bool
EnableIPForward bool
EnableIPMasq bool
EnableUserlandProxy bool
DefaultIP net.IP
Iface string
IP string
FixedCIDR string
FixedCIDRv6 string
DefaultGatewayIPv4 net.IP
DefaultGatewayIPv6 net.IP
InterContainerCommunication bool
}
// InstallFlags adds command-line options to the top-level flag parser for
// the current process.
// Subsequent calls to `flag.Parse` will populate config with values parsed
@@ -56,21 +35,10 @@ func (config *Config) InstallFlags() {
config.InstallCommonFlags()
// Then platform-specific install flags
opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options")
opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options")
flag.BoolVar(&config.EnableSelinuxSupport, []string{"-selinux-enabled"}, false, "Enable selinux support")
flag.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", "Group for the unix socket")
config.Ulimits = make(map[string]*ulimit.Ulimit)
opts.UlimitMapVar(config.Ulimits, []string{"-default-ulimit"}, "Set default ulimits for containers")
flag.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, "Enable addition of iptables rules")
flag.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
flag.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, "Enable IP masquerading")
flag.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, "Enable IPv6 networking")
flag.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", "Specify network bridge IP")
flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
opts.IPVar(&config.Bridge.DefaultGatewayIPv4, []string{"-default-gateway"}, "", "Container default gateway IPv4 address")
opts.IPVar(&config.Bridge.DefaultGatewayIPv6, []string{"-default-gateway-v6"}, "", "Container default gateway IPv6 address")
flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
opts.IPVar(&config.Bridge.DefaultIP, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports")
flag.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, "Use userland proxy for loopback traffic")
}
+1 -4
View File
@@ -73,10 +73,7 @@ type CommonContainer struct {
MountLabel, ProcessLabel string
RestartCount int
UpdateDns bool
MountPoints map[string]*mountPoint
Volumes map[string]string // Deprecated since 1.7, kept for backwards compatibility
VolumesRW map[string]bool // Deprecated since 1.7, kept for backwards compatibility
MountPoints map[string]*mountPoint
hostConfig *runconfig.HostConfig
command *execdriver.Command
-4
View File
@@ -15,10 +15,6 @@ import (
)
func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig) (string, []string, error) {
if config == nil {
return "", nil, fmt.Errorf("Config cannot be empty in order to create a container")
}
warnings, err := daemon.verifyHostConfig(hostConfig)
if err != nil {
return "", warnings, err
+36 -83
View File
@@ -1,7 +1,6 @@
package daemon
import (
"errors"
"fmt"
"io"
"io/ioutil"
@@ -49,9 +48,10 @@ import (
"github.com/docker/docker/utils"
volumedrivers "github.com/docker/docker/volume/drivers"
"github.com/docker/docker/volume/local"
"github.com/docker/libcontainer/netlink"
)
const defaultVolumesPathName = "volumes"
var (
validContainerNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
validContainerNamePattern = regexp.MustCompile(`^/?` + validContainerNameChars + `+$`)
@@ -158,7 +158,12 @@ func (daemon *Daemon) containerRoot(id string) string {
// This is typically done at startup.
func (daemon *Daemon) load(id string) (*Container, error) {
container := &Container{
CommonContainer: daemon.newBaseContainer(id),
CommonContainer: CommonContainer{
State: NewState(),
root: daemon.containerRoot(id),
MountPoints: make(map[string]*mountPoint),
execCommands: newExecStore(),
},
}
if err := container.FromDisk(); err != nil {
@@ -521,21 +526,25 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID
daemon.generateHostname(id, config)
entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
base := daemon.newBaseContainer(id)
base.Created = time.Now().UTC()
base.Path = entrypoint
base.Args = args //FIXME: de-duplicate from config
base.Config = config
base.hostConfig = &runconfig.HostConfig{}
base.ImageID = imgID
base.NetworkSettings = &network.Settings{}
base.Name = name
base.Driver = daemon.driver.String()
base.ExecDriver = daemon.execDriver.Name()
container := &Container{
CommonContainer: base,
CommonContainer: CommonContainer{
ID: id, // FIXME: we should generate the ID here instead of receiving it as an argument
Created: time.Now().UTC(),
Path: entrypoint,
Args: args, //FIXME: de-duplicate from config
Config: config,
hostConfig: &runconfig.HostConfig{},
ImageID: imgID,
NetworkSettings: &network.Settings{},
Name: name,
Driver: daemon.driver.String(),
ExecDriver: daemon.execDriver.Name(),
State: NewState(),
execCommands: newExecStore(),
MountPoints: map[string]*mountPoint{},
},
}
container.root = daemon.containerRoot(container.ID)
return container, err
}
@@ -674,8 +683,6 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
if config.Bridge.Iface != "" && config.Bridge.IP != "" {
return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
}
setDefaultMtu(config)
if !config.Bridge.EnableIPTables && !config.Bridge.InterContainerCommunication {
return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
}
@@ -785,7 +792,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
return nil, err
}
volumesDriver, err := local.New(config.Root)
volumesDriver, err := local.New(filepath.Join(config.Root, defaultVolumesPathName))
if err != nil {
return nil, err
}
@@ -956,14 +963,6 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error)
netOption["FixedCIDRv6"] = fCIDRv6
}
if config.Bridge.DefaultGatewayIPv4 != nil {
netOption["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4
}
if config.Bridge.DefaultGatewayIPv6 != nil {
netOption["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6
}
// --ip processing
if config.Bridge.DefaultIP != nil {
netOption["DefaultBindingIP"] = config.Bridge.DefaultIP
@@ -983,6 +982,16 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error)
}
func (daemon *Daemon) Shutdown() error {
if daemon.containerGraph != nil {
if err := daemon.containerGraph.Close(); err != nil {
logrus.Errorf("Error during container graph.Close(): %v", err)
}
}
if daemon.driver != nil {
if err := daemon.driver.Cleanup(); err != nil {
logrus.Errorf("Error during graph storage driver.Cleanup(): %v", err)
}
}
if daemon.containers != nil {
group := sync.WaitGroup{}
logrus.Debug("starting clean shutdown of all containers...")
@@ -1004,23 +1013,6 @@ func (daemon *Daemon) Shutdown() error {
}
}
group.Wait()
// trigger libnetwork GC only if it's initialized
if daemon.netController != nil {
daemon.netController.GC()
}
}
if daemon.containerGraph != nil {
if err := daemon.containerGraph.Close(); err != nil {
logrus.Errorf("Error during container graph.Close(): %v", err)
}
}
if daemon.driver != nil {
if err := daemon.driver.Cleanup(); err != nil {
logrus.Errorf("Error during graph storage driver.Cleanup(): %v", err)
}
}
return nil
@@ -1254,42 +1246,3 @@ func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.
container.toDisk()
return nil
}
func (daemon *Daemon) newBaseContainer(id string) CommonContainer {
return CommonContainer{
ID: id,
State: NewState(),
MountPoints: make(map[string]*mountPoint),
Volumes: make(map[string]string),
VolumesRW: make(map[string]bool),
execCommands: newExecStore(),
root: daemon.containerRoot(id),
}
}
func setDefaultMtu(config *Config) {
// do nothing if the config does not have the default 0 value.
if config.Mtu != 0 {
return
}
config.Mtu = defaultNetworkMtu
if routeMtu, err := getDefaultRouteMtu(); err == nil {
config.Mtu = routeMtu
}
}
var errNoDefaultRoute = errors.New("no default route was found")
// getDefaultRouteMtu returns the MTU for the default route's interface.
func getDefaultRouteMtu() (int, error) {
routes, err := netlink.NetworkGetRoutes()
if err != nil {
return 0, err
}
for _, r := range routes {
if r.Default {
return r.Iface.MTU, nil
}
}
return 0, errNoDefaultRoute
}
+7 -220
View File
@@ -12,8 +12,6 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/truncindex"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/drivers"
"github.com/docker/docker/volume/local"
)
//
@@ -180,11 +178,10 @@ func TestLoadWithVolume(t *testing.T) {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
daemon := &Daemon{
repository: tmp,
root: tmp,
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
@@ -217,7 +214,7 @@ func TestLoadWithVolume(t *testing.T) {
t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
}
newVolumeContent := filepath.Join(volumePath, local.VolumeDataPathName, "helo")
newVolumeContent := filepath.Join(volumePath, "helo")
b, err := ioutil.ReadFile(newVolumeContent)
if err != nil {
t.Fatal(err)
@@ -268,11 +265,10 @@ func TestLoadWithBindMount(t *testing.T) {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
daemon := &Daemon{
repository: tmp,
root: tmp,
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
@@ -305,212 +301,3 @@ func TestLoadWithBindMount(t *testing.T) {
t.Fatalf("Expected mount point to be RW but it was not\n")
}
}
func TestLoadWithVolume17RC(t *testing.T) {
tmp, err := ioutil.TempDir("", "docker-daemon-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
containerPath := filepath.Join(tmp, containerId)
if err := os.MkdirAll(containerPath, 0755); err != nil {
t.Fatal(err)
}
hostVolumeId := "6a3c03fc4a4e588561a543cc3bdd50089e27bd11bbb0e551e19bf735e2514101"
volumePath := filepath.Join(tmp, "volumes", hostVolumeId)
if err := os.MkdirAll(volumePath, 0755); err != nil {
t.Fatal(err)
}
content := filepath.Join(volumePath, "helo")
if err := ioutil.WriteFile(content, []byte("HELO"), 0644); err != nil {
t.Fatal(err)
}
config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
"Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
"ID":"d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e","Created":"2015-05-26T16:48:53.7987917Z","Path":"top",
"Args":[],"Config":{"Hostname":"d59df5276e7b","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"",
"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":true,"OpenStdin":true,
"StdinOnce":false,"Env":null,"Cmd":["top"],"Image":"ubuntu:latest","Volumes":null,"WorkingDir":"","Entrypoint":null,
"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{}},"Image":"07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
"NetworkSettings":{"IPAddress":"172.17.0.1","IPPrefixLen":16,"MacAddress":"02:42:ac:11:00:01","LinkLocalIPv6Address":"fe80::42:acff:fe11:1",
"LinkLocalIPv6PrefixLen":64,"GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"Gateway":"172.17.42.1","IPv6Gateway":"","Bridge":"docker0","PortMapping":null,"Ports":{}},
"ResolvConfPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/resolv.conf",
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname",
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts",
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log",
"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
"UpdateDns":false,"MountPoints":{"/vol1":{"Name":"6a3c03fc4a4e588561a543cc3bdd50089e27bd11bbb0e551e19bf735e2514101","Destination":"/vol1","Driver":"local","RW":true,"Source":"","Relabel":""}},"AppliedVolumesFrom":null}`
if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(config), 0644); err != nil {
t.Fatal(err)
}
hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
"Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
t.Fatal(err)
}
err = daemon.verifyVolumesInfo(c)
if err != nil {
t.Fatal(err)
}
if len(c.MountPoints) != 1 {
t.Fatalf("Expected 1 volume mounted, was 0\n")
}
m := c.MountPoints["/vol1"]
if m.Name != hostVolumeId {
t.Fatalf("Expected mount name to be %s, was %s\n", hostVolumeId, m.Name)
}
if m.Destination != "/vol1" {
t.Fatalf("Expected mount destination /vol1, was %s\n", m.Destination)
}
if !m.RW {
t.Fatalf("Expected mount point to be RW but it was not\n")
}
if m.Driver != volume.DefaultDriverName {
t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
}
newVolumeContent := filepath.Join(volumePath, local.VolumeDataPathName, "helo")
b, err := ioutil.ReadFile(newVolumeContent)
if err != nil {
t.Fatal(err)
}
if string(b) != "HELO" {
t.Fatalf("Expected HELO, was %s\n", string(b))
}
}
func TestRemoveLocalVolumesFollowingSymlinks(t *testing.T) {
tmp, err := ioutil.TempDir("", "docker-daemon-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
containerPath := filepath.Join(tmp, containerId)
if err := os.MkdirAll(containerPath, 0755); err != nil {
t.Fatal(err)
}
hostVolumeId := stringid.GenerateRandomID()
vfsPath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
volumePath := filepath.Join(tmp, "volumes", hostVolumeId)
if err := os.MkdirAll(vfsPath, 0755); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(volumePath, 0755); err != nil {
t.Fatal(err)
}
content := filepath.Join(vfsPath, "helo")
if err := ioutil.WriteFile(content, []byte("HELO"), 0644); err != nil {
t.Fatal(err)
}
config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
"Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
"ID":"d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e","Created":"2015-05-26T16:48:53.7987917Z","Path":"top",
"Args":[],"Config":{"Hostname":"d59df5276e7b","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"Cpuset":"",
"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":true,"OpenStdin":true,
"StdinOnce":false,"Env":null,"Cmd":["top"],"Image":"ubuntu:latest","Volumes":null,"WorkingDir":"","Entrypoint":null,
"NetworkDisabled":false,"MacAddress":"","OnBuild":null,"Labels":{}},"Image":"07f8e8c5e66084bef8f848877857537ffe1c47edd01a93af27e7161672ad0e95",
"NetworkSettings":{"IPAddress":"172.17.0.1","IPPrefixLen":16,"MacAddress":"02:42:ac:11:00:01","LinkLocalIPv6Address":"fe80::42:acff:fe11:1",
"LinkLocalIPv6PrefixLen":64,"GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"Gateway":"172.17.42.1","IPv6Gateway":"","Bridge":"docker0","PortMapping":null,"Ports":{}},
"ResolvConfPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/resolv.conf",
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname",
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts",
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log",
"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
"UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
cfg := fmt.Sprintf(config, vfsPath)
if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(cfg), 0644); err != nil {
t.Fatal(err)
}
hostConfig := `{"Binds":[],"ContainerIDFile":"","LxcConf":[],"Memory":0,"MemorySwap":0,"CpuShares":0,"CpusetCpus":"",
"Privileged":false,"PortBindings":{},"Links":null,"PublishAllPorts":false,"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,
"Devices":[],"NetworkMode":"bridge","IpcMode":"","PidMode":"","CapAdd":null,"CapDrop":null,"RestartPolicy":{"Name":"no","MaximumRetryCount":0},
"SecurityOpt":null,"ReadonlyRootfs":false,"Ulimits":null,"LogConfig":{"Type":"","Config":null},"CgroupParent":""}`
if err = ioutil.WriteFile(filepath.Join(containerPath, "hostconfig.json"), []byte(hostConfig), 0644); err != nil {
t.Fatal(err)
}
daemon, err := initDaemonForVolumesTest(tmp)
if err != nil {
t.Fatal(err)
}
defer volumedrivers.Unregister(volume.DefaultDriverName)
c, err := daemon.load(containerId)
if err != nil {
t.Fatal(err)
}
err = daemon.verifyVolumesInfo(c)
if err != nil {
t.Fatal(err)
}
if len(c.MountPoints) != 1 {
t.Fatalf("Expected 1 volume mounted, was 0\n")
}
m := c.MountPoints["/vol1"]
v, err := createVolume(m.Name, m.Driver)
if err != nil {
t.Fatal(err)
}
if err := removeVolume(v); err != nil {
t.Fatal(err)
}
fi, err := os.Stat(vfsPath)
if err == nil || !os.IsNotExist(err) {
t.Fatalf("Expected vfs path to not exist: %v - %v\n", fi, err)
}
}
func initDaemonForVolumesTest(tmp string) (*Daemon, error) {
daemon := &Daemon{
repository: tmp,
root: tmp,
}
volumesDriver, err := local.New(tmp)
if err != nil {
return nil, err
}
volumedrivers.Register(volumesDriver, volumesDriver.Name())
return daemon, nil
}
-1
View File
@@ -24,7 +24,6 @@ func InitContainer(c *Command) *configs.Config {
container.Devices = c.AutoCreatedDevices
container.Rootfs = c.Rootfs
container.Readonlyfs = c.ReadonlyRootfs
container.Privatefs = true
// check to see if we are running in ramdisk to disable pivot root
container.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
+1 -1
View File
@@ -124,7 +124,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
dataPath = d.containerDir(c.ID)
)
if c.Network == nil || (c.Network.NamespacePath == "" && c.Network.ContainerID == "") {
if c.Network.NamespacePath == "" && c.Network.ContainerID == "" {
return execdriver.ExitStatus{ExitCode: -1}, fmt.Errorf("empty namespace path for non-container network")
}
+2 -4
View File
@@ -17,7 +17,6 @@ import (
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/libcontainer/label"
zfs "github.com/mistifyio/go-zfs"
)
@@ -282,15 +281,14 @@ func (d *Driver) Remove(id string) error {
func (d *Driver) Get(id, mountLabel string) (string, error) {
mountpoint := d.MountPath(id)
filesystem := d.ZfsPath(id)
options := label.FormatMountLabel("", mountLabel)
log.Debugf(`[zfs] mount("%s", "%s", "%s")`, filesystem, mountpoint, options)
log.Debugf(`[zfs] mount("%s", "%s", "%s")`, filesystem, mountpoint, mountLabel)
// Create the target directories if they don't exist
if err := os.MkdirAll(mountpoint, 0755); err != nil && !os.IsExist(err) {
return "", err
}
err := mount.Mount(filesystem, mountpoint, "zfs", options)
err := mount.Mount(filesystem, mountpoint, "zfs", mountLabel)
if err != nil {
return "", fmt.Errorf("error creating zfs mount of %s to %s: %v", filesystem, mountpoint, err)
}
+16 -24
View File
@@ -15,39 +15,31 @@ func (daemon *Daemon) ContainerStats(name string, stream bool, out io.Writer) er
if err != nil {
return err
}
var preCpuStats types.CpuStats
getStat := func(v interface{}) *types.Stats {
var pre_cpu_stats types.CpuStats
for first_v := range updates {
first_update := first_v.(*execdriver.ResourceStats)
first_stats := convertToAPITypes(first_update.Stats)
pre_cpu_stats = first_stats.CpuStats
pre_cpu_stats.SystemUsage = first_update.SystemUsage
break
}
enc := json.NewEncoder(out)
for v := range updates {
update := v.(*execdriver.ResourceStats)
ss := convertToAPITypes(update.Stats)
ss.PreCpuStats = preCpuStats
ss.PreCpuStats = pre_cpu_stats
ss.MemoryStats.Limit = uint64(update.MemoryLimit)
ss.Read = update.Read
ss.CpuStats.SystemUsage = update.SystemUsage
preCpuStats = ss.CpuStats
return ss
}
enc := json.NewEncoder(out)
if !stream {
// prime the cpu stats so they aren't 0 in the final output
s := getStat(<-updates)
// now pull stats again with the cpu stats primed
s = getStat(<-updates)
err := enc.Encode(s)
daemon.UnsubscribeToContainerStats(name, updates)
return err
}
for v := range updates {
s := getStat(v)
if err := enc.Encode(s); err != nil {
pre_cpu_stats = ss.CpuStats
if err := enc.Encode(ss); err != nil {
// TODO: handle the specific broken pipe
daemon.UnsubscribeToContainerStats(name, updates)
return err
}
if !stream {
break
}
}
return nil
}
+67 -79
View File
@@ -1,6 +1,7 @@
package daemon
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -11,7 +12,6 @@ import (
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/local"
"github.com/docker/libcontainer/label"
)
@@ -53,13 +53,6 @@ func (m *mountPoint) Path() string {
return m.Source
}
// BackwardsCompatible decides whether this mount point can be
// used in old versions of Docker or not.
// Only bind mounts and local volumes can be used in old versions of Docker.
func (m *mountPoint) BackwardsCompatible() bool {
return len(m.Source) > 0 || m.Driver == volume.DefaultDriverName
}
func parseBindMount(spec string, mountLabel string, config *runconfig.Config) (*mountPoint, error) {
bind := &mountPoint{
RW: true,
@@ -239,20 +232,8 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
mountPoints[bind.Destination] = bind
}
// Keep backwards compatible structures
bcVolumes := map[string]string{}
bcVolumesRW := map[string]bool{}
for _, m := range mountPoints {
if m.BackwardsCompatible() {
bcVolumes[m.Destination] = m.Path()
bcVolumesRW[m.Destination] = m.RW
}
}
container.Lock()
container.MountPoints = mountPoints
container.Volumes = bcVolumes
container.VolumesRW = bcVolumesRW
container.Unlock()
return nil
@@ -261,74 +242,81 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
// verifyVolumesInfo ports volumes configured for the containers pre docker 1.7.
// It reads the container configuration and creates valid mount points for the old volumes.
func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
// Inspect old structures only when we're upgrading from old versions
// to versions >= 1.7 and the MountPoints has not been populated with volumes data.
if len(container.MountPoints) == 0 && len(container.Volumes) > 0 {
for destination, hostPath := range container.Volumes {
vfsPath := filepath.Join(daemon.root, "vfs", "dir")
rw := container.VolumesRW != nil && container.VolumesRW[destination]
if strings.HasPrefix(hostPath, vfsPath) {
id := filepath.Base(hostPath)
if err := migrateVolume(id, hostPath); err != nil {
return err
}
container.addLocalMountPoint(id, destination, rw)
} else { // Bind mount
id, source, err := parseVolumeSource(hostPath)
// We should not find an error here coming
// from the old configuration, but who knows.
if err != nil {
return err
}
container.addBindMountPoint(id, source, destination, rw)
}
}
} else if len(container.MountPoints) > 0 {
// Volumes created with a Docker version >= 1.7. We verify integrity in case of data created
// with Docker 1.7 RC versions that put the information in
// DOCKER_ROOT/volumes/VOLUME_ID rather than DOCKER_ROOT/volumes/VOLUME_ID/_container_data.
l, err := getVolumeDriver(volume.DefaultDriverName)
if err != nil {
return err
jsonPath, err := container.jsonPath()
if err != nil {
return err
}
f, err := os.Open(jsonPath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
for _, m := range container.MountPoints {
if m.Driver != volume.DefaultDriverName {
continue
}
dataPath := l.(*local.Root).DataPath(m.Name)
volumePath := filepath.Dir(dataPath)
type oldContVolCfg struct {
Volumes map[string]string
VolumesRW map[string]bool
}
d, err := ioutil.ReadDir(volumePath)
if err != nil {
// If the volume directory doesn't exist yet it will be recreated,
// so we only return the error when there is a different issue.
if !os.IsNotExist(err) {
return err
}
// Do not check when the volume directory does not exist.
continue
}
if validVolumeLayout(d) {
continue
}
vols := oldContVolCfg{
Volumes: make(map[string]string),
VolumesRW: make(map[string]bool),
}
if err := json.NewDecoder(f).Decode(&vols); err != nil {
return err
}
if err := os.Mkdir(dataPath, 0755); err != nil {
for destination, hostPath := range vols.Volumes {
vfsPath := filepath.Join(daemon.root, "vfs", "dir")
rw := vols.VolumesRW != nil && vols.VolumesRW[destination]
if strings.HasPrefix(hostPath, vfsPath) {
id := filepath.Base(hostPath)
if err := daemon.migrateVolume(id, hostPath); err != nil {
return err
}
// Move data inside the data directory
for _, f := range d {
oldp := filepath.Join(volumePath, f.Name())
newp := filepath.Join(dataPath, f.Name())
if err := os.Rename(oldp, newp); err != nil {
logrus.Errorf("Unable to move %s to %s\n", oldp, newp)
}
container.addLocalMountPoint(id, destination, rw)
} else { // Bind mount
id, source, err := parseVolumeSource(hostPath)
// We should not find an error here coming
// from the old configuration, but who knows.
if err != nil {
return err
}
container.addBindMountPoint(id, source, destination, rw)
}
}
return container.ToDisk()
return container.ToDisk()
}
// migrateVolume moves the contents of a volume created pre Docker 1.7
// to the location expected by the local driver. Steps:
// 1. Save old directory that includes old volume's config json file.
// 2. Move virtual directory with content to where the local driver expects it to be.
// 3. Remove the backup of the old volume config.
func (daemon *Daemon) migrateVolume(id, vfs string) error {
volumeInfo := filepath.Join(daemon.root, defaultVolumesPathName, id)
backup := filepath.Join(daemon.root, defaultVolumesPathName, id+".back")
var err error
if err = os.Rename(volumeInfo, backup); err != nil {
return err
}
defer func() {
// Put old configuration back in place in case one of the next steps fails.
if err != nil {
os.Rename(backup, volumeInfo)
}
}()
if err = os.Rename(vfs, volumeInfo); err != nil {
return err
}
if err = os.RemoveAll(backup); err != nil {
logrus.Errorf("Unable to remove volume info backup directory %s: %v", backup, err)
}
return nil
-49
View File
@@ -10,8 +10,6 @@ import (
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/local"
)
// copyOwnership copies the permissions and uid:gid of the source file
@@ -70,50 +68,3 @@ func (m mounts) Swap(i, j int) {
func (m mounts) parts(i int) int {
return len(strings.Split(filepath.Clean(m[i].Destination), string(os.PathSeparator)))
}
// migrateVolume links the contents of a volume created pre Docker 1.7
// into the location expected by the local driver.
// It creates a symlink from DOCKER_ROOT/vfs/dir/VOLUME_ID to DOCKER_ROOT/volumes/VOLUME_ID/_container_data.
// It preserves the volume json configuration generated pre Docker 1.7 to be able to
// downgrade from Docker 1.7 to Docker 1.6 without losing volume compatibility.
func migrateVolume(id, vfs string) error {
l, err := getVolumeDriver(volume.DefaultDriverName)
if err != nil {
return err
}
newDataPath := l.(*local.Root).DataPath(id)
fi, err := os.Stat(newDataPath)
if err != nil && !os.IsNotExist(err) {
return err
}
if fi != nil && fi.IsDir() {
return nil
}
return os.Symlink(vfs, newDataPath)
}
// validVolumeLayout checks whether the volume directory layout
// is valid to work with Docker post 1.7 or not.
func validVolumeLayout(files []os.FileInfo) bool {
if len(files) == 1 && files[0].Name() == local.VolumeDataPathName && files[0].IsDir() {
return true
}
if len(files) != 2 {
return false
}
for _, f := range files {
if f.Name() == "config.json" ||
(f.Name() == local.VolumeDataPathName && f.Mode()&os.ModeSymlink == os.ModeSymlink) {
// Old volume configuration, we ignore it
continue
}
return false
}
return true
}
+1 -13
View File
@@ -2,11 +2,7 @@
package daemon
import (
"os"
"github.com/docker/docker/daemon/execdriver"
)
import "github.com/docker/docker/daemon/execdriver"
// Not supported on Windows
func copyOwnership(source, destination string) error {
@@ -16,11 +12,3 @@ func copyOwnership(source, destination string) error {
func (container *Container) setupMounts() ([]execdriver.Mount, error) {
return nil, nil
}
func migrateVolume(id, vfs string) error {
return nil
}
func validVolumeLayout(files []os.FileInfo) bool {
return true
}
+3
View File
@@ -1,2 +1,5 @@
# generated by man/man/md2man-all.sh
man1/
man5/
# avoid commiting the awsconfig file used for releases
awsconfig
+159 -20
View File
@@ -1,24 +1,163 @@
FROM docs/base:hugo
MAINTAINER Mary Anthony <mary@docker.com> (@moxiegirl)
#
# See the top level Makefile in https://github.com/docker/docker for usage.
#
FROM docs/base:latest
MAINTAINER Sven Dowideit <SvenDowideit@docker.com> (@SvenDowideit)
# To get the git info for this repo
# This section ensures we pull the correct version of each
# sub project
ENV COMPOSE_BRANCH release
ENV SWARM_BRANCH v0.2.0
ENV MACHINE_BRANCH docs
ENV DISTRIB_BRANCH docs
ENV KITEMATIC_BRANCH master
# TODO: need the full repo source to get the git version info
COPY . /src
COPY . /docs/content/engine/
# Reset the /docs dir so we can replace the theme meta with the new repo's git info
# RUN git reset --hard
# Sed to process GitHub Markdown
# 1-2 Remove comment code from metadata block
# 3 Remove .md extension from link text
# 4 Change ](/ to ](/project/ in links
# 5 Change ](word) to ](/project/word)
# 6 Change ](../../ to ](/project/
# 7 Change ](../ to ](/project/word)
#
#
RUN find /docs/content/engine -type f -name "*.md" -exec sed -i.old \
-e '/^<!.*metadata]>/g' \
-e '/^<!.*end-metadata.*>/g' \
-e 's/\([(]\)\(.*\)\(\.md\)/\1\2/g' \
-e 's/\(\]\)\([(]\)\(\/\)/\1\2\/engine\//g' \
-e 's/\(\][(]\)\([A-z]*[)]\)/\]\(\/engine\/\2/g' \
-e 's/\(\][(]\)\(\.\.\/\)/\1\/engine\//g' {} \;
# Then copy the desired docs into the /docs/sources/ dir
COPY ./sources/ /docs/sources
COPY ./VERSION VERSION
# adding the image spec will require Docker 1.5 and `docker build -f docs/Dockerfile .`
#COPY ./image/spec/v1.md /docs/sources/reference/image-spec-v1.md
# TODO: don't do this - look at merging the yml file in build.sh
COPY ./mkdocs.yml ./s3_website.json ./release.sh ./
#######################
# Docker Distribution
########################
#ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/mkdocs.yml /docs/mkdocs-distribution.yml
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/images/notifications.png \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/images/registry.png \
/docs/sources/registry/images/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/index.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/deploying.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/configuration.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storagedrivers.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/notifications.md \
/docs/sources/registry/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/spec/api.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/spec/json.md \
/docs/sources/registry/spec/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/s3.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/azure.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/filesystem.md \
https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/storage-drivers/inmemory.md \
/docs/sources/registry/storage-drivers/
ADD https://raw.githubusercontent.com/docker/distribution/${DISTRIB_BRANCH}/docs/spec/auth/token.md /docs/sources/registry/spec/auth/token.md
RUN sed -i.old '1s;^;no_version_dropdown: true;' \
/docs/sources/registry/*.md \
/docs/sources/registry/spec/*.md \
/docs/sources/registry/spec/auth/*.md \
/docs/sources/registry/storage-drivers/*.md
RUN sed -i.old -e '/^<!--GITHUB/g' -e '/^IGNORES-->/g'\
/docs/sources/registry/*.md \
/docs/sources/registry/spec/*.md \
/docs/sources/registry/spec/auth/*.md \
/docs/sources/registry/storage-drivers/*.md
#######################
# Docker Swarm
#######################
#ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/docs/mkdocs.yml /docs/mkdocs-swarm.yml
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/docs/index.md /docs/sources/swarm/index.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/discovery/README.md /docs/sources/swarm/discovery.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/api/README.md /docs/sources/swarm/API.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/scheduler/filter/README.md /docs/sources/swarm/scheduler/filter.md
ADD https://raw.githubusercontent.com/docker/swarm/${SWARM_BRANCH}/scheduler/strategy/README.md /docs/sources/swarm/scheduler/strategy.md
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/swarm/*.md /docs/sources/swarm/scheduler/*.md
#######################
# Docker Machine
#######################
#ADD https://raw.githubusercontent.com/docker/machine/${MACHINE_BRANCH}/docs/mkdocs.yml /docs/mkdocs-machine.yml
ADD https://raw.githubusercontent.com/docker/machine/${MACHINE_BRANCH}/docs/index.md /docs/sources/machine/index.md
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/machine/index.md
#######################
# Docker Compose
#######################
#ADD https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/mkdocs.yml /docs/mkdocs-compose.yml
ADD https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/index.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/install.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/cli.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/yml.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/env.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/completion.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/django.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/rails.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/wordpress.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/extends.md \
https://raw.githubusercontent.com/docker/compose/${COMPOSE_BRANCH}/docs/production.md \
/docs/sources/compose/
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/compose/*.md
#######################
# Kitematic
#######################
ADD https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/faq.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/index.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/known-issues.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/minecraft-server.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/nginx-web-server.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/rethinkdb-dev-database.md \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/userguide.md \
/docs/sources/kitematic/
RUN sed -i.old '1s;^;no_version_dropdown: true;' /docs/sources/kitematic/*.md
ADD https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/browse-images.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/change-folder.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/cli-access-button.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/cli-redis-container.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/cli-terminal.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/containers.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/installing.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-add-server.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-create.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-data-volume.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-login.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-map.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-port.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-restart.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/minecraft-server-address.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-2048-files.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-2048.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-create.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-data-folder.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-data-volume.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-hello-world.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-preview.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/nginx-serving-2048.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethink-container.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethink-create.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethink-ports.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/rethinkdb-preview.png \
https://raw.githubusercontent.com/kitematic/kitematic/${KITEMATIC_BRANCH}/docs/assets/volumes-dir.png \
/docs/sources/kitematic/assets/
# Then build everything together, ready for mkdocs
RUN /docs/build.sh
-55
View File
@@ -1,55 +0,0 @@
.PHONY: all binary build cross default docs docs-build docs-shell shell test test-unit test-integration test-integration-cli test-docker-py validate
# env vars passed through directly to Docker's build scripts
# to allow things like `make DOCKER_CLIENTONLY=1 binary` easily
# `docs/sources/contributing/devenvironment.md ` and `project/PACKAGERS.md` have some limited documentation of some of these
DOCKER_ENVS := \
-e BUILDFLAGS \
-e DOCKER_CLIENTONLY \
-e DOCKER_EXECDRIVER \
-e DOCKER_GRAPHDRIVER \
-e TESTDIRS \
-e TESTFLAGS \
-e TIMEOUT
# note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds
# to allow `make DOCSDIR=docs docs-shell` (to create a bind mount in docs)
DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR)/$(DOCSDIR):/$(DOCSDIR))
# to allow `make DOCSPORT=9000 docs`
DOCSPORT := 8000
# Get the IP ADDRESS
DOCKER_IP=$(shell python -c "import urlparse ; print urlparse.urlparse('$(DOCKER_HOST)').hostname or ''")
HUGO_BASE_URL=$(shell test -z "$(DOCKER_IP)" && echo localhost || echo "$(DOCKER_IP)")
HUGO_BIND_IP=0.0.0.0
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
DOCKER_IMAGE := docker$(if $(GIT_BRANCH),:$(GIT_BRANCH))
DOCKER_DOCS_IMAGE := docs-base$(if $(GIT_BRANCH),:$(GIT_BRANCH))
DOCKER_RUN_DOCS := docker run --rm -it $(DOCS_MOUNT) -e AWS_S3_BUCKET -e NOCACHE
# for some docs workarounds (see below in "docs-build" target)
GITCOMMIT := $(shell git rev-parse --short HEAD 2>/dev/null)
default: docs
docs: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP)
docs-draft: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --buildDrafts="true" --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP)
docs-shell: docs-build
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" bash
docs-build:
# ( git remote | grep -v upstream ) || git diff --name-status upstream/release..upstream/docs ./ > ./changed-files
# echo "$(GIT_BRANCH)" > GIT_BRANCH
# echo "$(AWS_S3_BUCKET)" > AWS_S3_BUCKET
# echo "$(GITCOMMIT)" > GITCOMMIT
docker build -t "$(DOCKER_DOCS_IMAGE)" .
+17 -10
View File
@@ -1,9 +1,3 @@
<!--[metadata]>
+++
draft = true
+++
<![end-metadata]-->
# Docker Documentation
The source for Docker documentation is in this directory under `sources/`. Our
@@ -286,11 +280,24 @@ aws cloudfront create-invalidation --profile docs.docker.com --distribution-id
aws cloudfront create-invalidation --profile docs.docker.com --distribution-id $DISTRIBUTION_ID --invalidation-batch '{"Paths":{"Quantity":1, "Items":["/v1.1/reference/api/docker_io_oauth_api/"]},"CallerReference":"6Mar2015sventest1"}'
```
### Generate the man pages
### Generate the man pages for Mac OSX
For information on generating man pages (short for manual page), see [the man
page directory](https://github.com/docker/docker/tree/master/docker) in this
project.
When using Docker on Mac OSX the man pages will be missing by default. You can manually generate them by following these steps:
1. Checkout the docker source. You must clone into your `/Users` directory because Boot2Docker can only share this path
with the docker containers.
$ git clone https://github.com/docker/docker.git
2. Build the docker image.
$ cd docker/docs/man
$ docker build -t docker/md2man .
3. Build the man pages.
$ docker run -v /Users/<path-to-git-dir>/docker/docs/man:/docs:rw -w /docs -i docker/md2man /docs/md2man-all.sh
4. Copy the generated man pages to `/usr/share/man`
$ cp -R man* /usr/share/man/
+2 -2
View File
@@ -1,7 +1,7 @@
FROM golang:1.4
FROM golang:1.3
RUN mkdir -p /go/src/github.com/cpuguy83
RUN mkdir -p /go/src/github.com/cpuguy83 \
&& git clone -b v1.0.1 https://github.com/cpuguy83/go-md2man.git /go/src/github.com/cpuguy83/go-md2man \
&& git clone -b v1 https://github.com/cpuguy83/go-md2man.git /go/src/github.com/cpuguy83/go-md2man \
&& cd /go/src/github.com/cpuguy83/go-md2man \
&& go get -v ./...
CMD ["/go/bin/go-md2man", "--help"]
@@ -196,7 +196,7 @@ A Dockerfile is similar to a Makefile.
ADD <src> <dest>
# Required for paths with whitespace
ADD ["<src>",... "<dest>"]
ADD ["<src>", "<dest>"]
```
The **ADD** instruction copies new files, directories
@@ -215,7 +215,7 @@ A Dockerfile is similar to a Makefile.
COPY <src> <dest>
# Required for paths with whitespace
COPY ["<src>",... "<dest>"]
COPY ["<src>", "<dest>"]
```
The **COPY** instruction copies new files from `<src>` and
@@ -63,12 +63,7 @@ Again the output container IDs have been shortened for the purposes of this docu
2015-01-28T20:25:45.000000000-08:00 c21f6c22ba27: (from whenry/testimage:latest) die
2015-01-28T20:25:46.000000000-08:00 c21f6c22ba27: (from whenry/testimage:latest) stop
If you do not provide the --since option, the command returns only new and/or
live events.
# HISTORY
April 2014, Originally compiled by William Henry (whenry at redhat dot com)
based on docker.com source material and internal work.
June 2014, updated by Sven Dowideit <SvenDowideit@home.org.au>
June 2015, updated by Brian Goff <cpuguy83@gmail.com>
+6 -1
View File
@@ -1,5 +1,5 @@
site_name: Docker Documentation
#site_url: https://docs.docker.com/
#site_url: http://docs.docker.com/
site_url: /
site_description: Documentation for fast and lightweight Docker container based virtualization framework.
site_favicon: img/favicon.png
@@ -27,6 +27,11 @@ pages:
- ['index.md', 'About', 'Docker']
- ['introduction/understanding-docker.md', 'About', 'Understanding Docker']
- ['release-notes.md', 'About', 'Release notes']
# Experimental
- ['experimental/experimental.md', 'About', 'Experimental Features']
- ['experimental/plugin_api.md', '**HIDDEN**']
- ['experimental/plugins_volume.md', '**HIDDEN**']
- ['experimental/plugins.md', '**HIDDEN**']
- ['reference/glossary.md', 'About', 'Glossary']
- ['introduction/index.md', '**HIDDEN**']
+176
View File
@@ -0,0 +1,176 @@
#!/bin/bash
set -e
set -o pipefail
usage() {
cat >&2 <<'EOF'
To publish the Docker documentation you need to set your access_key and secret_key in the docs/awsconfig file
(with the keys in a [profile $AWS_S3_BUCKET] section - so you can have more than one set of keys in your file)
and set the AWS_S3_BUCKET env var to the name of your bucket.
If you're publishing the current release's documentation, also set `BUILD_ROOT=yes`
make AWS_S3_BUCKET=docs-stage.docker.com docs-release
will then push the documentation site to your s3 bucket.
Note: you can add `OPTIONS=--dryrun` to see what will be done without sending to the server
You can also add NOCACHE=1 to publish without a cache, which is what we do for the master docs.
EOF
exit 1
}
create_robots_txt() {
if [ "$AWS_S3_BUCKET" == "docs.docker.com" ]; then
cat > ./sources/robots.txt <<-'EOF'
User-agent: *
Allow: /
EOF
else
cat > ./sources/robots.txt <<-'EOF'
User-agent: *
Disallow: /
EOF
fi
}
setup_s3() {
# Try creating the bucket. Ignore errors (it might already exist).
echo "create $BUCKET if it does not exist"
aws s3 mb --profile $BUCKET s3://$BUCKET 2>/dev/null || true
# Check access to the bucket.
echo "test $BUCKET exists"
aws s3 --profile $BUCKET ls s3://$BUCKET
# Make the bucket accessible through website endpoints.
echo "make $BUCKET accessible as a website"
#aws s3 website s3://$BUCKET --index-document index.html --error-document jsearch/index.html
local s3conf=$(cat s3_website.json | envsubst)
aws s3api --profile $BUCKET put-bucket-website --bucket $BUCKET --website-configuration "$s3conf"
}
build_current_documentation() {
mkdocs build
cd site/
gzip -9k -f search_content.json
cd ..
}
upload_current_documentation() {
src=site/
dst=s3://$BUCKET$1
cache=max-age=3600
if [ "$NOCACHE" ]; then
cache=no-cache
fi
printf "\nUploading $src to $dst\n"
# a really complicated way to send only the files we want
# if there are too many in any one set, aws s3 sync seems to fall over with 2 files to go
# versions.html_fragment
include="--recursive --include \"*.$i\" "
run="aws s3 cp $src $dst $OPTIONS --profile $BUCKET --cache-control $cache --acl public-read $include"
printf "\n=====\n$run\n=====\n"
$run
# Make sure the search_content.json.gz file has the right content-encoding
aws s3 cp --profile $BUCKET --cache-control $cache --content-encoding="gzip" --acl public-read "site/search_content.json.gz" "$dst"
}
invalidate_cache() {
if [[ -z "$DISTRIBUTION_ID" ]]; then
echo "Skipping Cloudfront cache invalidation"
return
fi
dst=$1
aws configure set preview.cloudfront true
# Get all the files
# not .md~ files
# replace spaces w %20 so urlencoded
files=( $(find site/ -not -name "*.md*" -type f | sed 's/site//g' | sed 's/ /%20/g') )
len=${#files[@]}
last_file=${files[$((len-1))]}
echo "aws cloudfront create-invalidation --profile $AWS_S3_BUCKET --distribution-id $DISTRIBUTION_ID --invalidation-batch '" > batchfile
echo "{\"Paths\":{\"Quantity\":$len," >> batchfile
echo "\"Items\": [" >> batchfile
for file in "${files[@]}" ; do
if [[ $file == $last_file ]]; then
comma=""
else
comma=","
fi
echo "\"$dst$file\"$comma" >> batchfile
done
echo "]}, \"CallerReference\":\"$(date)\"}'" >> batchfile
sh batchfile
}
main() {
[ "$AWS_S3_BUCKET" ] || usage
# Make sure there is an awsconfig file
export AWS_CONFIG_FILE=$(pwd)/awsconfig
[ -f "$AWS_CONFIG_FILE" ] || usage
# Get the version
VERSION=$(cat VERSION)
# Disallow pushing dev docs to master
if [ "$AWS_S3_BUCKET" == "docs.docker.com" ] && [ "${VERSION%-dev}" != "$VERSION" ]; then
echo "Please do not push '-dev' documentation to docs.docker.com ($VERSION)"
exit 1
fi
# Clean version - 1.0.2-dev -> 1.0
export MAJOR_MINOR="v${VERSION%.*}"
export BUCKET=$AWS_S3_BUCKET
export AWS_DEFAULT_PROFILE=$BUCKET
# debug variables
echo "bucket: $BUCKET, full version: $VERSION, major-minor: $MAJOR_MINOR"
echo "cfg file: $AWS_CONFIG_FILE ; profile: $AWS_DEFAULT_PROFILE"
# create the robots.txt
create_robots_txt
if [ "$OPTIONS" != "--dryrun" ]; then
setup_s3
fi
# Default to only building the version specific docs
# so we don't clober the latest by accident with old versions
if [ "$BUILD_ROOT" == "yes" ]; then
echo "Building root documentation"
build_current_documentation
echo "Uploading root documentation"
upload_current_documentation
[ "$NOCACHE" ] || invalidate_cache
fi
#build again with /v1.0/ prefix
sed -i "s/^site_url:.*/site_url: \/$MAJOR_MINOR\//" mkdocs.yml
echo "Building the /$MAJOR_MINOR/ documentation"
build_current_documentation
echo "Uploading the documentation"
upload_current_documentation "/$MAJOR_MINOR/"
# Invalidating cache
[ "$NOCACHE" ] || invalidate_cache "/$MAJOR_MINOR"
}
main
+50
View File
@@ -0,0 +1,50 @@
{
"ErrorDocument": {
"Key": "jsearch/index.html"
},
"IndexDocument": {
"Suffix": "index.html"
},
"RoutingRules": [
{ "Condition": { "KeyPrefixEquals": "en/latest/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "" } },
{ "Condition": { "KeyPrefixEquals": "en/master/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "" } },
{ "Condition": { "KeyPrefixEquals": "en/v0.6.3/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "" } },
{ "Condition": { "KeyPrefixEquals": "jsearch/index.html" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "jsearch/" } },
{ "Condition": { "KeyPrefixEquals": "index/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-io/" } },
{ "Condition": { "KeyPrefixEquals": "reference/api/index_api/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "reference/api/docker-io_api/" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/groups.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/groups.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/hub.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/hub.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/invite.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/invite.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/orgs.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/orgs.png" } },
{ "Condition": { "KeyPrefixEquals": "docker-hub/repos.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/hub-images/repos.png" } },
{ "Condition": { "KeyPrefixEquals": "installation/images/linux_docker_host.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/images/linux_docker_host.svg" } },
{ "Condition": { "KeyPrefixEquals": "installation/images/osx_docker_host.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/images/osx_docker_host.svg" } },
{ "Condition": { "KeyPrefixEquals": "installation/images/win_docker_host.png" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/images/win_docker_host.svg" } },
{ "Condition": { "KeyPrefixEquals": "examples/hello_world/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerizing/" } },
{ "Condition": { "KeyPrefixEquals": "examples/python_web_app/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerizing/" } },
{ "Condition": { "KeyPrefixEquals": "use/working_with_volumes/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockervolumes/" } },
{ "Condition": { "KeyPrefixEquals": "use/working_with_links_names/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerlinks/" } },
{ "Condition": { "KeyPrefixEquals": "use/workingwithrepository/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerrepos/" } },
{ "Condition": { "KeyPrefixEquals": "use/port_redirection" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "userguide/dockerlinks/" } },
{ "Condition": { "KeyPrefixEquals": "use/networking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/networking/" } },
{ "Condition": { "KeyPrefixEquals": "use/puppet/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/puppet/" } },
{ "Condition": { "KeyPrefixEquals": "use/ambassador_pattern_linking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/ambassador_pattern_linking/" } },
{ "Condition": { "KeyPrefixEquals": "use/basics/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/basics/" } },
{ "Condition": { "KeyPrefixEquals": "use/chef/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/chef/" } },
{ "Condition": { "KeyPrefixEquals": "use/host_integration/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/host_integration/" } },
{ "Condition": { "KeyPrefixEquals": "docker-io/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "docker-hub/" } },
{ "Condition": { "KeyPrefixEquals": "examples/cfengine_process_management/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/cfengine_process_management/" } },
{ "Condition": { "KeyPrefixEquals": "examples/https/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/https/" } },
{ "Condition": { "KeyPrefixEquals": "examples/ambassador_pattern_linking/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/ambassador_pattern_linking/" } },
{ "Condition": { "KeyPrefixEquals": "examples/using_supervisord/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "articles/using_supervisord/" } },
{ "Condition": { "KeyPrefixEquals": "reference/api/registry_index_spec/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "reference/api/hub_registry_spec/" } },
{ "Condition": { "KeyPrefixEquals": "use/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "examples/" } },
{ "Condition": { "KeyPrefixEquals": "installation/openSUSE/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "installation/SUSE/" } },
{ "Condition": { "KeyPrefixEquals": "contributing/contributing/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "project/who-written-for/" } },
{ "Condition": { "KeyPrefixEquals": "contributing/devenvironment/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "project/set-up-prereqs/" } },
{ "Condition": { "KeyPrefixEquals": "contributing/docs_style-guide/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "project/doc-style/" } },
{ "Condition": { "KeyPrefixEquals": "registry/overview/" }, "Redirect": { "HostName": "$BUCKET", "ReplaceKeyPrefixWith": "registry/" } }
]
}

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 175 KiB

@@ -1,13 +1,6 @@
<!--[metadata]>
+++
title = "Link via an ambassador container"
description = "Using the Ambassador pattern to abstract (network) services"
keywords = ["Examples, Usage, links, docker, documentation, examples, names, name, container naming"]
[menu.main]
parent = "smn_administrate"
weight = 6
+++
<![end-metadata]-->
page_title: Link via an ambassador container
page_description: Using the Ambassador pattern to abstract (network) services
page_keywords: Examples, Usage, links, docker, documentation, examples, names, name, container naming
# Link via an ambassador container

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

@@ -1,12 +1,6 @@
<!--[metadata]>
+++
title = "Resizing a Boot2Docker volume "
description = "Resizing a Boot2Docker volume in VirtualBox with GParted"
keywords = ["boot2docker, volume, virtualbox"]
[menu.main]
parent = "smn_win_osx"
+++
<![end-metadata]-->
page_title: Resizing a Boot2Docker volume
page_description: Resizing a Boot2Docker volume in VirtualBox with GParted
page_keywords: boot2docker, volume, virtualbox
# Getting “no space left on device” errors with Boot2Docker?

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