mirror of https://github.com/docker/docs.git
merge from master
This commit is contained in:
commit
18519f12ae
|
@ -1,4 +1,4 @@
|
||||||
package commands
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
@ -6,7 +6,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker"
|
|
||||||
"github.com/dotcloud/docker/auth"
|
"github.com/dotcloud/docker/auth"
|
||||||
"github.com/dotcloud/docker/fs"
|
"github.com/dotcloud/docker/fs"
|
||||||
"github.com/dotcloud/docker/future"
|
"github.com/dotcloud/docker/future"
|
||||||
|
@ -24,7 +23,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "0.0.1"
|
const VERSION = "0.0.2"
|
||||||
|
|
||||||
func (srv *Server) Name() string {
|
func (srv *Server) Name() string {
|
||||||
return "docker"
|
return "docker"
|
||||||
|
@ -589,7 +588,7 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
||||||
if !*quiet {
|
if !*quiet {
|
||||||
command := fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
|
command := fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
|
||||||
if !*fl_full {
|
if !*fl_full {
|
||||||
command = docker.Trunc(command, 20)
|
command = Trunc(command, 20)
|
||||||
}
|
}
|
||||||
for idx, field := range []string{
|
for idx, field := range []string{
|
||||||
/* ID */ container.Id,
|
/* ID */ container.Id,
|
||||||
|
@ -780,10 +779,10 @@ func (srv *Server) CmdLogs(stdin io.ReadCloser, stdout io.Writer, args ...string
|
||||||
return errors.New("No such container: " + cmd.Arg(0))
|
return errors.New("No such container: " + cmd.Arg(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) CreateContainer(img *fs.Image, ports []int, user string, tty bool, openStdin bool, memory int64, comment string, cmd string, args ...string) (*docker.Container, error) {
|
func (srv *Server) CreateContainer(img *fs.Image, ports []int, user string, tty bool, openStdin bool, memory int64, comment string, cmd string, args ...string) (*Container, error) {
|
||||||
id := future.RandomId()[:8]
|
id := future.RandomId()[:8]
|
||||||
container, err := srv.containers.Create(id, cmd, args, img,
|
container, err := srv.containers.Create(id, cmd, args, img,
|
||||||
&docker.Config{
|
&Config{
|
||||||
Hostname: id,
|
Hostname: id,
|
||||||
Ports: ports,
|
Ports: ports,
|
||||||
User: user,
|
User: user,
|
||||||
|
@ -984,12 +983,12 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() (*Server, error) {
|
func NewServer() (*Server, error) {
|
||||||
future.Seed()
|
future.Seed()
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, err
|
// return nil, err
|
||||||
// }
|
// }
|
||||||
containers, err := docker.New()
|
containers, err := New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1040,6 +1039,6 @@ func (srv *Server) CmdWeb(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
containers *docker.Docker
|
containers *Docker
|
||||||
images *fs.Store
|
images *fs.Store
|
||||||
}
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
The `contrib` directory contains scripts, images, and other helpful things
|
||||||
|
which are not part of the core docker distribution. Please note that they
|
||||||
|
could be out of date, since they do not receive the same attention as the
|
||||||
|
rest of the repository.
|
|
@ -38,14 +38,14 @@ fi
|
||||||
echo "Downloading docker binary and uncompressing into /usr/local/bin..."
|
echo "Downloading docker binary and uncompressing into /usr/local/bin..."
|
||||||
curl -s http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz |
|
curl -s http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz |
|
||||||
tar -C /usr/local/bin --strip-components=1 -zxf- \
|
tar -C /usr/local/bin --strip-components=1 -zxf- \
|
||||||
docker-master/docker docker-master/dockerd
|
docker-master/docker
|
||||||
|
|
||||||
if [ -f /etc/init/dockerd.conf ]
|
if [ -f /etc/init/dockerd.conf ]
|
||||||
then
|
then
|
||||||
echo "Upstart script already exists."
|
echo "Upstart script already exists."
|
||||||
else
|
else
|
||||||
echo "Creating /etc/init/dockerd.conf..."
|
echo "Creating /etc/init/dockerd.conf..."
|
||||||
echo "exec /usr/local/bin/dockerd" > /etc/init/dockerd.conf
|
echo "exec /usr/local/bin/docker -d" > /etc/init/dockerd.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Starting dockerd..."
|
echo "Starting dockerd..."
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Generate a very minimal filesystem based on busybox-static,
|
||||||
|
# and load it into the local docker under the name "busybox".
|
||||||
|
|
||||||
|
BUSYBOX=$(which busybox)
|
||||||
|
[ "$BUSYBOX" ] || {
|
||||||
|
echo "Sorry, I could not locate busybox."
|
||||||
|
echo "Try 'apt-get install busybox-static'?"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
ROOTFS=/tmp/rootfs-busybox-$$-$RANDOM
|
||||||
|
mkdir $ROOTFS
|
||||||
|
cd $ROOTFS
|
||||||
|
|
||||||
|
mkdir bin etc dev dev/pts lib proc sys tmp
|
||||||
|
touch etc/resolv.conf
|
||||||
|
cp /etc/nsswitch.conf etc/nsswitch.conf
|
||||||
|
echo root:x:0:0:root:/:/bin/sh > etc/passwd
|
||||||
|
echo root:x:0: > etc/group
|
||||||
|
ln -s lib lib64
|
||||||
|
ln -s bin sbin
|
||||||
|
cp $BUSYBOX bin
|
||||||
|
for X in $(busybox --list)
|
||||||
|
do
|
||||||
|
ln -s busybox bin/$X
|
||||||
|
done
|
||||||
|
rm bin/init
|
||||||
|
ln bin/busybox bin/init
|
||||||
|
cp /lib/x86_64-linux-gnu/lib{pthread,c,dl,nsl,nss_*}.so.* lib
|
||||||
|
cp /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 lib
|
||||||
|
for X in console null ptmx random stdin stdout stderr tty urandom zero
|
||||||
|
do
|
||||||
|
cp -a /dev/$X dev
|
||||||
|
done
|
||||||
|
|
||||||
|
tar -cf- . | docker put busybox
|
||||||
|
docker run -i -a -u root busybox /bin/echo Success.
|
||||||
|
|
19
docker.go
19
docker.go
|
@ -76,10 +76,9 @@ func (docker *Docker) Destroy(container *Container) error {
|
||||||
if err := container.Mountpoint.Umount(); err != nil {
|
if err := container.Mountpoint.Umount(); err != nil {
|
||||||
log.Printf("Unable to umount container %v: %v", container.Id, err)
|
log.Printf("Unable to umount container %v: %v", container.Id, err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if err := container.Mountpoint.Deregister(); err != nil {
|
if err := container.Mountpoint.Deregister(); err != nil {
|
||||||
log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
|
log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err := os.RemoveAll(container.Root); err != nil {
|
if err := os.RemoveAll(container.Root); err != nil {
|
||||||
log.Printf("Unable to remove filesystem for %v: %v", container.Id, err)
|
log.Printf("Unable to remove filesystem for %v: %v", container.Id, err)
|
||||||
|
@ -109,6 +108,12 @@ func New() (*Docker, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFromDirectory(root string) (*Docker, error) {
|
func NewFromDirectory(root string) (*Docker, error) {
|
||||||
|
docker_repo := path.Join(root, "containers")
|
||||||
|
|
||||||
|
if err := os.MkdirAll(docker_repo, 0700); err != nil && !os.IsExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
store, err := fs.New(path.Join(root, "images"))
|
store, err := fs.New(path.Join(root, "images"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -120,16 +125,12 @@ func NewFromDirectory(root string) (*Docker, error) {
|
||||||
|
|
||||||
docker := &Docker{
|
docker := &Docker{
|
||||||
root: root,
|
root: root,
|
||||||
repository: path.Join(root, "containers"),
|
repository: docker_repo,
|
||||||
containers: list.New(),
|
containers: list.New(),
|
||||||
Store: store,
|
Store: store,
|
||||||
networkManager: netManager,
|
networkManager: netManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(docker.repository, 0700); err != nil && !os.IsExist(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := docker.restore(); err != nil {
|
if err := docker.restore(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/dotcloud/docker"
|
"github.com/dotcloud/docker"
|
||||||
"github.com/dotcloud/docker/commands"
|
|
||||||
"github.com/dotcloud/docker/future"
|
"github.com/dotcloud/docker/future"
|
||||||
"github.com/dotcloud/docker/rcli"
|
"github.com/dotcloud/docker/rcli"
|
||||||
"github.com/dotcloud/docker/term"
|
"github.com/dotcloud/docker/term"
|
||||||
|
@ -36,7 +35,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func daemon() error {
|
func daemon() error {
|
||||||
service, err := commands.New()
|
service, err := docker.NewServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -78,7 +77,7 @@ func runCommand(args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
service, err := commands.New()
|
service, err := docker.NewServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,28 @@ import (
|
||||||
"github.com/dotcloud/docker/fs"
|
"github.com/dotcloud/docker/fs"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
|
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
|
||||||
|
const unitTestImageName string = "busybox"
|
||||||
|
|
||||||
|
var unitTestStoreBase string
|
||||||
|
var srv *Server
|
||||||
|
|
||||||
func nuke(docker *Docker) error {
|
func nuke(docker *Docker) error {
|
||||||
return os.RemoveAll(docker.root)
|
return os.RemoveAll(docker.root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CopyDirectory(source, dest string) error {
|
||||||
|
if _, err := exec.Command("cp", "-ra", source, dest).Output(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func layerArchive(tarfile string) (io.Reader, error) {
|
func layerArchive(tarfile string) (io.Reader, error) {
|
||||||
// FIXME: need to close f somewhere
|
// FIXME: need to close f somewhere
|
||||||
f, err := os.Open(tarfile)
|
f, err := os.Open(tarfile)
|
||||||
|
@ -28,15 +39,29 @@ func init() {
|
||||||
// Hack to run sys init during unit testing
|
// Hack to run sys init during unit testing
|
||||||
if SelfPath() == "/sbin/init" {
|
if SelfPath() == "/sbin/init" {
|
||||||
SysInit()
|
SysInit()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the unit test image is there
|
// Create a temp directory
|
||||||
if _, err := os.Stat(testLayerPath); err != nil {
|
root, err := ioutil.TempDir("", "docker-test")
|
||||||
if !os.IsNotExist(err) {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Fatalf("Unit test base image not found. Please fix the problem by running \"debootstrap --arch=amd64 quantal %v\"", testLayerPath)
|
unitTestStoreBase = root
|
||||||
return
|
|
||||||
|
// Make it our Store root
|
||||||
|
docker, err := NewFromDirectory(root)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Create the "Server"
|
||||||
|
srv := &Server{
|
||||||
|
images: docker.Store,
|
||||||
|
containers: docker,
|
||||||
|
}
|
||||||
|
// Retrieve the Image
|
||||||
|
if err := srv.CmdImport(os.Stdin, os.Stdout, unitTestImageName); err != nil {
|
||||||
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,19 +70,19 @@ func newTestDocker() (*Docker, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := os.Remove(root); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := CopyDirectory(unitTestStoreBase, root); err != nil {
|
||||||
|
panic(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
docker, err := NewFromDirectory(root)
|
docker, err := NewFromDirectory(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if layer, err := layerArchive(testLayerPath); err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
_, err = docker.Store.Create(layer, nil, "docker-ut", "unit tests")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return docker, nil
|
return docker, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,25 +256,22 @@ func TestGet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRestore(t *testing.T) {
|
func TestRestore(t *testing.T) {
|
||||||
|
|
||||||
root, err := ioutil.TempDir("", "docker-test")
|
root, err := ioutil.TempDir("", "docker-test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
if err := os.Remove(root); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := CopyDirectory(unitTestStoreBase, root); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
docker1, err := NewFromDirectory(root)
|
docker1, err := NewFromDirectory(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer nuke(docker1)
|
|
||||||
|
|
||||||
if layer, err := layerArchive(testLayerPath); err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
_, err = docker1.Store.Create(layer, nil, "docker-ut", "unit tests")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a container with one instance of docker
|
// Create a container with one instance of docker
|
||||||
container1, err := docker1.Create(
|
container1, err := docker1.Create(
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -93,7 +93,7 @@ func (store *LayerStore) AddLayer(id string, archive Archive) (string, error) {
|
||||||
return "", fmt.Errorf("Mktemp failed: %s", err)
|
return "", fmt.Errorf("Mktemp failed: %s", err)
|
||||||
}
|
}
|
||||||
if err := Untar(archive, tmp); err != nil {
|
if err := Untar(archive, tmp); err != nil {
|
||||||
return "", nil
|
return "", err
|
||||||
}
|
}
|
||||||
layer := store.layerPath(id)
|
layer := store.layerPath(id)
|
||||||
if !store.Exists(id) {
|
if !store.Exists(id) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ func (store *Store) Remove(img *Image) error {
|
||||||
|
|
||||||
func (store *Store) List(pth string) ([]*Image, error) {
|
func (store *Store) List(pth string) ([]*Image, error) {
|
||||||
pth = path.Clean(pth)
|
pth = path.Clean(pth)
|
||||||
images, err := store.orm.Select(Image{}, "select images.* from images, paths where Path=? and paths.Image=images.Id", pth)
|
images, err := store.orm.Select(Image{}, "select images.* from images, paths where Path=? and paths.Image=images.Id order by images.Created desc", pth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,25 +101,30 @@ func Download(url string, stderr io.Writer) (*http.Response, error) {
|
||||||
|
|
||||||
// Reader with progress bar
|
// Reader with progress bar
|
||||||
type progressReader struct {
|
type progressReader struct {
|
||||||
reader io.ReadCloser // Stream to read from
|
reader io.ReadCloser // Stream to read from
|
||||||
output io.Writer // Where to send progress bar to
|
output io.Writer // Where to send progress bar to
|
||||||
read_total int // Expected stream length (bytes)
|
read_total int // Expected stream length (bytes)
|
||||||
read_progress int // How much has been read so far (bytes)
|
read_progress int // How much has been read so far (bytes)
|
||||||
last_update int // How many bytes read at least update
|
last_update int // How many bytes read at least update
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *progressReader) Read(p []byte) (n int, err error) {
|
func (r *progressReader) Read(p []byte) (n int, err error) {
|
||||||
read, err := io.ReadCloser(r.reader).Read(p)
|
read, err := io.ReadCloser(r.reader).Read(p)
|
||||||
r.read_progress += read
|
r.read_progress += read
|
||||||
|
|
||||||
// Only update progress for every 1% read
|
// Only update progress for every 1% read
|
||||||
update_every := int(0.01 * float64(r.read_total))
|
update_every := int(0.01 * float64(r.read_total))
|
||||||
if r.read_progress - r.last_update > update_every {
|
if r.read_progress-r.last_update > update_every || r.read_progress == r.read_total {
|
||||||
fmt.Fprintf(r.output, "%d/%d (%.0f%%)\r",
|
fmt.Fprintf(r.output, "%d/%d (%.0f%%)\r",
|
||||||
r.read_progress,
|
r.read_progress,
|
||||||
r.read_total,
|
r.read_total,
|
||||||
float64(r.read_progress) / float64(r.read_total) * 100)
|
float64(r.read_progress)/float64(r.read_total)*100)
|
||||||
r.last_update = r.read_progress
|
r.last_update = r.read_progress
|
||||||
}
|
}
|
||||||
|
// Send newline when complete
|
||||||
|
if err == io.EOF {
|
||||||
|
fmt.Fprintf(r.output, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
return read, err
|
return read, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue