merge from master

This commit is contained in:
Ken Cochrane 2013-03-14 18:23:45 -07:00
commit 18519f12ae
11 changed files with 129 additions and 280 deletions

View File

@ -1,4 +1,4 @@
package commands
package docker
import (
"bufio"
@ -6,7 +6,6 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/auth"
"github.com/dotcloud/docker/fs"
"github.com/dotcloud/docker/future"
@ -24,7 +23,7 @@ import (
"time"
)
const VERSION = "0.0.1"
const VERSION = "0.0.2"
func (srv *Server) Name() string {
return "docker"
@ -589,7 +588,7 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string)
if !*quiet {
command := fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
if !*fl_full {
command = docker.Trunc(command, 20)
command = Trunc(command, 20)
}
for idx, field := range []string{
/* 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))
}
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]
container, err := srv.containers.Create(id, cmd, args, img,
&docker.Config{
&Config{
Hostname: id,
Ports: ports,
User: user,
@ -984,12 +983,12 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
return nil
}
func New() (*Server, error) {
func NewServer() (*Server, error) {
future.Seed()
// if err != nil {
// return nil, err
// }
containers, err := docker.New()
containers, err := New()
if err != nil {
return nil, err
}
@ -1040,6 +1039,6 @@ func (srv *Server) CmdWeb(stdin io.ReadCloser, stdout io.Writer, args ...string)
}
type Server struct {
containers *docker.Docker
containers *Docker
images *fs.Store
}

4
contrib/README Normal file
View File

@ -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.

4
install.sh → contrib/install.sh Normal file → Executable file
View File

@ -38,14 +38,14 @@ fi
echo "Downloading docker binary and uncompressing into /usr/local/bin..."
curl -s http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz |
tar -C /usr/local/bin --strip-components=1 -zxf- \
docker-master/docker docker-master/dockerd
docker-master/docker
if [ -f /etc/init/dockerd.conf ]
then
echo "Upstart script already exists."
else
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
echo "Starting dockerd..."

40
contrib/mkimage-busybox.sh Executable file
View File

@ -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.

View File

@ -76,10 +76,9 @@ func (docker *Docker) Destroy(container *Container) error {
if err := container.Mountpoint.Umount(); err != nil {
log.Printf("Unable to umount container %v: %v", container.Id, err)
}
if err := container.Mountpoint.Deregister(); err != nil {
log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
}
}
if err := container.Mountpoint.Deregister(); err != nil {
log.Printf("Unable to deregiser mountpoint %v: %v", container.Mountpoint.Root, err)
}
if err := os.RemoveAll(container.Root); err != nil {
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) {
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"))
if err != nil {
return nil, err
@ -120,16 +125,12 @@ func NewFromDirectory(root string) (*Docker, error) {
docker := &Docker{
root: root,
repository: path.Join(root, "containers"),
repository: docker_repo,
containers: list.New(),
Store: store,
networkManager: netManager,
}
if err := os.MkdirAll(docker.repository, 0700); err != nil && !os.IsExist(err) {
return nil, err
}
if err := docker.restore(); err != nil {
return nil, err
}

View File

@ -3,7 +3,6 @@ package main
import (
"flag"
"github.com/dotcloud/docker"
"github.com/dotcloud/docker/commands"
"github.com/dotcloud/docker/future"
"github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/term"
@ -36,7 +35,7 @@ func main() {
}
func daemon() error {
service, err := commands.New()
service, err := docker.NewServer()
if err != nil {
return err
}
@ -78,7 +77,7 @@ func runCommand(args []string) error {
}
}
} else {
service, err := commands.New()
service, err := docker.NewServer()
if err != nil {
return err
}

View File

@ -4,17 +4,28 @@ import (
"github.com/dotcloud/docker/fs"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"testing"
)
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
const unitTestImageName string = "busybox"
var unitTestStoreBase string
var srv *Server
func nuke(docker *Docker) error {
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) {
// FIXME: need to close f somewhere
f, err := os.Open(tarfile)
@ -28,15 +39,29 @@ func init() {
// Hack to run sys init during unit testing
if SelfPath() == "/sbin/init" {
SysInit()
return
}
// Make sure the unit test image is there
if _, err := os.Stat(testLayerPath); err != nil {
if !os.IsNotExist(err) {
panic(err)
}
log.Fatalf("Unit test base image not found. Please fix the problem by running \"debootstrap --arch=amd64 quantal %v\"", testLayerPath)
return
// Create a temp directory
root, err := ioutil.TempDir("", "docker-test")
if err != nil {
panic(err)
}
unitTestStoreBase = root
// 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 {
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)
if err != nil {
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
}
@ -231,25 +256,22 @@ func TestGet(t *testing.T) {
}
func TestRestore(t *testing.T) {
root, err := ioutil.TempDir("", "docker-test")
if err != nil {
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)
if err != nil {
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
container1, err := docker1.Create(

File diff suppressed because one or more lines are too long

View File

@ -93,7 +93,7 @@ func (store *LayerStore) AddLayer(id string, archive Archive) (string, error) {
return "", fmt.Errorf("Mktemp failed: %s", err)
}
if err := Untar(archive, tmp); err != nil {
return "", nil
return "", err
}
layer := store.layerPath(id)
if !store.Exists(id) {

View File

@ -112,7 +112,7 @@ func (store *Store) Remove(img *Image) error {
func (store *Store) List(pth string) ([]*Image, error) {
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 {
return nil, err
}

View File

@ -101,25 +101,30 @@ func Download(url string, stderr io.Writer) (*http.Response, error) {
// Reader with progress bar
type progressReader struct {
reader io.ReadCloser // Stream to read from
output io.Writer // Where to send progress bar to
read_total int // Expected stream length (bytes)
read_progress int // How much has been read so far (bytes)
last_update int // How many bytes read at least update
reader io.ReadCloser // Stream to read from
output io.Writer // Where to send progress bar to
read_total int // Expected stream length (bytes)
read_progress int // How much has been read so far (bytes)
last_update int // How many bytes read at least update
}
func (r *progressReader) Read(p []byte) (n int, err error) {
read, err := io.ReadCloser(r.reader).Read(p)
r.read_progress += read
// Only update progress for every 1% read
update_every := int(0.01 * float64(r.read_total))
if r.read_progress - r.last_update > update_every {
fmt.Fprintf(r.output, "%d/%d (%.0f%%)\r",
if r.read_progress-r.last_update > update_every || r.read_progress == r.read_total {
fmt.Fprintf(r.output, "%d/%d (%.0f%%)\r",
r.read_progress,
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
}
// Send newline when complete
if err == io.EOF {
fmt.Fprintf(r.output, "\n")
}
return read, err
}