mirror of https://github.com/docker/docs.git
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:
commit
27a43692c2
|
@ -22,3 +22,4 @@ bundles/
|
||||||
.git/
|
.git/
|
||||||
vendor/pkg/
|
vendor/pkg/
|
||||||
pyenv
|
pyenv
|
||||||
|
Vagrantfile
|
||||||
|
|
|
@ -6,4 +6,3 @@ Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
|
||||||
api.go: Victor Vieux <victor@dotcloud.com> (@vieux)
|
api.go: Victor Vieux <victor@dotcloud.com> (@vieux)
|
||||||
Dockerfile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
|
Dockerfile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
|
||||||
Makefile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
|
Makefile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
|
||||||
Vagrantfile: Cristian Staretu <cristian.staretu@gmail.com> (@unclejack)
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"mime"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
|
@ -29,31 +28,12 @@ import (
|
||||||
"time"
|
"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 (
|
var (
|
||||||
activationLock chan struct{}
|
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
|
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) {
|
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
|
||||||
conn, _, err := w.(http.Hijacker).Hijack()
|
conn, _, err := w.(http.Hijacker).Hijack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -133,27 +113,6 @@ func getBoolParam(value string) (bool, error) {
|
||||||
return ret, nil
|
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 {
|
func postAuth(eng *engine.Engine, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
var (
|
var (
|
||||||
authConfig, err = ioutil.ReadAll(r.Body)
|
authConfig, err = ioutil.ReadAll(r.Body)
|
|
@ -110,7 +110,7 @@ func (b *buildFile) CmdFrom(name string) error {
|
||||||
b.config = image.Config
|
b.config = image.Config
|
||||||
}
|
}
|
||||||
if b.config.Env == nil || len(b.config.Env) == 0 {
|
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
|
// Process ONBUILD triggers if they exist
|
||||||
if nTriggers := len(b.config.OnBuild); nTriggers != 0 {
|
if nTriggers := len(b.config.OnBuild); nTriggers != 0 {
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ type DaemonConfig struct {
|
||||||
BridgeIP string
|
BridgeIP string
|
||||||
InterContainerCommunication bool
|
InterContainerCommunication bool
|
||||||
GraphDriver string
|
GraphDriver string
|
||||||
|
ExecDriver string
|
||||||
Mtu int
|
Mtu int
|
||||||
DisableNetwork bool
|
DisableNetwork bool
|
||||||
}
|
}
|
||||||
|
@ -43,6 +44,7 @@ func DaemonConfigFromJob(job *engine.Job) *DaemonConfig {
|
||||||
DefaultIp: net.ParseIP(job.Getenv("DefaultIp")),
|
DefaultIp: net.ParseIP(job.Getenv("DefaultIp")),
|
||||||
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
|
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
|
||||||
GraphDriver: job.Getenv("GraphDriver"),
|
GraphDriver: job.Getenv("GraphDriver"),
|
||||||
|
ExecDriver: job.Getenv("ExecDriver"),
|
||||||
}
|
}
|
||||||
if dns := job.GetenvList("Dns"); dns != nil {
|
if dns := job.GetenvList("Dns"); dns != nil {
|
||||||
config.Dns = dns
|
config.Dns = dns
|
||||||
|
|
|
@ -23,6 +23,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNotATTY = errors.New("The PTY is not a file")
|
ErrNotATTY = errors.New("The PTY is not a file")
|
||||||
ErrNoTTY = errors.New("No PTY found")
|
ErrNoTTY = errors.New("No PTY found")
|
||||||
|
@ -447,7 +449,7 @@ func (container *Container) Start() (err error) {
|
||||||
// Setup environment
|
// Setup environment
|
||||||
env := []string{
|
env := []string{
|
||||||
"HOME=/",
|
"HOME=/",
|
||||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
"PATH=" + defaultPathEnv,
|
||||||
"HOSTNAME=" + container.Config.Hostname,
|
"HOSTNAME=" + container.Config.Hostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,8 @@ debianStable=wheezy
|
||||||
debianUnstable=sid
|
debianUnstable=sid
|
||||||
# this should match the name found at http://releases.ubuntu.com/
|
# this should match the name found at http://releases.ubuntu.com/
|
||||||
ubuntuLatestLTS=precise
|
ubuntuLatestLTS=precise
|
||||||
|
# this should match the name found at http://releases.tanglu.org/
|
||||||
|
tangluLatest=aequorea
|
||||||
|
|
||||||
while getopts v:i:a:p:dst name; do
|
while getopts v:i:a:p:dst name; do
|
||||||
case "$name" in
|
case "$name" in
|
||||||
|
@ -201,6 +203,17 @@ if [ -z "$strictDebootstrap" ]; then
|
||||||
s/ $suite-updates main/ ${suite}-security main/
|
s/ $suite-updates main/ ${suite}-security main/
|
||||||
" etc/apt/sources.list
|
" 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
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -248,6 +261,28 @@ else
|
||||||
fi
|
fi
|
||||||
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
|
esac
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -31,7 +31,7 @@ stop on runlevel [!2345]
|
||||||
respawn
|
respawn
|
||||||
|
|
||||||
script
|
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
|
end script
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
_ "github.com/dotcloud/docker"
|
|
||||||
"github.com/dotcloud/docker/api"
|
"github.com/dotcloud/docker/api"
|
||||||
|
"github.com/dotcloud/docker/builtins"
|
||||||
"github.com/dotcloud/docker/dockerversion"
|
"github.com/dotcloud/docker/dockerversion"
|
||||||
"github.com/dotcloud/docker/engine"
|
"github.com/dotcloud/docker/engine"
|
||||||
flag "github.com/dotcloud/docker/pkg/mflag"
|
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")
|
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")
|
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")
|
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)
|
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")
|
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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
// Load builtins
|
||||||
|
builtins.Register(eng)
|
||||||
// load the daemon in the background so we can immediately start
|
// load the daemon in the background so we can immediately start
|
||||||
// the http api so that connections don't fail while the daemon
|
// the http api so that connections don't fail while the daemon
|
||||||
// is booting
|
// is booting
|
||||||
|
@ -98,6 +101,7 @@ func main() {
|
||||||
job.Setenv("DefaultIp", *flDefaultIp)
|
job.Setenv("DefaultIp", *flDefaultIp)
|
||||||
job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
|
job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
|
||||||
job.Setenv("GraphDriver", *flGraphDriver)
|
job.Setenv("GraphDriver", *flGraphDriver)
|
||||||
|
job.Setenv("ExecDriver", *flExecDriver)
|
||||||
job.SetenvInt("Mtu", *flMtu)
|
job.SetenvInt("Mtu", *flMtu)
|
||||||
if err := job.Run(); err != nil {
|
if err := job.Run(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -92,14 +92,6 @@ To execute the test cases, run this command:
|
||||||
|
|
||||||
sudo make test
|
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
|
If the test are successful then the tail of the output should look something like this
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
|
@ -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
|
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
|
use VirtualBox to run Docker in a virtual machine on your box, and
|
||||||
get the best of both worlds. Check out the
|
get the best of both worlds. Check out the :ref:`macosx` and
|
||||||
:ref:`macosx` and :ref:`windows` installation
|
:ref:`windows` installation guides. The small Linux distribution boot2docker
|
||||||
guides.
|
can be run inside virtual machines on these two operating systems.
|
||||||
|
|
||||||
How do containers compare to virtual machines?
|
How do containers compare to virtual machines?
|
||||||
..............................................
|
..............................................
|
||||||
|
|
|
@ -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>`_
|
Docker, we have a `quick start <http://www.docker.io/gettingstarted>`_
|
||||||
and a more in-depth guide to :ref:`ubuntu_linux` and other
|
and a more in-depth guide to :ref:`ubuntu_linux` and other
|
||||||
:ref:`installation_list` paths including prebuilt binaries,
|
: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>`
|
Enough reading! :ref:`Try it out! <running_examples>`
|
||||||
|
|
|
@ -10,8 +10,7 @@ Amazon EC2
|
||||||
There are several ways to install Docker on AWS EC2:
|
There are several ways to install Docker on AWS EC2:
|
||||||
|
|
||||||
* :ref:`amazonquickstart` or
|
* :ref:`amazonquickstart` or
|
||||||
* :ref:`amazonstandard` or
|
* :ref:`amazonstandard`
|
||||||
* :ref:`amazonvagrant`
|
|
||||||
|
|
||||||
**You'll need an** `AWS account <http://aws.amazon.com/>`_ **first, of course.**
|
**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
|
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.
|
*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.
|
Continue with the :ref:`hello_world` example.
|
||||||
|
|
|
@ -1,223 +1,72 @@
|
||||||
:title: Installation on Windows
|
:title: Installation on Windows
|
||||||
:description: Please note this project is currently under heavy development. It should not be used in production.
|
: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:
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Docker can run on Windows using a VM like VirtualBox. You then run
|
Docker can run on Windows using a virtualization platform like VirtualBox. A Linux
|
||||||
Linux within the VM.
|
distribution is run inside a virtual machine and that's where Docker will run.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
.. include:: install_header.inc
|
.. 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”
|
6. Browse to the path where you've saved the `boot2docker.iso`, select the `boot2docker.iso` and click open.
|
||||||
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.
|
|
||||||
|
|
||||||
.. image:: images/win/_01.gif
|
7. Click OK on the Settings dialog to save the changes and close the window.
|
||||||
:alt: Git install
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
This should open a cmd prompt window.
|
8. Start the virtual machine by clicking the green start button.
|
||||||
|
|
||||||
.. image:: images/win/_02.gif
|
9. The boot2docker virtual machine should boot now.
|
||||||
: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
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
Let’s 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
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Let’s 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 !
|
|
||||||
|
|
||||||
Running Docker
|
Running Docker
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
First you have to be root in order to run docker. Simply run the
|
boot2docker will log you in automatically so you can start using Docker right
|
||||||
following command:
|
away.
|
||||||
|
|
||||||
.. code-block:: bash
|
Let's try the “hello world” example. Run
|
||||||
|
|
||||||
sudo su
|
|
||||||
|
|
||||||
You are now ready for the docker’s “hello world” example. Run
|
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
docker run busybox echo hello world
|
docker run busybox echo hello world
|
||||||
|
|
||||||
.. image:: images/win/run_04.gif
|
This will download the small busybox image and print hello world.
|
||||||
:alt: run docker
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
All done!
|
|
||||||
|
|
||||||
Now you can continue with the :ref:`hello_world` example.
|
Observations
|
||||||
|
------------
|
||||||
|
|
||||||
Troubleshooting
|
Persistent storage
|
||||||
---------------
|
``````````````````
|
||||||
|
|
||||||
VM does not boot
|
The virtual machine created above lacks any persistent data storage. All images
|
||||||
````````````````
|
and containers will be lost when shutting down or rebooting the VM.
|
||||||
|
|
||||||
.. 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`
|
|
||||||
|
|
|
@ -118,6 +118,7 @@ Create a container
|
||||||
"User":"",
|
"User":"",
|
||||||
"Memory":0,
|
"Memory":0,
|
||||||
"MemorySwap":0,
|
"MemorySwap":0,
|
||||||
|
"CpuShares":0,
|
||||||
"AttachStdin":false,
|
"AttachStdin":false,
|
||||||
"AttachStdout":true,
|
"AttachStdout":true,
|
||||||
"AttachStderr":true,
|
"AttachStderr":true,
|
||||||
|
@ -153,7 +154,15 @@ Create a container
|
||||||
"Warnings":[]
|
"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_-]+``.
|
:query name: Assign the specified name to the container. Must match ``/?[a-zA-Z0-9_-]+``.
|
||||||
:statuscode 201: no error
|
:statuscode 201: no error
|
||||||
:statuscode 404: no such container
|
:statuscode 404: no such container
|
||||||
|
@ -394,7 +403,11 @@ Start a container
|
||||||
HTTP/1.1 204 No Content
|
HTTP/1.1 204 No Content
|
||||||
Content-Type: text/plain
|
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 204: no error
|
||||||
:statuscode 404: no such container
|
:statuscode 404: no such container
|
||||||
:statuscode 500: server error
|
:statuscode 500: server error
|
||||||
|
|
|
@ -118,6 +118,7 @@ Create a container
|
||||||
"User":"",
|
"User":"",
|
||||||
"Memory":0,
|
"Memory":0,
|
||||||
"MemorySwap":0,
|
"MemorySwap":0,
|
||||||
|
"CpuShares":0,
|
||||||
"AttachStdin":false,
|
"AttachStdin":false,
|
||||||
"AttachStdout":true,
|
"AttachStdout":true,
|
||||||
"AttachStderr":true,
|
"AttachStderr":true,
|
||||||
|
@ -153,7 +154,15 @@ Create a container
|
||||||
"Warnings":[]
|
"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_-]+``.
|
:query name: Assign the specified name to the container. Must match ``/?[a-zA-Z0-9_-]+``.
|
||||||
:statuscode 201: no error
|
:statuscode 201: no error
|
||||||
:statuscode 404: no such container
|
:statuscode 404: no such container
|
||||||
|
@ -394,7 +403,11 @@ Start a container
|
||||||
HTTP/1.1 204 No Content
|
HTTP/1.1 204 No Content
|
||||||
Content-Type: text/plain
|
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 204: no error
|
||||||
:statuscode 404: no such container
|
:statuscode 404: no such container
|
||||||
:statuscode 500: server error
|
:statuscode 500: server error
|
||||||
|
|
|
@ -74,7 +74,7 @@ When you're done with your build, you're ready to look into
|
||||||
2. Format
|
2. Format
|
||||||
=========
|
=========
|
||||||
|
|
||||||
The Dockerfile format is quite simple:
|
Here is the format of the Dockerfile:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ Commands
|
||||||
-p, --pidfile="/var/run/docker.pid": Path to use for daemon PID file
|
-p, --pidfile="/var/run/docker.pid": Path to use for daemon PID file
|
||||||
-r, --restart=true: Restart previously running containers
|
-r, --restart=true: Restart previously running containers
|
||||||
-s, --storage-driver="": Force the docker runtime to use a specific storage driver
|
-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
|
-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
|
--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
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
"io"
|
"io"
|
||||||
|
@ -136,6 +137,48 @@ func (eng *Engine) Job(name string, args ...string) *Job {
|
||||||
return 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) {
|
func (eng *Engine) Logf(format string, args ...interface{}) (n int, err error) {
|
||||||
if os.Getenv("TEST") == "" {
|
if os.Getenv("TEST") == "" {
|
||||||
prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))
|
prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"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)
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,13 @@ func (env *Env) Exists(key string) bool {
|
||||||
return exists
|
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) {
|
func (env *Env) GetBool(key string) (value bool) {
|
||||||
s := strings.ToLower(strings.Trim(env.Get(key), " \t"))
|
s := strings.ToLower(strings.Trim(env.Get(key), " \t"))
|
||||||
if s == "" || s == "0" || s == "no" || s == "false" || s == "none" {
|
if s == "" || s == "0" || s == "no" || s == "false" || s == "none" {
|
||||||
|
|
|
@ -74,7 +74,7 @@ func (job *Job) Run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if job.status != 0 {
|
if job.status != 0 {
|
||||||
return fmt.Errorf("%s: %s", job.Name, errorMessage)
|
return fmt.Errorf("%s", errorMessage)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,10 @@ func (job *Job) String() string {
|
||||||
return fmt.Sprintf("%s.%s%s", job.Eng, job.CallString(), job.StatusString())
|
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) {
|
func (job *Job) EnvExists(key string) (value bool) {
|
||||||
return job.env.Exists(key)
|
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 {
|
func (job *Job) Errorf(format string, args ...interface{}) Status {
|
||||||
|
if format[len(format)-1] != '\n' {
|
||||||
|
format = format + "\n"
|
||||||
|
}
|
||||||
fmt.Fprintf(job.Stderr, format, args...)
|
fmt.Fprintf(job.Stderr, format, args...)
|
||||||
return StatusErr
|
return StatusErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *Job) Error(err error) Status {
|
func (job *Job) Error(err error) Status {
|
||||||
fmt.Fprintf(job.Stderr, "%s", err)
|
fmt.Fprintf(job.Stderr, "%s\n", err)
|
||||||
return StatusErr
|
return StatusErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,9 +301,8 @@ func (d *driver) Info(id string) execdriver.Info {
|
||||||
func (d *driver) GetPidsForContainer(id string) ([]int, error) {
|
func (d *driver) GetPidsForContainer(id string) ([]int, error) {
|
||||||
pids := []int{}
|
pids := []int{}
|
||||||
|
|
||||||
// memory is chosen randomly, any cgroup used by docker works
|
// cpu is chosen because it is the only non optional subsystem in cgroups
|
||||||
subsystem := "memory"
|
subsystem := "cpu"
|
||||||
|
|
||||||
cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
|
cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pids, err
|
return pids, err
|
||||||
|
|
|
@ -12,5 +12,5 @@ bundle_test_integration() {
|
||||||
# this "grep" hides some really irritating warnings that "go test -coverpkg"
|
# this "grep" hides some really irritating warnings that "go test -coverpkg"
|
||||||
# spews when it is given packages that aren't used
|
# spews when it is given packages that aren't used
|
||||||
bundle_test_integration 2>&1 \
|
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
|
| tee $DEST/test.log
|
||||||
|
|
|
@ -123,19 +123,8 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBaseImage() {
|
func setupBaseImage() {
|
||||||
eng, err := engine.New(unitTestStoreBase)
|
eng := newTestEngine(log.New(os.Stderr, "", 0), false, unitTestStoreBase)
|
||||||
if err != nil {
|
job := eng.Job("inspect", unitTestImageName, "image")
|
||||||
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")
|
|
||||||
img, _ := job.Stdout.AddEnv()
|
img, _ := job.Stdout.AddEnv()
|
||||||
// If the unit test is not found, try to download it.
|
// If the unit test is not found, try to download it.
|
||||||
if err := job.Run(); err != nil || img.Get("id") != unitTestImageID {
|
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
|
// Here are are simulating a docker restart - that is, reloading all containers
|
||||||
// from scratch
|
// from scratch
|
||||||
root := eng.Root()
|
eng = newTestEngine(t, false, 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime2 := mkRuntimeFromEngine(eng, t)
|
runtime2 := mkRuntimeFromEngine(eng, t)
|
||||||
if len(runtime2.List()) != 2 {
|
if len(runtime2.List()) != 2 {
|
||||||
t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
|
t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
|
||||||
|
@ -612,22 +590,14 @@ func TestRestore(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReloadContainerLinks(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)
|
root, err := newTestDirectory(unitTestStoreBase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
eng, err := engine.New(root)
|
// FIXME: here we don't use NewTestEngine because it calls initserver with Autorestart=false,
|
||||||
if err != nil {
|
// and we want to set it to true.
|
||||||
t.Fatal(err)
|
|
||||||
}
|
eng := newTestEngine(t, true, root)
|
||||||
job := eng.Job("initserver")
|
|
||||||
job.Setenv("Root", eng.Root())
|
|
||||||
job.SetenvBool("Autorestart", true)
|
|
||||||
if err := job.Run(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime1 := mkRuntimeFromEngine(eng, t)
|
runtime1 := mkRuntimeFromEngine(eng, t)
|
||||||
defer nuke(runtime1)
|
defer nuke(runtime1)
|
||||||
|
@ -668,17 +638,7 @@ func TestReloadContainerLinks(t *testing.T) {
|
||||||
|
|
||||||
// Here are are simulating a docker restart - that is, reloading all containers
|
// Here are are simulating a docker restart - that is, reloading all containers
|
||||||
// from scratch
|
// from scratch
|
||||||
eng, err = engine.New(root)
|
eng = newTestEngine(t, false, 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime2 := mkRuntimeFromEngine(eng, t)
|
runtime2 := mkRuntimeFromEngine(eng, t)
|
||||||
if len(runtime2.List()) != 2 {
|
if len(runtime2.List()) != 2 {
|
||||||
t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
|
t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
|
||||||
|
|
|
@ -2,7 +2,6 @@ package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/dotcloud/docker"
|
"github.com/dotcloud/docker"
|
||||||
"github.com/dotcloud/docker/engine"
|
|
||||||
"github.com/dotcloud/docker/runconfig"
|
"github.com/dotcloud/docker/runconfig"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -258,20 +257,7 @@ func TestRestartKillWait(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
eng, err = engine.New(eng.Root())
|
eng = newTestEngine(t, false, 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
srv = mkServerFromEngine(eng, t)
|
srv = mkServerFromEngine(eng, t)
|
||||||
|
|
||||||
job = srv.Eng.Job("containers")
|
job = srv.Eng.Job("containers")
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dotcloud/docker"
|
"github.com/dotcloud/docker"
|
||||||
|
"github.com/dotcloud/docker/builtins"
|
||||||
"github.com/dotcloud/docker/engine"
|
"github.com/dotcloud/docker/engine"
|
||||||
"github.com/dotcloud/docker/runconfig"
|
"github.com/dotcloud/docker/runconfig"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
|
@ -27,26 +28,12 @@ import (
|
||||||
// Create a temporary runtime suitable for unit testing.
|
// Create a temporary runtime suitable for unit testing.
|
||||||
// Call t.Fatal() at the first error.
|
// Call t.Fatal() at the first error.
|
||||||
func mkRuntime(f utils.Fataler) *docker.Runtime {
|
func mkRuntime(f utils.Fataler) *docker.Runtime {
|
||||||
root, err := newTestDirectory(unitTestStoreBase)
|
eng := newTestEngine(f, false, "")
|
||||||
if err != nil {
|
return mkRuntimeFromEngine(eng, f)
|
||||||
f.Fatal(err)
|
// FIXME:
|
||||||
}
|
// [...]
|
||||||
config := &docker.DaemonConfig{
|
// Mtu: docker.GetDefaultNetworkMtu(),
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNamedTestContainer(eng *engine.Engine, config *runconfig.Config, f utils.Fataler, name string) (shortId string) {
|
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
|
return runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestEngine(t utils.Fataler) *engine.Engine {
|
func newTestEngine(t utils.Fataler, autorestart bool, root string) *engine.Engine {
|
||||||
root, err := newTestDirectory(unitTestStoreBase)
|
if root == "" {
|
||||||
if err != nil {
|
if dir, err := newTestDirectory(unitTestStoreBase); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
} else {
|
||||||
|
root = dir
|
||||||
|
}
|
||||||
}
|
}
|
||||||
eng, err := engine.New(root)
|
eng, err := engine.New(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// Load default plugins
|
// Load default plugins
|
||||||
|
builtins.Register(eng)
|
||||||
// (This is manually copied and modified from main() until we have a more generic plugin system)
|
// (This is manually copied and modified from main() until we have a more generic plugin system)
|
||||||
job := eng.Job("initserver")
|
job := eng.Job("initserver")
|
||||||
job.Setenv("Root", root)
|
job.Setenv("Root", root)
|
||||||
job.SetenvBool("AutoRestart", false)
|
job.SetenvBool("AutoRestart", autorestart)
|
||||||
// TestGetEnabledCors and TestOptionsRoute require EnableCors=true
|
// TestGetEnabledCors and TestOptionsRoute require EnableCors=true
|
||||||
job.SetenvBool("EnableCors", true)
|
job.SetenvBool("EnableCors", true)
|
||||||
if err := job.Run(); err != nil {
|
if err := job.Run(); err != nil {
|
||||||
|
@ -207,6 +198,10 @@ func NewTestEngine(t utils.Fataler) *engine.Engine {
|
||||||
return eng
|
return eng
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTestEngine(t utils.Fataler) *engine.Engine {
|
||||||
|
return newTestEngine(t, false, "")
|
||||||
|
}
|
||||||
|
|
||||||
func newTestDirectory(templateDir string) (dir string, err error) {
|
func newTestDirectory(templateDir string) (dir string, err error) {
|
||||||
return utils.TestDirectory(templateDir)
|
return utils.TestDirectory(templateDir)
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ func (l *Link) ToEnv() []string {
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
continue
|
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" {
|
if parts[0] == "HOME" || parts[0] == "PATH" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,6 @@ var (
|
||||||
currentInterfaces = make(map[string]*networkInterface)
|
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 {
|
func InitDriver(job *engine.Job) engine.Status {
|
||||||
var (
|
var (
|
||||||
network *net.IPNet
|
network *net.IPNet
|
||||||
|
|
13
runtime.go
13
runtime.go
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/dotcloud/docker/engine"
|
"github.com/dotcloud/docker/engine"
|
||||||
"github.com/dotcloud/docker/execdriver"
|
"github.com/dotcloud/docker/execdriver"
|
||||||
"github.com/dotcloud/docker/execdriver/docker"
|
"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"
|
||||||
"github.com/dotcloud/docker/graphdriver/aufs"
|
"github.com/dotcloud/docker/graphdriver/aufs"
|
||||||
_ "github.com/dotcloud/docker/graphdriver/btrfs"
|
_ "github.com/dotcloud/docker/graphdriver/btrfs"
|
||||||
|
@ -704,7 +704,16 @@ func NewRuntimeFromDirectory(config *DaemonConfig, eng *engine.Engine) (*Runtime
|
||||||
|
|
||||||
sysInfo := sysinfo.New(false)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,14 +34,10 @@ func (srv *Server) Close() error {
|
||||||
return srv.runtime.Close()
|
return srv.runtime.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
engine.Register("initserver", jobInitServer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// jobInitApi runs the remote api server `srv` as a daemon,
|
// 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.
|
// 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.
|
// 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")
|
job.Logf("Creating server")
|
||||||
srv, err := NewServer(job.Eng, DaemonConfigFromJob(job))
|
srv, err := NewServer(job.Eng, DaemonConfigFromJob(job))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,11 +7,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func GetVersion(job *engine.Job) engine.Status {
|
||||||
engine.Register("version", jobVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func jobVersion(job *engine.Job) engine.Status {
|
|
||||||
if _, err := dockerVersion().WriteTo(job.Stdout); err != nil {
|
if _, err := dockerVersion().WriteTo(job.Stdout); err != nil {
|
||||||
job.Errorf("%s", err)
|
job.Errorf("%s", err)
|
||||||
return engine.StatusErr
|
return engine.StatusErr
|
||||||
|
|
Loading…
Reference in New Issue