Merge branch 'master' into add-libcontainer

Conflicts:
	runtime.go

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-02-24 20:35:12 -08:00
commit 27a43692c2
35 changed files with 343 additions and 674 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ bundles/
.git/
vendor/pkg/
pyenv
Vagrantfile

View File

@ -6,4 +6,3 @@ Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
api.go: Victor Vieux <victor@dotcloud.com> (@vieux)
Dockerfile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
Makefile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
Vagrantfile: Cristian Staretu <cristian.staretu@gmail.com> (@unclejack)

206
Vagrantfile vendored
View File

@ -1,206 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
BOX_NAME = ENV['BOX_NAME'] || "ubuntu"
BOX_URI = ENV['BOX_URI'] || "http://files.vagrantup.com/precise64.box"
VF_BOX_URI = ENV['BOX_URI'] || "http://files.vagrantup.com/precise64_vmware_fusion.box"
AWS_BOX_URI = ENV['BOX_URI'] || "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
AWS_REGION = ENV['AWS_REGION'] || "us-east-1"
AWS_AMI = ENV['AWS_AMI'] || "ami-69f5a900"
AWS_INSTANCE_TYPE = ENV['AWS_INSTANCE_TYPE'] || 't1.micro'
SSH_PRIVKEY_PATH = ENV['SSH_PRIVKEY_PATH']
PRIVATE_NETWORK = ENV['PRIVATE_NETWORK']
# Boolean that forwards the Docker dynamic ports 49000-49900
# See http://docs.docker.io/en/latest/use/port_redirection/ for more
# $ FORWARD_DOCKER_PORTS=1 vagrant [up|reload]
FORWARD_DOCKER_PORTS = ENV['FORWARD_DOCKER_PORTS']
VAGRANT_RAM = ENV['VAGRANT_RAM'] || 512
VAGRANT_CORES = ENV['VAGRANT_CORES'] || 1
# You may also provide a comma-separated list of ports
# for Vagrant to forward. For example:
# $ FORWARD_PORTS=8080,27017 vagrant [up|reload]
FORWARD_PORTS = ENV['FORWARD_PORTS']
# A script to upgrade from the 12.04 kernel to the raring backport kernel (3.8)
# and install docker.
$script = <<SCRIPT
# The username to add to the docker group will be passed as the first argument
# to the script. If nothing is passed, default to "vagrant".
user="$1"
if [ -z "$user" ]; then
user=vagrant
fi
# Enable memory cgroup and swap accounting
sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"/g' /etc/default/grub
update-grub
# Adding an apt gpg key is idempotent.
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
# Creating the docker.list file is idempotent, but it may overwrite desired
# settings if it already exists. This could be solved with md5sum but it
# doesn't seem worth it.
echo 'deb http://get.docker.io/ubuntu docker main' > \
/etc/apt/sources.list.d/docker.list
# Update remote package metadata. 'apt-get update' is idempotent.
apt-get update -q
# Install docker. 'apt-get install' is idempotent.
apt-get install -q -y lxc-docker
usermod -a -G docker "$user"
tmp=`mktemp -q` && {
# Only install the backport kernel, don't bother upgrading if the backport is
# already installed. We want parse the output of apt so we need to save it
# with 'tee'. NOTE: The installation of the kernel will trigger dkms to
# install vboxguest if needed.
apt-get install -q -y --no-upgrade linux-image-generic-lts-raring | \
tee "$tmp"
# Parse the number of installed packages from the output
NUM_INST=`awk '$2 == "upgraded," && $4 == "newly" { print $3 }' "$tmp"`
rm "$tmp"
}
# If the number of installed packages is greater than 0, we want to reboot (the
# backport kernel was installed but is not running).
if [ "$NUM_INST" -gt 0 ];
then
echo "Rebooting down to activate new kernel."
echo "/vagrant will not be mounted. Use 'vagrant halt' followed by"
echo "'vagrant up' to ensure /vagrant is mounted."
shutdown -r now
fi
SCRIPT
# We need to install the virtualbox guest additions *before* we do the normal
# docker installation. As such this script is prepended to the common docker
# install script above. This allows the install of the backport kernel to
# trigger dkms to build the virtualbox guest module install.
$vbox_script = <<VBOX_SCRIPT + $script
# Install the VirtualBox guest additions if they aren't already installed.
if [ ! -d /opt/VBoxGuestAdditions-4.3.6/ ]; then
# Update remote package metadata. 'apt-get update' is idempotent.
apt-get update -q
# Kernel Headers and dkms are required to build the vbox guest kernel
# modules.
apt-get install -q -y linux-headers-generic-lts-raring dkms
echo 'Downloading VBox Guest Additions...'
wget -cq http://dlc.sun.com.edgesuite.net/virtualbox/4.3.6/VBoxGuestAdditions_4.3.6.iso
echo "95648fcdb5d028e64145a2fe2f2f28c946d219da366389295a61fed296ca79f0 VBoxGuestAdditions_4.3.6.iso" | sha256sum --check || exit 1
mount -o loop,ro /home/vagrant/VBoxGuestAdditions_4.3.6.iso /mnt
/mnt/VBoxLinuxAdditions.run --nox11
umount /mnt
fi
VBOX_SCRIPT
Vagrant::Config.run do |config|
# Setup virtual machine box. This VM configuration code is always executed.
config.vm.box = BOX_NAME
config.vm.box_url = BOX_URI
# Use the specified private key path if it is specified and not empty.
if SSH_PRIVKEY_PATH
config.ssh.private_key_path = SSH_PRIVKEY_PATH
end
config.ssh.forward_agent = true
end
# Providers were added on Vagrant >= 1.1.0
#
# NOTE: The vagrant "vm.provision" appends its arguments to a list and executes
# them in order. If you invoke "vm.provision :shell, :inline => $script"
# twice then vagrant will run the script two times. Unfortunately when you use
# providers and the override argument to set up provisioners (like the vbox
# guest extensions) they 1) don't replace the other provisioners (they append
# to the end of the list) and 2) you can't control the order the provisioners
# are executed (you can only append to the list). If you want the virtualbox
# only script to run before the other script, you have to jump through a lot of
# hoops.
#
# Here is my only repeatable solution: make one script that is common ($script)
# and another script that is the virtual box guest *prepended* to the common
# script. Only ever use "vm.provision" *one time* per provider. That means
# every single provider has an override, and every single one configures
# "vm.provision". Much saddness, but such is life.
Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
config.vm.provider :aws do |aws, override|
username = "ubuntu"
override.vm.box_url = AWS_BOX_URI
override.vm.provision :shell, :inline => $script, :args => username
aws.access_key_id = ENV["AWS_ACCESS_KEY"]
aws.secret_access_key = ENV["AWS_SECRET_KEY"]
aws.keypair_name = ENV["AWS_KEYPAIR_NAME"]
override.ssh.username = username
aws.region = AWS_REGION
aws.ami = AWS_AMI
aws.instance_type = AWS_INSTANCE_TYPE
end
config.vm.provider :rackspace do |rs, override|
override.vm.provision :shell, :inline => $script
rs.username = ENV["RS_USERNAME"]
rs.api_key = ENV["RS_API_KEY"]
rs.public_key_path = ENV["RS_PUBLIC_KEY"]
rs.flavor = /512MB/
rs.image = /Ubuntu/
end
config.vm.provider :vmware_fusion do |f, override|
override.vm.box_url = VF_BOX_URI
override.vm.synced_folder ".", "/vagrant", disabled: true
override.vm.provision :shell, :inline => $script
f.vmx["displayName"] = "docker"
end
config.vm.provider :virtualbox do |vb, override|
override.vm.provision :shell, :inline => $vbox_script
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
vb.customize ["modifyvm", :id, "--memory", VAGRANT_RAM]
vb.customize ["modifyvm", :id, "--cpus", VAGRANT_CORES]
end
end
# If this is a version 1 config, virtualbox is the only option. A version 2
# config would have already been set in the above provider section.
Vagrant::VERSION < "1.1.0" and Vagrant::Config.run do |config|
config.vm.provision :shell, :inline => $vbox_script
end
# Setup port forwarding per loaded environment variables
forward_ports = FORWARD_DOCKER_PORTS.nil? ? [] : [*49153..49900]
forward_ports += FORWARD_PORTS.split(',').map{|i| i.to_i } if FORWARD_PORTS
if forward_ports.any?
Vagrant::VERSION < "1.1.0" and Vagrant::Config.run do |config|
forward_ports.each do |port|
config.vm.forward_port port, port
end
end
Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
forward_ports.each do |port|
config.vm.network :forwarded_port, :host => port, :guest => port, auto_correct: true
end
end
end
if !PRIVATE_NETWORK.nil?
Vagrant::VERSION < "1.1.0" and Vagrant::Config.run do |config|
config.vm.network :hostonly, PRIVATE_NETWORK
end
Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
config.vm.network "private_network", ip: PRIVATE_NETWORK
end
end

