Merge from master

This commit is contained in:
Andrea Luzzardi 2013-02-26 17:32:07 -08:00
commit c7f4602b18
17 changed files with 207 additions and 175 deletions

4
.gitignore vendored
View File

@ -1,5 +1,5 @@
.vagrant
docker
dockerd
docker/docker
dockerd/dockerd
.*.swp
a.out

View File

@ -157,7 +157,7 @@ Step by step host setup
3. Type the following commands:
apt-get update
apt-get install lxc wget bsdtar
apt-get install lxc wget bsdtar curl
4. Download the latest version of the [docker binaries](https://dl.dropbox.com/u/20637798/docker.tar.gz) (`wget https://dl.dropbox.com/u/20637798/docker.tar.gz`) (warning: this may not be the most up-to-date build)
5. Extract the contents of the tar file `tar -xf docker.tar.gz`

View File

@ -1,8 +1,8 @@
package client
import (
"github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/future"
"github.com/dotcloud/docker/rcli"
"io"
"io/ioutil"
"log"

View File

@ -15,7 +15,6 @@ type Termios struct {
Ospeed uintptr
}
const (
// Input flags
inpck = 0x010
@ -136,12 +135,9 @@ func MakeRaw(fd int) (*State, error) {
return &oldState, nil
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
return err
}

View File

@ -460,10 +460,13 @@ func (container *Container) Restart() error {
return nil
}
func (container *Container) Wait() {
// Wait blocks until the container stops running, then returns its exit code.
func (container *Container) Wait() int {
for container.State.Running {
container.State.wait()
}
return container.State.ExitCode
}
func (container *Container) WaitTimeout(timeout time.Duration) error {

View File

@ -2,10 +2,10 @@ package main
import (
"flag"
"github.com/dotcloud/docker/client"
"log"
"os"
"path"
"github.com/dotcloud/docker/client"
)
func main() {
@ -27,4 +27,3 @@ func main() {
}
}
}

View File

@ -49,7 +49,7 @@ if [ "$CMD" = "build" ]; then
fi
if attach $BUILD_JOB ; then
BUILD_STATUS=`docker ps -a | sed -E -n "s/^$BUILD_JOB.*Exit ([0-9]+) *$/\1/p"`
BUILD_STATUS=`docker wait $BUILD_JOB`
if [ -z "$BUILD_STATUS" -o "$BUILD_STATUS" != 0 ]; then
echo "Build failed"
exit 1

View File

@ -1,15 +1,14 @@
package fake
import (
"bytes"
"math/rand"
"io"
"archive/tar"
"os/exec"
"bytes"
"github.com/kr/pty"
"io"
"math/rand"
"os/exec"
)
func FakeTar() (io.Reader, error) {
content := []byte("Hello world!\n")
buf := new(bytes.Buffer)
@ -27,7 +26,6 @@ func FakeTar() (io.Reader, error) {
return buf, nil
}
func WriteFakeTar(dst io.Writer) error {
if data, err := FakeTar(); err != nil {
return err
@ -37,7 +35,6 @@ func WriteFakeTar(dst io.Writer) error {
return nil
}
func RandomBytesChanged() uint {
return uint(rand.Int31n(24 * 1024 * 1024))
}
@ -54,7 +51,6 @@ func ContainerRunning() bool {
return false
}
func StartCommand(cmd *exec.Cmd, interactive bool) (io.WriteCloser, io.ReadCloser, error) {
if interactive {
term, err := pty.Start(cmd)
@ -76,5 +72,3 @@ func StartCommand(cmd *exec.Cmd, interactive bool) (io.WriteCloser, io.ReadClose
}
return stdin, stdout, nil
}

View File

@ -3,6 +3,7 @@ package docker
import (
"errors"
"fmt"
"github.com/dotcloud/docker/image"
"io"
"io/ioutil"
"os"
@ -10,7 +11,6 @@ import (
"strings"
"syscall"
"time"
"github.com/dotcloud/docker/image"
)
type Filesystem struct {

View File

@ -1,12 +1,13 @@
package future
import (
"crypto/sha256"
"io"
"fmt"
"time"
"bytes"
"crypto/sha256"
"fmt"
"io"
"math/rand"
"os/exec"
"time"
)
func Seed() {
@ -84,3 +85,18 @@ func Pv(src io.Reader, info io.Writer) io.Reader {
return r
}
// Curl makes an http request by executing the unix command 'curl', and returns
// the body of the response. If `stderr` is not nil, a progress bar will be
// written to it.
func Curl(url string, stderr io.Writer) (io.Reader, error) {
curl := exec.Command("curl", "-#", "-L", url)
output, err := curl.StdoutPipe()
if err != nil {
return nil, err
}
curl.Stderr = stderr
if err := curl.Start(); err != nil {
return nil, err
}
return output, nil
}

View File

@ -1,10 +1,10 @@
package image
import (
"errors"
"io"
"io/ioutil"
"os/exec"
"errors"
)
type Compression uint32
@ -17,8 +17,10 @@ const (
func (compression *Compression) Flag() string {
switch *compression {
case Bzip2: return "j"
case Gzip: return "z"
case Bzip2:
return "j"
case Gzip:
return "z"
}
return ""
}

View File

@ -1,10 +1,10 @@
package image
import (
"testing"
"io/ioutil"
"os"
"os/exec"
"io/ioutil"
"testing"
)
func TestCmdStreamBad(t *testing.T) {

View File

@ -1,27 +1,25 @@
package image
import (
"encoding/json"
"errors"
"github.com/dotcloud/docker/future"
"io"
"io/ioutil"
"encoding/json"
"time"
"os"
"path"
"path/filepath"
"errors"
"sort"
"os"
"github.com/dotcloud/docker/future"
"strings"
"time"
)
type Store struct {
*Index
Root string
Layers *LayerStore
}
func New(root string) (*Store, error) {
abspath, err := filepath.Abs(root)
if err != nil {
@ -73,7 +71,6 @@ func (store *Store) Create(name string, source string, layers ...string) (*Image
return image, nil
}
// Index
type Index struct {

View File

@ -2,12 +2,12 @@ package image
import (
"errors"
"path"
"path/filepath"
"github.com/dotcloud/docker/future"
"io"
"io/ioutil"
"os"
"github.com/dotcloud/docker/future"
"path"
"path/filepath"
)
type LayerStore struct {
@ -66,7 +66,6 @@ func (store *LayerStore) Init() error {
return os.Mkdir(store.Root, 0700)
}
func (store *LayerStore) Mktemp() (string, error) {
tmpName := future.RandomId()
tmpPath := path.Join(store.Root, "tmp-"+tmpName)
@ -80,7 +79,6 @@ func (store *LayerStore) layerPath(id string) string {
return path.Join(store.Root, id)
}
func (store *LayerStore) AddLayer(archive io.Reader) (string, error) {
errors := make(chan error)
// Untar
@ -111,7 +109,8 @@ func (store *LayerStore) AddLayer(archive io.Reader) (string, error) {
// Wait for goroutines
for i := 0; i < 2; i += 1 {
select {
case err := <-errors: {
case err := <-errors:
{
if err != nil {
return "", err
}

View File

@ -1,12 +1,12 @@
package image
import (
"bytes"
"github.com/dotcloud/docker/fake"
"github.com/dotcloud/docker/future"
"io/ioutil"
"os"
"testing"
"io/ioutil"
"bytes"
"github.com/dotcloud/docker/future"
"github.com/dotcloud/docker/fake"
)
func TestAddLayer(t *testing.T) {
@ -45,4 +45,3 @@ func TestComputeId(t *testing.T) {
t.Fatalf("Identical checksums for difference content (%s == %s)", id1, id2)
}
}

View File

@ -2,7 +2,6 @@ package docker
import "syscall"
func mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
return syscall.Mount(source, target, fstype, flags, data)
}

View File

@ -53,6 +53,7 @@ func (srv *Server) Help() string {
{"diff", "Inspect changes on a container's filesystem"},
{"commit", "Save the state of a container"},
{"attach", "Attach to the standard inputs and outputs of a running container"},
{"wait", "Block until a container exits, then print its exit code"},
{"info", "Display system-wide information"},
{"tar", "Stream the contents of a container as a tar archive"},
{"web", "Generate a web UI"},
@ -63,6 +64,27 @@ func (srv *Server) Help() string {
return help
}
// 'docker wait': block until a container stops
func (srv *Server) CmdWait(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout, "wait", "[OPTIONS] NAME", "Block until a container stops, then print its exit code.")
if err := cmd.Parse(args); err != nil {
cmd.Usage()
return nil
}
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
for _, name := range cmd.Args() {
if container := srv.containers.Get(name); container != nil {
fmt.Fprintln(stdout, container.Wait())
} else {
return errors.New("No such container: " + name)
}
}
return nil
}
// 'docker info': display system-wide information.
func (srv *Server) CmdInfo(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
fmt.Fprintf(stdout, "containers: %d\nversion: %s\nimages: %d\n",
@ -368,12 +390,18 @@ func (srv *Server) CmdPull(stdin io.ReadCloser, stdout io.Writer, args ...string
u.Path = path.Join("/docker.io/images", u.Path)
}
fmt.Fprintf(stdout, "Downloading from %s\n", u.String())
resp, err := http.Get(u.String())
// Download with curl (pretty progress bar)
// If curl is not available, fallback to http.Get()
archive, err := future.Curl(u.String(), stdout)
if err != nil {
if resp, err := http.Get(u.String()); err != nil {
return err
} else {
archive = resp.Body
}
}
fmt.Fprintf(stdout, "Unpacking to %s\n", name)
img, err := srv.images.Import(name, resp.Body, nil)
img, err := srv.images.Import(name, archive, nil)
if err != nil {
return err
}