1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge branch 'graph' of github.com:dotcloud/docker into graph

This commit is contained in:
creack 2013-03-22 04:35:19 -07:00
commit db8f2a1a9d
13 changed files with 166 additions and 100 deletions

112
README.md
View file

@ -1,9 +1,9 @@
Docker: the Linux container runtime
===================================
Docker complements LXC with a high-level API with operates at the process level. It runs unix processes with strong guarantees of isolation and repeatability across servers.
Docker complements LXC with a high-level API which operates at the process level. It runs unix processes with strong guarantees of isolation and repeatability across servers.
Is is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
Docker is a great building block for automating distributed systems: large-scale web deployments, database clusters, continuous deployment systems, private PaaS, service-oriented architectures, etc.
<img src="http://bricks.argz.com/bricksfiles/lego/07000/7823/012.jpg"/>
@ -27,7 +27,7 @@ Notable features
* Copy-on-write: root filesystems are created using copy-on-write, which makes deployment extremeley fast, memory-cheap and disk-cheap.
* Logging: the standard streams (stdout/stderr/stdin) of each process container is collected and logged for real-time or batch retrieval.
* Logging: the standard streams (stdout/stderr/stdin) of each process container are collected and logged for real-time or batch retrieval.
* Change management: changes to a container's filesystem can be committed into a new image and re-used to create more containers. No templating or manual configuration required.
@ -58,28 +58,28 @@ Installing on Ubuntu 12.04 and 12.10
1. Install dependencies:
```bash
sudo apt-get install lxc wget bsdtar curl
sudo apt-get install linux-image-extra-`uname -r`
```
```bash
sudo apt-get install lxc wget bsdtar curl
sudo apt-get install linux-image-extra-`uname -r`
```
The `linux-image-extra` package is needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.
The `linux-image-extra` package is needed on standard Ubuntu EC2 AMIs in order to install the aufs kernel module.
2. Install the latest docker binary:
```bash
wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz
tar -xf docker-master.tgz
```
```bash
wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz
tar -xf docker-master.tgz
```
3. Run your first container!
```bash
cd docker-master
sudo ./docker run -a -i -t base /bin/bash
```
```bash
cd docker-master
sudo ./docker run -a -i -t base /bin/bash
```
Consider adding docker to your `PATH` for simplicity.
Consider adding docker to your `PATH` for simplicity.
Installing on other Linux distributions
---------------------------------------
@ -99,12 +99,12 @@ with VirtualBox as well as on Amazon EC2. Vagrant 1.1 is required for
EC2, but deploying is as simple as:
```bash
$ export AWS_ACCESS_KEY_ID=xxx \
AWS_SECRET_ACCESS_KEY=xxx \
AWS_KEYPAIR_NAME=xxx \
AWS_SSH_PRIVKEY=xxx
$ vagrant plugin install vagrant-aws
$ vagrant up --provider=aws
$ export AWS_ACCESS_KEY_ID=xxx \
AWS_SECRET_ACCESS_KEY=xxx \
AWS_KEYPAIR_NAME=xxx \
AWS_SSH_PRIVKEY=xxx
$ vagrant plugin install vagrant-aws
$ vagrant up --provider=aws
```
The environment variables are:
@ -115,11 +115,11 @@ The environment variables are:
* `AWS_SSH_PRIVKEY` - The path to the private key for the named keypair
For VirtualBox, you can simply ignore setting any of the environment
variables and omit the ``provider`` flag. VirtualBox is still supported with
Vagrant <= 1.1:
variables and omit the `provider` flag. VirtualBox is still supported with
Vagrant &lt;= 1.1:
```bash
$ vagrant up
$ vagrant up
```
@ -131,12 +131,12 @@ Running an interactive shell
----------------------------
```bash
# Download a base image
docker import base
# Download a base image
docker import base
# Run an interactive shell in the base image,
# allocate a tty, attach stdin and stdout
docker run -a -i -t base /bin/bash
# Run an interactive shell in the base image,
# allocate a tty, attach stdin and stdout
docker run -a -i -t base /bin/bash
```
@ -144,17 +144,17 @@ Starting a long-running worker process
--------------------------------------
```bash
# Run docker in daemon mode
(docker -d || echo "Docker daemon already running") &
# Run docker in daemon mode
(docker -d || echo "Docker daemon already running") &
# Start a very useful long-running process
JOB=$(docker run base /bin/sh -c "while true; do echo Hello world; sleep 1; done")
# Start a very useful long-running process
JOB=$(docker run base /bin/sh -c "while true; do echo Hello world; sleep 1; done")
# Collect the output of the job so far
docker logs $JOB
# Collect the output of the job so far
docker logs $JOB
# Kill the job
docker kill $JOB
# Kill the job
docker kill $JOB
```
@ -162,7 +162,7 @@ Listing all running containers
------------------------------
```bash
docker ps
docker ps
```
@ -170,17 +170,17 @@ Expose a service on a TCP port
------------------------------
```bash
# Expose port 4444 of this container, and tell netcat to listen on it
JOB=$(docker run -p 4444 base /bin/nc -l -p 4444)
# Expose port 4444 of this container, and tell netcat to listen on it
JOB=$(docker run -p 4444 base /bin/nc -l -p 4444)
# Which public port is NATed to my container?
PORT=$(docker port $JOB 4444)
# Which public port is NATed to my container?
PORT=$(docker port $JOB 4444)
# Connect to the public port via the host's public address
echo hello world | nc $(hostname) $PORT
# Connect to the public port via the host's public address
echo hello world | nc $(hostname) $PORT
# Verify that the network connection worked
echo "Daemon received: $(docker logs $JOB)"
# Verify that the network connection worked
echo "Daemon received: $(docker logs $JOB)"
```
Contributing to Docker
@ -195,10 +195,10 @@ Contribution guidelines
We are always thrilled to receive pull requests, and do our best to process them as fast as possible. Not sure if that typo is worth a pull request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be discouraged! If there's a problen with the implementation, hopefully you received feedback on what to improve.
If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve.
We're trying very hard to keep Docker lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature.
However there might be a way to implement that feature *on top of* docker.
However, there might be a way to implement that feature *on top of* docker.
### Discuss your design on the mailing list
@ -207,7 +207,7 @@ you in the right direction, give feedback on your design, and maybe point out if
### Create issues...
Any significant improvement should be documented as a github issue before anybody start working on it.
Any significant improvement should be documented as [a github issue](https://github.com/dotcloud/docker/issues) before anybody starts working on it.
### ...but check for existing issues first!
@ -224,9 +224,9 @@ Golang has a great testing suite built in: use it! Take a look at existing tests
Setting up a dev environment
----------------------------
Instructions that is verified to work on Ubuntu 12.10,
Instructions that have been verified to work on Ubuntu 12.10,
```
```bash
sudo apt-get -y install lxc wget bsdtar curl libsqlite3-dev golang git pkg-config
export GOPATH=~/go/
@ -243,7 +243,7 @@ go install -v github.com/dotcloud/docker/...
Then run the docker daemon,
```
```bash
sudo $GOPATH/bin/docker -d
```
@ -254,9 +254,9 @@ What is a Standard Container?
=============================
Docker defines a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependency, regardless of the underlying machine and the contents of the container.
a format that is self-describing and portable, so that any compliant runtime can run it without extra dependencies, regardless of the underlying machine and the contents of the container.
The spec for Standard Containers is currently work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
The spec for Standard Containers is currently a work in progress, but it is very straightforward. It mostly defines 1) an image format, 2) a set of standard operations, and 3) an execution environment.
A great analogy for this is the shipping container. Just like Standard Containers are a fundamental unit of software delivery, shipping containers (http://bricks.argz.com/ins/7823-1/12) are a fundamental unit of physical delivery.

37
Vagrantfile vendored
View file

@ -1,7 +1,7 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("1") do |config|
def v10(config)
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.
@ -20,7 +20,7 @@ Vagrant.configure("1") do |config|
# via the IP. Host-only networks can talk to the host machine as well as
# any other machines on the same network, but cannot be accessed (through this
# network interface) by any external networks.
# config.vm.network :hostonly, "192.168.33.10"
config.vm.network :hostonly, "192.168.33.10"
# Assign this VM to a bridged network, allowing you to connect directly to a
# network using the host's network device. This makes the VM appear as another
@ -34,6 +34,9 @@ Vagrant.configure("1") do |config|
# Share an additional folder to the guest VM. The first argument is
# an identifier, the second is the path on the guest to mount the
# folder, and the third is the path on the host to the actual folder.
if not File.exist? File.expand_path '~/docker'
Dir.mkdir(File.expand_path '~/docker')
end
config.vm.share_folder "v-data", "~/docker", "~/docker"
# Enable provisioning with Puppet stand alone. Puppet manifests
@ -99,21 +102,29 @@ Vagrant.configure("1") do |config|
# chef.validation_client_name = "ORGNAME-validator"
end
Vagrant.configure("2") do |config|
"#{Vagrant::VERSION}" < "1.1.0" and Vagrant::Config.run do |config|
v10(config)
end
"#{Vagrant::VERSION}" >= "1.1.0" and Vagrant.configure("1") do |config|
v10(config)
end
"#{Vagrant::VERSION}" >= "1.1.0" and Vagrant.configure("2") do |config|
config.vm.provider :aws do |aws|
config.vm.box = "dummy"
config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
config.vm.box = "dummy"
config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
aws.access_key_id = ENV["AWS_ACCESS_KEY_ID"]
aws.secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
aws.keypair_name = ENV["AWS_KEYPAIR_NAME"]
aws.ssh_private_key_path = ENV["AWS_SSH_PRIVKEY"]
aws.region = "us-east-1"
aws.secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
aws.keypair_name = ENV["AWS_KEYPAIR_NAME"]
aws.ssh_private_key_path = ENV["AWS_SSH_PRIVKEY"]
aws.region = "us-east-1"
aws.ami = "ami-1c1e8075"
aws.ssh_username = "vagrant"
aws.instance_type = "t1.micro"
aws.instance_type = "t1.micro"
end
config.vm.provider :virtualbox do |vb|
config.vm.box = "quantal64_3.5.0-25"
config.vm.box_url = "http://get.docker.io/vbox/ubuntu/12.10/quantal64_3.5.0-25.box"
end
config.vm.box = "quantal64_3.5.0-25"
config.vm.box_url = "http://get.docker.io/vbox/ubuntu/12.10/quantal64_3.5.0-25.box"
end
end

View file

@ -391,7 +391,7 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri
// Optionally register the image at REPO/TAG
if repository := cmd.Arg(1); repository != "" {
tag := cmd.Arg(2) // Repository will handle an empty tag properly
if err := srv.runtime.repositories.Set(repository, tag, img.Id); err != nil {
if err := srv.runtime.repositories.Set(repository, tag, img.Id, true); err != nil {
return err
}
}
@ -764,6 +764,19 @@ func (p *ports) Set(value string) error {
return nil
}
func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "tag", "[OPTIONS] IMAGE REPOSITORY [TAG]", "Tag an image into a repository")
force := cmd.Bool("f", false, "Force")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() < 2 {
cmd.Usage()
return nil
}
return srv.runtime.repositories.Set(cmd.Arg(1), cmd.Arg(2), cmd.Arg(0), *force)
}
func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
fl_user := cmd.String("u", "", "Username or UID")

4
docs/README.md Normal file
View file

@ -0,0 +1,4 @@
Docs readme
===========
Let's see if this file shows up as we hope it does.

View file

@ -95,7 +95,8 @@ func getIfaceAddr(name string) (net.Addr, error) {
case len(addrs4) == 0:
return nil, fmt.Errorf("Interface %v has no IP addresses", name)
case len(addrs4) > 1:
return nil, fmt.Errorf("Interface %v has more than 1 IPv4 address", name)
fmt.Printf("Interface %v has more than 1 IPv4 address. Defaulting to using %v\n",
name, (addrs4[0].(*net.IPNet)).IP)
}
return addrs4[0], nil
}
@ -123,6 +124,9 @@ func (mapper *PortMapper) setup() error {
if err := iptables("-t", "nat", "-A", "PREROUTING", "-j", "DOCKER"); err != nil {
return errors.New("Unable to setup port networking: Failed to inject docker in PREROUTING chain")
}
if err := iptables("-t", "nat", "-A", "OUTPUT", "-j", "DOCKER"); err != nil {
return errors.New("Unable to setup port networking: Failed to inject docker in OUTPUT chain")
}
return nil
}

View file

@ -80,7 +80,7 @@ class docker {
owner => "root",
group => "root",
content => template("docker/dockerd.conf"),
require => Exec["fetch-docker"],
require => Exec["copy-docker-bin"],
}
file { "/home/vagrant":

View file

@ -8,5 +8,5 @@ respawn
script
test -f /etc/default/locale && . /etc/default/locale || true
LANG=$LANG LC_ALL=$LANG /usr/local/bin/docker -d
LANG=$LANG LC_ALL=$LANG /usr/local/bin/docker -d >> /var/log/dockerd 2>&1
end script

View file

@ -175,7 +175,7 @@ func (graph *Graph) PullRepository(user, repoName, askedTag string, repositories
if err = graph.PullImage(rev, authConfig); err != nil {
return err
}
if err = repositories.Set(repoName, tag, rev); err != nil {
if err = repositories.Set(repoName, tag, rev, true); err != nil {
return err
}
}

View file

@ -201,7 +201,7 @@ func (runtime *Runtime) Commit(id, repository, tag string) (*Image, error) {
}
// Register the image if needed
if repository != "" {
if err := runtime.repositories.Set(repository, tag, img.Id); err != nil {
if err := runtime.repositories.Set(repository, tag, img.Id, true); err != nil {
return img, err
}
}

11
tags.go
View file

@ -83,7 +83,11 @@ func (store *TagStore) LookupImage(name string) (*Image, error) {
return img, nil
}
func (store *TagStore) Set(repoName, tag, revision string) error {
func (store *TagStore) Set(repoName, tag, imageName string, force bool) error {
img, err := store.LookupImage(imageName)
if err != nil {
return err
}
if tag == "" {
tag = DEFAULT_TAG
}
@ -101,9 +105,12 @@ func (store *TagStore) Set(repoName, tag, revision string) error {
repo = r
} else {
repo = make(map[string]string)
if old, exists := store.Repositories[repoName]; exists && !force {
return fmt.Errorf("Tag %s:%s is already set to %s", repoName, tag, old)
}
store.Repositories[repoName] = repo
}
repo[tag] = revision
repo[tag] = img.Id
return store.Save()
}

View file

@ -114,27 +114,6 @@ func IsTerminal(fd int) bool {
return err == 0
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF
newState.Iflag |= ICRNL
newState.Oflag |= ONLCR
newState.Lflag &^= ECHO | ICANON | ISIG
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err
}
return &oldState, nil
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {

View file

@ -1,8 +1,32 @@
package term
import "syscall"
import (
"syscall"
"unsafe"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
)
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF
newState.Iflag |= ICRNL
newState.Oflag |= ONLCR
newState.Lflag &^= ECHO | ICANON | ISIG
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err
}
return &oldState, nil
}

View file

@ -1,8 +1,32 @@
package term
import "syscall"
import (
"syscall"
"unsafe"
)
const (
getTermios = syscall.TCGETS
setTermios = syscall.TCSETS
)
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= ISTRIP | IXON | IXOFF
newState.Iflag |= ICRNL
newState.Oflag |= ONLCR
newState.Lflag &^= ECHO | ICANON | ISIG
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err
}
return &oldState, nil
}