Merge remote-tracking branch 'dotcloud/master' into dhrp/docs

Conflicts:
	docker/docker.go
	docs/sources/installation/archlinux.rst
	docs/sources/installation/index.rst
	docs/sources/installation/ubuntulinux.rst
	runtime.go
	utils.go
This commit is contained in:
Thatcher Peskens 2013-04-22 18:44:50 -07:00
commit 5a5e417d46
8 changed files with 175 additions and 84 deletions

View file

@ -150,6 +150,82 @@ func TestMultipleAttachRestart(t *testing.T) {
} }
} }
func TestDiff(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
// Create a container and remove a file
container1, err := runtime.Create(
&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"/bin/rm", "/etc/passwd"},
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container1)
if err := container1.Run(); err != nil {
t.Fatal(err)
}
// Check the changelog
c, err := container1.Changes()
if err != nil {
t.Fatal(err)
}
success := false
for _, elem := range c {
if elem.Path == "/etc/passwd" && elem.Kind == 2 {
success = true
}
}
if !success {
t.Fatalf("/etc/passwd as been removed but is not present in the diff")
}
// Commit the container
rwTar, err := container1.ExportRw()
if err != nil {
t.Error(err)
}
img, err := runtime.graph.Create(rwTar, container1, "unit test commited image - diff", "")
if err != nil {
t.Error(err)
}
// Create a new container from the commited image
container2, err := runtime.Create(
&Config{
Image: img.Id,
Cmd: []string{"cat", "/etc/passwd"},
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container2)
if err := container2.Run(); err != nil {
t.Fatal(err)
}
// Check the changelog
c, err = container2.Changes()
if err != nil {
t.Fatal(err)
}
for _, elem := range c {
if elem.Path == "/etc/passwd" {
t.Fatalf("/etc/passwd should not be present in the diff after commit.")
}
}
}
func TestCommitRun(t *testing.T) { func TestCommitRun(t *testing.T) {
runtime, err := newTestRuntime() runtime, err := newTestRuntime()
if err != nil { if err != nil {

View file

@ -7,9 +7,11 @@ import (
"github.com/dotcloud/docker/rcli" "github.com/dotcloud/docker/rcli"
"github.com/dotcloud/docker/term" "github.com/dotcloud/docker/term"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"os/signal" "os/signal"
"strconv"
"syscall" "syscall"
) )
@ -54,8 +56,13 @@ func main() {
} }
func createPidFile(pidfile string) error { func createPidFile(pidfile string) error {
if _, err := os.Stat(pidfile); err == nil { if pidString, err := ioutil.ReadFile(pidfile); err == nil {
return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile) pid, err := strconv.Atoi(string(pidString))
if err == nil {
if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil {
return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile)
}
}
} }
file, err := os.Create(pidfile) file, err := os.Create(pidfile)

View file

@ -56,7 +56,10 @@ There is a systemd service unit created for docker. To start the docker service
sudo systemctl start docker sudo systemctl start docker
<<<<<<< HEAD
=======
>>>>>>> dotcloud/master
To start on system boot: To start on system boot:
:: ::

View file

@ -0,0 +1,9 @@
package docker
import (
"fmt"
)
func getKernelVersion() (*KernelVersionInfo, error) {
return nil, fmt.Errorf("Kernel version detection is not available on darwin")
}

69
getKernelVersion_linux.go Normal file
View file

@ -0,0 +1,69 @@
package docker
import (
"bytes"
"strconv"
"strings"
"syscall"
)
func getKernelVersion() (*KernelVersionInfo, error) {
var (
uts syscall.Utsname
flavor string
kernel, major, minor int
err error
)
if err := syscall.Uname(&uts); err != nil {
return nil, err
}
release := make([]byte, len(uts.Release))
i := 0
for _, c := range uts.Release {
release[i] = byte(c)
i++
}
// Remove the \x00 from the release for Atoi to parse correctly
release = release[:bytes.IndexByte(release, 0)]
tmp := strings.SplitN(string(release), "-", 2)
tmp2 := strings.SplitN(tmp[0], ".", 3)
if len(tmp2) > 0 {
kernel, err = strconv.Atoi(tmp2[0])
if err != nil {
return nil, err
}
}
if len(tmp2) > 1 {
major, err = strconv.Atoi(tmp2[1])
if err != nil {
return nil, err
}
}
if len(tmp2) > 2 {
minor, err = strconv.Atoi(tmp2[2])
if err != nil {
return nil, err
}
}
if len(tmp) == 2 {
flavor = tmp[1]
} else {
flavor = ""
}
return &KernelVersionInfo{
Kernel: kernel,
Major: major,
Minor: minor,
Flavor: flavor,
}, nil
}

View file

@ -92,7 +92,7 @@ func MountAUFS(ro []string, rw string, target string) error {
rwBranch := fmt.Sprintf("%v=rw", rw) rwBranch := fmt.Sprintf("%v=rw", rw)
roBranches := "" roBranches := ""
for _, layer := range ro { for _, layer := range ro {
roBranches += fmt.Sprintf("%v=ro:", layer) roBranches += fmt.Sprintf("%v=ro+wh:", layer)
} }
branches := fmt.Sprintf("br:%v:%v", rwBranch, roBranches) branches := fmt.Sprintf("br:%v:%v", rwBranch, roBranches)
@ -136,34 +136,9 @@ func (image *Image) Mount(root, rw string) error {
if err := os.Mkdir(rw, 0755); err != nil && !os.IsExist(err) { if err := os.Mkdir(rw, 0755); err != nil && !os.IsExist(err) {
return err return err
} }
// FIXME: @creack shouldn't we do this after going over changes?
if err := MountAUFS(layers, rw, root); err != nil { if err := MountAUFS(layers, rw, root); err != nil {
return err return err
} }
// FIXME: Create tests for deletion
// FIXME: move this part to change.go
// Retrieve the changeset from the parent and apply it to the container
// - Retrieve the changes
changes, err := Changes(layers, layers[0])
if err != nil {
return err
}
// Iterate on changes
for _, c := range changes {
// If there is a delete
if c.Kind == ChangeDelete {
// Make sure the directory exists
file_path, file_name := path.Dir(c.Path), path.Base(c.Path)
if err := os.MkdirAll(path.Join(rw, file_path), 0755); err != nil {
return err
}
// And create the whiteout (we just need to create empty file, discard the return)
if _, err := os.Create(path.Join(path.Join(rw, file_path),
".wh."+path.Base(file_name))); err != nil {
return err
}
}
}
return nil return nil
} }

View file

@ -295,14 +295,13 @@ func NewRuntime() (*Runtime, error) {
return nil, err return nil, err
} }
k, err := GetKernelVersion() if k, err := GetKernelVersion(); err != nil {
if err != nil { log.Printf("WARNING: %s\n", err)
return nil, err } else {
} runtime.kernelVersion = k
runtime.kernelVersion = k if CompareKernelVersion(k, &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
if CompareKernelVersion(k, &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 { }
log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
} }
if cgroupMemoryMountpoint, err := FindCgroupMountpoint("memory"); err != nil { if cgroupMemoryMountpoint, err := FindCgroupMountpoint("memory"); err != nil {

View file

@ -14,10 +14,8 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
"strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
) )
@ -407,52 +405,7 @@ type KernelVersionInfo struct {
// FIXME: this doens't build on Darwin // FIXME: this doens't build on Darwin
func GetKernelVersion() (*KernelVersionInfo, error) { func GetKernelVersion() (*KernelVersionInfo, error) {
var uts syscall.Utsname return getKernelVersion()
if err := syscall.Uname(&uts); err != nil {
return nil, err
}
release := make([]byte, len(uts.Release))
i := 0
for _, c := range uts.Release {
release[i] = byte(c)
i++
}
tmp := strings.SplitN(string(release), "-", 2)
if len(tmp) != 2 {
return nil, fmt.Errorf("Unrecognized kernel version")
}
tmp2 := strings.SplitN(tmp[0], ".", 3)
if len(tmp2) != 3 {
return nil, fmt.Errorf("Unrecognized kernel version")
}
kernel, err := strconv.Atoi(tmp2[0])
if err != nil {
return nil, err
}
major, err := strconv.Atoi(tmp2[1])
if err != nil {
return nil, err
}
minor, err := strconv.Atoi(tmp2[2])
if err != nil {
return nil, err
}
flavor := tmp[1]
return &KernelVersionInfo{
Kernel: kernel,
Major: major,
Minor: minor,
Flavor: flavor,
}, nil
} }
func (k *KernelVersionInfo) String() string { func (k *KernelVersionInfo) String() string {