44
api/common.go Normal file
View File

@ -0,0 +1,44 @@
package api
import (
"fmt"
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker/utils"
"mime"
"strings"
)
const (
APIVERSION = 1.9
DEFAULTHTTPHOST = "127.0.0.1"
DEFAULTUNIXSOCKET = "/var/run/docker.sock"
)
func ValidateHost(val string) (string, error) {
host, err := utils.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val)
if err != nil {
return val, err
}
return host, nil
}
//TODO remove, used on < 1.5 in getContainersJSON
func displayablePorts(ports *engine.Table) string {
result := []string{}
for _, port := range ports.Data {
if port.Get("IP") == "" {
result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PublicPort"), port.Get("Type")))
} else {
result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type")))
}
}
return strings.Join(result, ", ")
}
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())
}
return err == nil && mimetype == expectedType
}

View File

@ -17,7 +17,6 @@ import (
"io"
"io/ioutil"
"log"
"mime"
"net"
"net/http"
"net/http/pprof"
@ -29,31 +28,12 @@ import (
"time"
)
// FIXME: move code common to client and server to common.go
const (
APIVERSION = 1.9
DEFAULTHTTPHOST = "127.0.0.1"
DEFAULTUNIXSOCKET = "/var/run/docker.sock"
)
var (
activationLock chan struct{}
)
func ValidateHost(val string) (string, error) {
host, err := utils.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val)
if err != nil {
return val, err
}
return host, nil
}
type HttpApiFunc func(eng *engine.Engine, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error
func init() {
engine.Register("serveapi", ServeApi)
}
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
@ -133,27 +113,6 @@ func getBoolParam(value string) (bool, error) {
return ret, nil
}
//TODO remove, used on < 1.5 in getContainersJSON
func displayablePorts(ports *engine.Table) string {
result := []string{}
for _, port := range ports.Data {
if port.Get("IP") == "" {
result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PublicPort"), port.Get("Type")))
} else {
result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type")))
}
}
return strings.Join(result, ", ")
}
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())
}
return err == nil && mimetype == expectedType
}
func postAuth(eng *engine.Engine, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var (
authConfig, err = ioutil.ReadAll(r.Body)

View File

@ -110,7 +110,7 @@ func (b *buildFile) CmdFrom(name string) error {
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")
b.config.Env = append(b.config.Env, "HOME=/", "PATH="+defaultPathEnv)
}
// Process ONBUILD triggers if they exist
if nTriggers := len(b.config.OnBuild); nTriggers != 0 {

40
builtins/builtins.go Normal file
View File

@ -0,0 +1,40 @@
package builtins
import (
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/api"
"github.com/dotcloud/docker/networkdriver/lxc"
)
func Register(eng *engine.Engine) {
daemon(eng)
remote(eng)
}
// remote: a RESTful api for cross-docker communication
func remote(eng *engine.Engine) {
eng.Register("serveapi", api.ServeApi)
}
// daemon: a default execution and storage backend for Docker on Linux,
// with the following underlying components:
//
// * Pluggable storage drivers including aufs, vfs, lvm and btrfs.
// * Pluggable execution drivers including lxc and chroot.
//
// In practice `daemon` still includes most core Docker components, including:
//
// * The reference registry client implementation
// * Image management
// * The build facility
// * Logging
//
// These components should be broken off into plugins of their own.
//
func daemon(eng *engine.Engine) {
eng.Register("initserver", docker.InitServer)
eng.Register("init_networkdriver", lxc.InitDriver)
eng.Register("version", docker.GetVersion)
}

View File

@ -25,6 +25,7 @@ type DaemonConfig struct {
BridgeIP string
InterContainerCommunication bool
GraphDriver string
ExecDriver string
Mtu int
DisableNetwork bool
}
@ -43,6 +44,7 @@ func DaemonConfigFromJob(job *engine.Job) *DaemonConfig {
DefaultIp: net.ParseIP(job.Getenv("DefaultIp")),
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
GraphDriver: job.Getenv("GraphDriver"),
ExecDriver: job.Getenv("ExecDriver"),
}
if dns := job.GetenvList("Dns"); dns != nil {
config.Dns = dns

View File

@ -23,6 +23,8 @@ import (
"time"
)
const defaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
var (
ErrNotATTY = errors.New("The PTY is not a file")
ErrNoTTY = errors.New("No PTY found")
@ -447,7 +449,7 @@ func (container *Container) Start() (err error) {
// Setup environment
env := []string{
"HOME=/",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PATH=" + defaultPathEnv,
"HOSTNAME=" + container.Config.Hostname,
}

View File

@ -44,6 +44,8 @@ debianStable=wheezy
debianUnstable=sid
# this should match the name found at http://releases.ubuntu.com/
ubuntuLatestLTS=precise
# this should match the name found at http://releases.tanglu.org/
tangluLatest=aequorea
while getopts v:i:a:p:dst name; do
case "$name" in
@ -201,6 +203,17 @@ if [ -z "$strictDebootstrap" ]; then
s/ $suite-updates main/ ${suite}-security main/
" etc/apt/sources.list
;;
Tanglu)
# add the updates repository
if [ "$suite" = "$tangluLatest" ]; then
# ${suite}-updates only applies to stable Tanglu versions
sudo sed -i "p; s/ $suite main$/ ${suite}-updates main/" etc/apt/sources.list
fi
;;
SteamOS)
# add contrib and non-free
sudo sed -i "s/ $suite main$/ $suite main contrib non-free/" etc/apt/sources.list
;;
esac
fi
@ -248,6 +261,28 @@ else
fi
fi
;;
Tanglu)
if [ "$suite" = "$tangluLatest" ]; 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 Tanglu version number, if available (1.0, 2.0, etc.)
$docker tag $repo:$suite $repo:$lsbRelease
fi
fi
;;
SteamOS)
if [ -r etc/lsb-release ]; then
lsbRelease="$(. etc/lsb-release && echo "$DISTRIB_RELEASE")"
if [ "$lsbRelease" ]; then
# tag specific SteamOS version number, if available (1.0, 2.0, etc.)
$docker tag $repo:$suite $repo:$lsbRelease
fi
fi
;;
esac
fi
fi

View File

@ -31,7 +31,7 @@ stop on runlevel [!2345]
respawn
script
/usr/bin/docker -d -H=tcp://0.0.0.0:4243/
/usr/bin/docker -d -H=tcp://0.0.0.0:4243
end script
```

View File

@ -6,8 +6,8 @@ import (
"os"
"strings"
_ "github.com/dotcloud/docker"
"github.com/dotcloud/docker/api"
"github.com/dotcloud/docker/builtins"
"github.com/dotcloud/docker/dockerversion"
"github.com/dotcloud/docker/engine"
flag "github.com/dotcloud/docker/pkg/mflag"
@ -39,6 +39,7 @@ func main() {
flDefaultIp = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports")
flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication")
flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the docker runtime to use a specific storage driver")
flExecDriver = flag.String([]string{"e", "-exec-driver"}, "", "Force the docker runtime to use a specific exec driver")
flHosts = opts.NewListOpts(api.ValidateHost)
flMtu = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU; if no value is provided: default to the default route MTU or 1500 if no default route is available")
)
@ -81,6 +82,8 @@ func main() {
if err != nil {
log.Fatal(err)
}
// Load builtins
builtins.Register(eng)
// load the daemon in the background so we can immediately start
// the http api so that connections don't fail while the daemon
// is booting
@ -98,6 +101,7 @@ func main() {
job.Setenv("DefaultIp", *flDefaultIp)
job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
job.Setenv("GraphDriver", *flGraphDriver)
job.Setenv("ExecDriver", *flExecDriver)
job.SetenvInt("Mtu", *flMtu)
if err := job.Run(); err != nil {
log.Fatal(err)

View File

@ -92,14 +92,6 @@ To execute the test cases, run this command:
sudo make test
Note: if you're running the tests in vagrant, you need to specify a dns entry in
the command (either edit the Makefile, or run the step manually):
.. code-block:: bash
sudo docker run -dns 8.8.8.8 -privileged -v `pwd`:/go/src/github.com/dotcloud/docker docker hack/make.sh test
If the test are successful then the tail of the output should look something like this
.. code-block:: bash

View File

@ -25,9 +25,9 @@ Does Docker run on Mac OS X or Windows?
Not at this time, Docker currently only runs on Linux, but you can
use VirtualBox to run Docker in a virtual machine on your box, and
get the best of both worlds. Check out the
:ref:`macosx` and :ref:`windows` installation
guides.
get the best of both worlds. Check out the :ref:`macosx` and
:ref:`windows` installation guides. The small Linux distribution boot2docker
can be run inside virtual machines on these two operating systems.
How do containers compare to virtual machines?
..............................................

View File

@ -24,6 +24,6 @@ For a high-level overview of Docker, please see the `Introduction
Docker, we have a `quick start <http://www.docker.io/gettingstarted>`_
and a more in-depth guide to :ref:`ubuntu_linux` and other
:ref:`installation_list` paths including prebuilt binaries,
Vagrant-created VMs, Rackspace and Amazon instances.
Rackspace and Amazon instances.
Enough reading! :ref:`Try it out! <running_examples>`

View File

@ -10,8 +10,7 @@ Amazon EC2
There are several ways to install Docker on AWS EC2:
* :ref:`amazonquickstart` or
* :ref:`amazonstandard` or
* :ref:`amazonvagrant`
* :ref:`amazonstandard`
**You'll need an** `AWS account <http://aws.amazon.com/>`_ **first, of course.**
@ -73,112 +72,4 @@ running Ubuntu. Just follow Step 1 from :ref:`amazonquickstart` to
pick an image (or use one of your own) and skip the step with the
*User Data*. Then continue with the :ref:`ubuntu_linux` instructions.
.. _amazonvagrant:
Use Vagrant
-----------
.. include:: install_unofficial.inc
And finally, if you prefer to work through Vagrant, you can install
Docker that way too. Vagrant 1.1 or higher is required.
1. Install vagrant from http://www.vagrantup.com/ (or use your package manager)
2. Install the vagrant aws plugin
::
vagrant plugin install vagrant-aws
3. Get the docker sources, this will give you the latest Vagrantfile.
::
git clone https://github.com/dotcloud/docker.git
4. Check your AWS environment.
Create a keypair specifically for EC2, give it a name and save it
to your disk. *I usually store these in my ~/.ssh/ folder*.
Check that your default security group has an inbound rule to
accept SSH (port 22) connections.
5. Inform Vagrant of your settings
Vagrant will read your access credentials from your environment, so
we need to set them there first. Make sure you have everything on
amazon aws setup so you can (manually) deploy a new image to EC2.
Note that where possible these variables are the same as those honored by
the ec2 api tools.
::
export AWS_ACCESS_KEY=xxx
export AWS_SECRET_KEY=xxx
export AWS_KEYPAIR_NAME=xxx
export SSH_PRIVKEY_PATH=xxx
export BOX_NAME=xxx
export AWS_REGION=xxx
export AWS_AMI=xxx
export AWS_INSTANCE_TYPE=xxx
The required environment variables are:
* ``AWS_ACCESS_KEY`` - The API key used to make requests to AWS
* ``AWS_SECRET_KEY`` - The secret key to make AWS API requests
* ``AWS_KEYPAIR_NAME`` - The name of the keypair used for this EC2 instance
* ``SSH_PRIVKEY_PATH`` - The path to the private key for the named
keypair, for example ``~/.ssh/docker.pem``
There are a number of optional environment variables:
* ``BOX_NAME`` - The name of the vagrant box to use. Defaults to
``ubuntu``.
* ``AWS_REGION`` - The aws region to spawn the vm in. Defaults to
``us-east-1``.
* ``AWS_AMI`` - The aws AMI to start with as a base. This must be
be an ubuntu 12.04 precise image. You must change this value if
``AWS_REGION`` is set to a value other than ``us-east-1``.
This is because AMIs are region specific. Defaults to ``ami-69f5a900``.
* ``AWS_INSTANCE_TYPE`` - The aws instance type. Defaults to ``t1.micro``.
You can check if they are set correctly by doing something like
::
echo $AWS_ACCESS_KEY
6. Do the magic!
::
vagrant up --provider=aws
If it stalls indefinitely on ``[default] Waiting for SSH to become
available...``, Double check your default security zone on AWS
includes rights to SSH (port 22) to your container.
If you have an advanced AWS setup, you might want to have a look at
`vagrant-aws <https://github.com/mitchellh/vagrant-aws>`_.
7. Connect to your machine
.. code-block:: bash
vagrant ssh
8. Your first command
Now you are in the VM, run docker
.. code-block:: bash
sudo docker
Continue with the :ref:`hello_world` example.

View File

@ -1,223 +1,72 @@
:title: Installation on Windows
:description: Please note this project is currently under heavy development. It should not be used in production.
:keywords: Docker, Docker documentation, Windows, requirements, virtualbox, vagrant, git, ssh, putty, cygwin
:keywords: Docker, Docker documentation, Windows, requirements, virtualbox, boot2docker
.. _windows:
Windows
=======
Docker can run on Windows using a VM like VirtualBox. You then run
Linux within the VM.
Docker can run on Windows using a virtualization platform like VirtualBox. A Linux
distribution is run inside a virtual machine and that's where Docker will run.
Installation
------------
.. include:: install_header.inc
.. include:: install_unofficial.inc
1. Install virtualbox from https://www.virtualbox.org - or follow this `tutorial <http://www.slideshare.net/julienbarbier42/install-virtualbox-on-windows-7>`_.
1. Install virtualbox from https://www.virtualbox.org - or follow this tutorial__
2. Download the latest boot2docker.iso from https://github.com/boot2docker/boot2docker/releases.
.. __: http://www.slideshare.net/julienbarbier42/install-virtualbox-on-windows-7
3. Start VirtualBox.
2. Install vagrant from http://www.vagrantup.com - or follow this tutorial__
4. Create a new Virtual machine with the following settings:
.. __: http://www.slideshare.net/julienbarbier42/install-vagrant-on-windows-7
- `Name: boot2docker`
- `Type: Linux`
- `Version: Linux 2.6 (64 bit)`
- `Memory size: 1024 MB`
- `Hard drive: Do not add a virtual hard drive`
3. Install git with ssh from http://git-scm.com/downloads - or follow this tutorial__
5. Open the settings of the virtual machine:
.. __: http://www.slideshare.net/julienbarbier42/install-git-with-ssh-on-windows-7
5.1. go to Storage
5.2. click the empty slot below `Controller: IDE`
We recommend having at least 2Gb of free disk space and 2Gb of RAM (or more).
5.3. click the disc icon on the right of `IDE Secondary Master`
Opening a command prompt
------------------------
5.4. click `Choose a virtual CD/DVD disk file`
First open a cmd prompt. Press Windows key and then press “R”
key. This will open the RUN dialog box for you. Type “cmd” and press
Enter. Or you can click on Start, type “cmd” in the “Search programs
and files” field, and click on cmd.exe.
6. Browse to the path where you've saved the `boot2docker.iso`, select the `boot2docker.iso` and click open.
.. image:: images/win/_01.gif
:alt: Git install
:align: center
7. Click OK on the Settings dialog to save the changes and close the window.
This should open a cmd prompt window.
8. Start the virtual machine by clicking the green start button.
.. image:: images/win/_02.gif
:alt: run docker
:align: center
Alternatively, you can also use a Cygwin terminal, or Git Bash (or any
other command line program you are usually using). The next steps
would be the same.
.. _launch_ubuntu:
Launch an Ubuntu virtual server
-------------------------------
Lets download and run an Ubuntu image with docker binaries already
installed.
.. code-block:: bash
git clone https://github.com/dotcloud/docker.git
cd docker
vagrant up
.. image:: images/win/run_02_.gif
:alt: run docker
:align: center
Congratulations! You are running an Ubuntu server with docker
installed on it. You do not see it though, because it is running in
the background.
Log onto your Ubuntu server
---------------------------
Lets log into your Ubuntu server now. To do so you have two choices:
- Use Vagrant on Windows command prompt OR
- Use SSH
Using Vagrant on Windows Command Prompt
```````````````````````````````````````
Run the following command
.. code-block:: bash
vagrant ssh
You may see an error message starting with “`ssh` executable not
found”. In this case it means that you do not have SSH in your
PATH. If you do not have SSH in your PATH you can set it up with the
“set” command. For instance, if your ssh.exe is in the folder named
“C:\Program Files (x86)\Git\bin”, then you can run the following
command:
.. code-block:: bash
set PATH=%PATH%;C:\Program Files (x86)\Git\bin
.. image:: images/win/run_03.gif
:alt: run docker
:align: center
Using SSH
`````````
First step is to get the IP and port of your Ubuntu server. Simply run:
.. code-block:: bash
vagrant ssh-config
You should see an output with HostName and Port information. In this
example, HostName is 127.0.0.1 and port is 2222. And the User is
“vagrant”. The password is not shown, but it is also “vagrant”.
.. image:: images/win/ssh-config.gif
:alt: run docker
:align: center
You can now use this information for connecting via SSH to your
server. To do so you can:
- Use putty.exe OR
- Use SSH from a terminal
Use putty.exe
'''''''''''''
You can download putty.exe from this page
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html Launch
putty.exe and simply enter the information you got from last step.
.. image:: images/win/putty.gif
:alt: run docker
:align: center
Open, and enter user = vagrant and password = vagrant.
.. image:: images/win/putty_2.gif
:alt: run docker
:align: center
SSH from a terminal
'''''''''''''''''''
You can also run this command on your favorite terminal (windows
prompt, cygwin, git-bash, …). Make sure to adapt the IP and port from
what you got from the vagrant ssh-config command.
.. code-block:: bash
ssh vagrant@127.0.0.1 p 2222
Enter user = vagrant and password = vagrant.
.. image:: images/win/cygwin.gif
:alt: run docker
:align: center
Congratulations, you are now logged onto your Ubuntu Server, running
on top of your Windows machine !
9. The boot2docker virtual machine should boot now.
Running Docker
--------------
First you have to be root in order to run docker. Simply run the
following command:
boot2docker will log you in automatically so you can start using Docker right
away.
.. code-block:: bash
sudo su
You are now ready for the dockers “hello world” example. Run
Let's try the “hello world” example. Run
.. code-block:: bash
docker run busybox echo hello world
.. image:: images/win/run_04.gif
:alt: run docker
:align: center
This will download the small busybox image and print hello world.
All done!
Now you can continue with the :ref:`hello_world` example.
Observations
------------
Troubleshooting
---------------
Persistent storage
``````````````````
VM does not boot
````````````````
.. image:: images/win/ts_go_bios.JPG
If you run into this error message "The VM failed to remain in the
'running' state while attempting to boot", please check that your
computer has virtualization technology available and activated by
going to the BIOS. Here's an example for an HP computer (System
configuration / Device configuration)
.. image:: images/win/hp_bios_vm.JPG
On some machines the BIOS menu can only be accessed before startup.
To access BIOS in this scenario you should restart your computer and
press ESC/Enter when prompted to access the boot and BIOS controls. Typically
the option to allow virtualization is contained within the BIOS/Security menu.
Docker is not installed
```````````````````````
.. image:: images/win/ts_no_docker.JPG
If you run into this error message "The program 'docker' is currently
not installed", try deleting the docker folder and restart from
:ref:`launch_ubuntu`
The virtual machine created above lacks any persistent data storage. All images
and containers will be lost when shutting down or rebooting the VM.

View File

@ -118,6 +118,7 @@ Create a container
"User":"",
"Memory":0,
"MemorySwap":0,
"CpuShares":0,
"AttachStdin":false,
"AttachStdout":true,
"AttachStderr":true,
@ -153,7 +154,15 @@ Create a container
"Warnings":[]
}
:jsonparam config: the container's configuration
:jsonparam Hostname: Container host name
:jsonparam User: Username or UID
:jsonparam Memory: Memory Limit in bytes
:jsonparam CpuShares: CPU shares (relative weight)
:jsonparam AttachStdin: 1/True/true or 0/False/false, attach to standard input. Default false
:jsonparam AttachStdout: 1/True/true or 0/False/false, attach to standard output. Default false
:jsonparam AttachStderr: 1/True/true or 0/False/false, attach to standard error. Default false
:jsonparam Tty: 1/True/true or 0/False/false, allocate a pseudo-tty. Default false
:jsonparam OpenStdin: 1/True/true or 0/False/false, keep stdin open even if not attached. Default false
:query name: Assign the specified name to the container. Must match ``/?[a-zA-Z0-9_-]+``.
:statuscode 201: no error
:statuscode 404: no such container
@ -394,7 +403,11 @@ Start a container
HTTP/1.1 204 No Content
Content-Type: text/plain
:jsonparam hostConfig: the container's host configuration (optional)
:jsonparam Binds: Create a bind mount to a directory or file with [host-path]:[container-path]:[rw|ro]. If a directory "container-path" is missing, then docker creates a new volume.
:jsonparam LxcConf: Map of custom lxc options
:jsonparam PortBindings: Expose ports from the container, optionally publishing them via the HostPort flag
:jsonparam PublishAllPorts: 1/True/true or 0/False/false, publish all exposed ports to the host interfaces. Default false
:jsonparam Privileged: 1/True/true or 0/False/false, give extended privileges to this container. Default false
:statuscode 204: no error
:statuscode 404: no such container
:statuscode 500: server error

View File

@ -118,6 +118,7 @@ Create a container
"User":"",
"Memory":0,
"MemorySwap":0,
"CpuShares":0,
"AttachStdin":false,
"AttachStdout":true,
"AttachStderr":true,
@ -153,7 +154,15 @@ Create a container
"Warnings":[]
}
:jsonparam config: the container's configuration
:jsonparam Hostname: Container host name
:jsonparam User: Username or UID
:jsonparam Memory: Memory Limit in bytes
:jsonparam CpuShares: CPU shares (relative weight)
:jsonparam AttachStdin: 1/True/true or 0/False/false, attach to standard input. Default false
:jsonparam AttachStdout: 1/True/true or 0/False/false, attach to standard output. Default false
:jsonparam AttachStderr: 1/True/true or 0/False/false, attach to standard error. Default false
:jsonparam Tty: 1/True/true or 0/False/false, allocate a pseudo-tty. Default false
:jsonparam OpenStdin: 1/True/true or 0/False/false, keep stdin open even if not attached. Default false
:query name: Assign the specified name to the container. Must match ``/?[a-zA-Z0-9_-]+``.
:statuscode 201: no error
:statuscode 404: no such container
@ -394,7 +403,11 @@ Start a container
HTTP/1.1 204 No Content
Content-Type: text/plain
:jsonparam hostConfig: the container's host configuration (optional)
:jsonparam Binds: Create a bind mount to a directory or file with [host-path]:[container-path]:[rw|ro]. If a directory "container-path" is missing, then docker creates a new volume.
:jsonparam LxcConf: Map of custom lxc options
:jsonparam PortBindings: Expose ports from the container, optionally publishing them via the HostPort flag
:jsonparam PublishAllPorts: 1/True/true or 0/False/false, publish all exposed ports to the host interfaces. Default false
:jsonparam Privileged: 1/True/true or 0/False/false, give extended privileges to this container. Default false
:statuscode 204: no error
:statuscode 404: no such container
:statuscode 500: server error

View File

@ -74,7 +74,7 @@ When you're done with your build, you're ready to look into
2. Format
=========
The Dockerfile format is quite simple:
Here is the format of the Dockerfile:
::

View File

@ -79,6 +79,7 @@ Commands
-p, --pidfile="/var/run/docker.pid": Path to use for daemon PID file
-r, --restart=true: Restart previously running containers
-s, --storage-driver="": Force the docker runtime to use a specific storage driver
-e, --exec-driver="": Force the docker runtime to use a specific exec driver
-v, --version=false: Print version information and quit
--mtu=0: Set the containers network MTU; if no value is provided: default to the default route MTU or 1500 if no default route is available

View File

@ -1,6 +1,7 @@
package engine
import (
"bufio"
"fmt"
"github.com/dotcloud/docker/utils"
"io"
@ -136,6 +137,48 @@ func (eng *Engine) Job(name string, args ...string) *Job {
return job
}
// ParseJob creates a new job from a text description using a shell-like syntax.
//
// The following syntax is used to parse `input`:
//
// * Words are separated using standard whitespaces as separators.
// * Quotes and backslashes are not interpreted.
// * Words of the form 'KEY=[VALUE]' are added to the job environment.
// * All other words are added to the job arguments.
//
// For example:
//
// job, _ := eng.ParseJob("VERBOSE=1 echo hello TEST=true world")
//
// The resulting job will have:
// job.Args={"echo", "hello", "world"}
// job.Env={"VERBOSE":"1", "TEST":"true"}
//
func (eng *Engine) ParseJob(input string) (*Job, error) {
// FIXME: use a full-featured command parser
scanner := bufio.NewScanner(strings.NewReader(input))
scanner.Split(bufio.ScanWords)
var (
cmd []string
env Env
)
for scanner.Scan() {
word := scanner.Text()
kv := strings.SplitN(word, "=", 2)
if len(kv) == 2 {
env.Set(kv[0], kv[1])
} else {
cmd = append(cmd, word)
}
}
if len(cmd) == 0 {
return nil, fmt.Errorf("empty command: '%s'", input)
}
job := eng.Job(cmd[0], cmd[1:]...)
job.Env().Init(&env)
return job, nil
}
func (eng *Engine) Logf(format string, args ...interface{}) (n int, err error) {
if os.Getenv("TEST") == "" {
prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))

View File

@ -5,6 +5,7 @@ import (
"os"
"path"
"path/filepath"
"strings"
"testing"
)
@ -114,3 +115,40 @@ func TestEngineLogf(t *testing.T) {
t.Fatalf("Test: Logf() should print at least as much as the input\ninput=%d\nprinted=%d", len(input), n)
}
}
func TestParseJob(t *testing.T) {
eng := newTestEngine(t)
defer os.RemoveAll(eng.Root())
// Verify that the resulting job calls to the right place
var called bool
eng.Register("echo", func(job *Job) Status {
called = true
return StatusOK
})
input := "echo DEBUG=1 hello world VERBOSITY=42"
job, err := eng.ParseJob(input)
if err != nil {
t.Fatal(err)
}
if job.Name != "echo" {
t.Fatalf("Invalid job name: %v", job.Name)
}
if strings.Join(job.Args, ":::") != "hello:::world" {
t.Fatalf("Invalid job args: %v", job.Args)
}
if job.Env().Get("DEBUG") != "1" {
t.Fatalf("Invalid job env: %v", job.Env)
}
if job.Env().Get("VERBOSITY") != "42" {
t.Fatalf("Invalid job env: %v", job.Env)
}
if len(job.Env().Map()) != 2 {
t.Fatalf("Invalid job env: %v", job.Env)
}
if err := job.Run(); err != nil {
t.Fatal(err)
}
if !called {
t.Fatalf("Job was not called")
}
}

View File

@ -36,6 +36,13 @@ func (env *Env) Exists(key string) bool {
return exists
}
func (env *Env) Init(src *Env) {
(*env) = make([]string, 0, len(*src))
for _, val := range *src {
(*env) = append((*env), val)
}
}
func (env *Env) GetBool(key string) (value bool) {
s := strings.ToLower(strings.Trim(env.Get(key), " \t"))
if s == "" || s == "0" || s == "no" || s == "false" || s == "none" {

View File

@ -74,7 +74,7 @@ func (job *Job) Run() error {
return err
}
if job.status != 0 {
return fmt.Errorf("%s: %s", job.Name, errorMessage)
return fmt.Errorf("%s", errorMessage)
}
return nil
}
@ -102,6 +102,10 @@ func (job *Job) String() string {
return fmt.Sprintf("%s.%s%s", job.Eng, job.CallString(), job.StatusString())
}
func (job *Job) Env() *Env {
return job.env
}
func (job *Job) EnvExists(key string) (value bool) {
return job.env.Exists(key)
}
@ -197,11 +201,14 @@ func (job *Job) Printf(format string, args ...interface{}) (n int, err error) {
}
func (job *Job) Errorf(format string, args ...interface{}) Status {
if format[len(format)-1] != '\n' {
format = format + "\n"
}
fmt.Fprintf(job.Stderr, format, args...)
return StatusErr
}
func (job *Job) Error(err error) Status {
fmt.Fprintf(job.Stderr, "%s", err)
fmt.Fprintf(job.Stderr, "%s\n", err)
return StatusErr
}

View File

@ -301,9 +301,8 @@ func (d *driver) Info(id string) execdriver.Info {
func (d *driver) GetPidsForContainer(id string) ([]int, error) {
pids := []int{}
// memory is chosen randomly, any cgroup used by docker works
subsystem := "memory"
// cpu is chosen because it is the only non optional subsystem in cgroups
subsystem := "cpu"
cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
if err != nil {
return pids, err

View File

@ -12,5 +12,5 @@ bundle_test_integration() {
# this "grep" hides some really irritating warnings that "go test -coverpkg"
# spews when it is given packages that aren't used
bundle_test_integration 2>&1 \
| grep -v '^warning: no packages being tested depend on ' \
| grep --line-buffered -v '^warning: no packages being tested depend on ' \
| tee $DEST/test.log

View File

@ -123,19 +123,8 @@ func init() {
}
func setupBaseImage() {
eng, err := engine.New(unitTestStoreBase)
if err != nil {
log.Fatalf("Can't initialize engine at %s: %s", unitTestStoreBase, err)
}
job := eng.Job("initserver")
job.Setenv("Root", unitTestStoreBase)
job.SetenvBool("Autorestart", false)
job.Setenv("BridgeIface", unitTestNetworkBridge)
if err := job.Run(); err != nil {
log.Fatalf("Unable to create a runtime for tests: %s", err)
}
job = eng.Job("inspect", unitTestImageName, "image")
eng := newTestEngine(log.New(os.Stderr, "", 0), false, unitTestStoreBase)
job := eng.Job("inspect", unitTestImageName, "image")
img, _ := job.Stdout.AddEnv()
// If the unit test is not found, try to download it.
if err := job.Run(); err != nil || img.Get("id") != unitTestImageID {
@ -575,18 +564,7 @@ func TestRestore(t *testing.T) {
// Here are are simulating a docker restart - that is, reloading all containers
// from scratch
root := eng.Root()
eng, err := engine.New(root)
if err != nil {
t.Fatal(err)
}
job := eng.Job("initserver")
job.Setenv("Root", eng.Root())
job.SetenvBool("Autorestart", false)
if err := job.Run(); err != nil {
t.Fatal(err)
}
eng = newTestEngine(t, false, eng.Root())
runtime2 := mkRuntimeFromEngine(eng, t)
if len(runtime2.List()) != 2 {
t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
@ -612,22 +590,14 @@ func TestRestore(t *testing.T) {
}
func TestReloadContainerLinks(t *testing.T) {
// FIXME: here we don't use NewTestEngine because it calls initserver with Autorestart=false,
// and we want to set it to true.
root, err := newTestDirectory(unitTestStoreBase)
if err != nil {
t.Fatal(err)
}
eng, err := engine.New(root)
if err != nil {
t.Fatal(err)
}
job := eng.Job("initserver")
job.Setenv("Root", eng.Root())
job.SetenvBool("Autorestart", true)
if err := job.Run(); err != nil {
t.Fatal(err)
}
// FIXME: here we don't use NewTestEngine because it calls initserver with Autorestart=false,
// and we want to set it to true.
eng := newTestEngine(t, true, root)
runtime1 := mkRuntimeFromEngine(eng, t)
defer nuke(runtime1)
@ -668,17 +638,7 @@ func TestReloadContainerLinks(t *testing.T) {
// Here are are simulating a docker restart - that is, reloading all containers
// from scratch
eng, err = engine.New(root)
if err != nil {
t.Fatal(err)
}
job = eng.Job("initserver")
job.Setenv("Root", eng.Root())
job.SetenvBool("Autorestart", false)
if err := job.Run(); err != nil {
t.Fatal(err)
}
eng = newTestEngine(t, false, root)
runtime2 := mkRuntimeFromEngine(eng, t)
if len(runtime2.List()) != 2 {
t.Errorf("Expected 2 container, %v found", len(runtime2.List()))

View File

@ -2,7 +2,6 @@ package docker
import (
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker/runconfig"
"strings"
"testing"
@ -258,20 +257,7 @@ func TestRestartKillWait(t *testing.T) {
t.Fatal(err)
}
eng, err = engine.New(eng.Root())
if err != nil {
t.Fatal(err)
}
job = eng.Job("initserver")
job.Setenv("Root", eng.Root())
job.SetenvBool("AutoRestart", false)
// TestGetEnabledCors and TestOptionsRoute require EnableCors=true
job.SetenvBool("EnableCors", true)
if err := job.Run(); err != nil {
t.Fatal(err)
}
eng = newTestEngine(t, false, eng.Root())
srv = mkServerFromEngine(eng, t)
job = srv.Eng.Job("containers")

View File

@ -15,6 +15,7 @@ import (
"time"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/builtins"
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker/runconfig"
"github.com/dotcloud/docker/utils"
@ -27,26 +28,12 @@ import (
// Create a temporary runtime suitable for unit testing.
// Call t.Fatal() at the first error.
func mkRuntime(f utils.Fataler) *docker.Runtime {
root, err := newTestDirectory(unitTestStoreBase)
if err != nil {
f.Fatal(err)
}
config := &docker.DaemonConfig{
Root: root,
AutoRestart: false,
Mtu: docker.GetDefaultNetworkMtu(),
}
eng, err := engine.New(root)
if err != nil {
f.Fatal(err)
}
r, err := docker.NewRuntimeFromDirectory(config, eng)
if err != nil {
f.Fatal(err)
}
return r
eng := newTestEngine(f, false, "")
return mkRuntimeFromEngine(eng, f)
// FIXME:
// [...]
// Mtu: docker.GetDefaultNetworkMtu(),
// [...]
}
func createNamedTestContainer(eng *engine.Engine, config *runconfig.Config, f utils.Fataler, name string) (shortId string) {
@ -185,20 +172,24 @@ func mkRuntimeFromEngine(eng *engine.Engine, t utils.Fataler) *docker.Runtime {
return runtime
}
func NewTestEngine(t utils.Fataler) *engine.Engine {
root, err := newTestDirectory(unitTestStoreBase)
if err != nil {
t.Fatal(err)
func newTestEngine(t utils.Fataler, autorestart bool, root string) *engine.Engine {
if root == "" {
if dir, err := newTestDirectory(unitTestStoreBase); err != nil {
t.Fatal(err)
} else {
root = dir
}
}
eng, err := engine.New(root)
if err != nil {
t.Fatal(err)
}
// Load default plugins
builtins.Register(eng)
// (This is manually copied and modified from main() until we have a more generic plugin system)
job := eng.Job("initserver")
job.Setenv("Root", root)
job.SetenvBool("AutoRestart", false)
job.SetenvBool("AutoRestart", autorestart)
// TestGetEnabledCors and TestOptionsRoute require EnableCors=true
job.SetenvBool("EnableCors", true)
if err := job.Run(); err != nil {
@ -207,6 +198,10 @@ func NewTestEngine(t utils.Fataler) *engine.Engine {
return eng
}
func NewTestEngine(t utils.Fataler) *engine.Engine {
return newTestEngine(t, false, "")
}
func newTestDirectory(templateDir string) (dir string, err error) {
return utils.TestDirectory(templateDir)
}

View File

@ -72,7 +72,7 @@ func (l *Link) ToEnv() []string {
if len(parts) != 2 {
continue
}
// Ignore a few variables that are added during docker build
// Ignore a few variables that are added during docker build (and not really relevant to linked containers)
if parts[0] == "HOME" || parts[0] == "PATH" {
continue
}

View File

@ -57,12 +57,6 @@ var (
currentInterfaces = make(map[string]*networkInterface)
)
func init() {
if err := engine.Register("init_networkdriver", InitDriver); err != nil {
panic(err)
}
}
func InitDriver(job *engine.Job) engine.Status {
var (
network *net.IPNet

View File

@ -8,7 +8,7 @@ import (
"github.com/dotcloud/docker/engine"
"github.com/dotcloud/docker/execdriver"
"github.com/dotcloud/docker/execdriver/docker"
_ "github.com/dotcloud/docker/execdriver/lxc"
"github.com/dotcloud/docker/execdriver/lxc"
"github.com/dotcloud/docker/graphdriver"
"github.com/dotcloud/docker/graphdriver/aufs"
_ "github.com/dotcloud/docker/graphdriver/btrfs"
@ -704,7 +704,16 @@ func NewRuntimeFromDirectory(config *DaemonConfig, eng *engine.Engine) (*Runtime
sysInfo := sysinfo.New(false)
ed, err := docker.NewDriver(config.Root)
var ed execdriver.Driver
utils.Debugf("execDriver: provided %s", config.ExecDriver)
if config.ExecDriver == "chroot" && false {
// chroot is presently a noop driver https://github.com/dotcloud/docker/pull/4189#issuecomment-35330655
ed, err = chroot.NewDriver()
utils.Debugf("execDriver: using chroot")
} else {
ed, err = lxc.NewDriver(config.Root, sysInfo.AppArmor)
utils.Debugf("execDriver: using lxc")
}
if err != nil {
return nil, err
}

View File

@ -34,14 +34,10 @@ func (srv *Server) Close() error {
return srv.runtime.Close()
}
func init() {
engine.Register("initserver", jobInitServer)
}
// jobInitApi runs the remote api server `srv` as a daemon,
// Only one api server can run at the same time - this is enforced by a pidfile.
// The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
func jobInitServer(job *engine.Job) engine.Status {
func InitServer(job *engine.Job) engine.Status {
job.Logf("Creating server")
srv, err := NewServer(job.Eng, DaemonConfigFromJob(job))
if err != nil {

View File

@ -7,11 +7,7 @@ import (
"runtime"
)
func init() {
engine.Register("version", jobVersion)
}
func jobVersion(job *engine.Job) engine.Status {
func GetVersion(job *engine.Job) engine.Status {
if _, err := dockerVersion().WriteTo(job.Stdout); err != nil {
job.Errorf("%s", err)
return engine.StatusErr