mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge
This commit is contained in:
commit
2d5a1abf79
6 changed files with 117 additions and 55 deletions
|
@ -16,6 +16,12 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var sysInitPath string
|
||||
|
||||
func init() {
|
||||
sysInitPath = SelfPath()
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
Id string
|
||||
Root string
|
||||
|
@ -29,6 +35,7 @@ type Container struct {
|
|||
Filesystem *Filesystem
|
||||
State *State
|
||||
|
||||
SysInitPath string
|
||||
lxcConfigPath string
|
||||
cmd *exec.Cmd
|
||||
stdout *writeBroadcaster
|
||||
|
@ -58,6 +65,7 @@ func createContainer(id string, root string, command string, args []string, laye
|
|||
Filesystem: newFilesystem(path.Join(root, "rootfs"), path.Join(root, "rw"), layers),
|
||||
State: newState(),
|
||||
|
||||
SysInitPath: sysInitPath,
|
||||
lxcConfigPath: path.Join(root, "config.lxc"),
|
||||
stdout: newWriteBroadcaster(),
|
||||
stderr: newWriteBroadcaster(),
|
||||
|
@ -261,6 +269,7 @@ func (container *Container) Start() error {
|
|||
"-n", container.Id,
|
||||
"-f", container.lxcConfigPath,
|
||||
"--",
|
||||
"/sbin/init",
|
||||
container.Path,
|
||||
}
|
||||
params = append(params, container.Args...)
|
||||
|
|
|
@ -6,6 +6,13 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// Hack to run sys init during unit testing
|
||||
func init() {
|
||||
if SelfPath() == "/sbin/init" {
|
||||
SysInit()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestDocker() (*Docker, error) {
|
||||
root, err := ioutil.TempDir("", "docker-test")
|
||||
if err != nil {
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/dotcloud/docker"
|
||||
"github.com/dotcloud/docker/rcli"
|
||||
"github.com/dotcloud/docker/image"
|
||||
"github.com/dotcloud/docker/future"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"io"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"os"
|
||||
"time"
|
||||
"github.com/dotcloud/docker"
|
||||
"github.com/dotcloud/docker/future"
|
||||
"github.com/dotcloud/docker/image"
|
||||
"github.com/dotcloud/docker/rcli"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"bytes"
|
||||
"sync"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
)
|
||||
|
||||
const VERSION = "0.0.1"
|
||||
|
@ -176,7 +176,6 @@ func (srv *Server) CmdWrite(stdin io.ReadCloser, stdout io.Writer, args ...strin
|
|||
return errors.New("No such container: " + name)
|
||||
}
|
||||
|
||||
|
||||
func (srv *Server) CmdLs(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
cmd := rcli.Subcmd(stdout, "ls", "[OPTIONS] CONTAINER PATH", "List the contents of a container's directory")
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
|
@ -268,7 +267,7 @@ func (srv *Server) CmdRm(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
return errors.New("No such container: " + name)
|
||||
}
|
||||
if err := srv.containers.Destroy(container); err != nil {
|
||||
fmt.Fprintln(stdout, "Error destroying container " + name + ": " + err.Error())
|
||||
fmt.Fprintln(stdout, "Error destroying container "+name+": "+err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -286,7 +285,7 @@ func (srv *Server) CmdKill(stdin io.ReadCloser, stdout io.Writer, args ...string
|
|||
return errors.New("No such container: " + name)
|
||||
}
|
||||
if err := container.Kill(); err != nil {
|
||||
fmt.Fprintln(stdout, "Error killing container " + name + ": " + err.Error())
|
||||
fmt.Fprintln(stdout, "Error killing container "+name+": "+err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -373,7 +372,7 @@ func (srv *Server) CmdImages(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
nameFilter = cmd.Arg(0)
|
||||
}
|
||||
w := tabwriter.NewWriter(stdout, 20, 1, 3, ' ', 0)
|
||||
if (!*quiet) {
|
||||
if !*quiet {
|
||||
fmt.Fprintf(w, "NAME\tID\tCREATED\tPARENT\n")
|
||||
}
|
||||
for _, name := range srv.images.Names() {
|
||||
|
@ -407,7 +406,7 @@ func (srv *Server) CmdImages(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!*quiet) {
|
||||
if !*quiet {
|
||||
w.Flush()
|
||||
}
|
||||
return nil
|
||||
|
@ -424,7 +423,7 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
return nil
|
||||
}
|
||||
w := tabwriter.NewWriter(stdout, 12, 1, 3, ' ', 0)
|
||||
if (!*quiet) {
|
||||
if !*quiet {
|
||||
fmt.Fprintf(w, "ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tCOMMENT\n")
|
||||
}
|
||||
for _, container := range srv.containers.List() {
|
||||
|
@ -437,7 +436,7 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
if !*fl_full {
|
||||
command = docker.Trunc(command, 20)
|
||||
}
|
||||
for idx, field := range[]string {
|
||||
for idx, field := range []string{
|
||||
/* ID */ container.Id,
|
||||
/* IMAGE */ container.GetUserData("image"),
|
||||
/* COMMAND */ command,
|
||||
|
@ -456,7 +455,7 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
stdout.Write([]byte(container.Id + "\n"))
|
||||
}
|
||||
}
|
||||
if (!*quiet) {
|
||||
if !*quiet {
|
||||
w.Flush()
|
||||
}
|
||||
return nil
|
||||
|
@ -475,7 +474,6 @@ func (srv *Server) CmdLayers(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (srv *Server) CmdCp(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
cmd := rcli.Subcmd(stdout,
|
||||
"cp", "[OPTIONS] IMAGE NAME",
|
||||
|
@ -521,7 +519,6 @@ func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
return errors.New("No such container: " + containerName)
|
||||
}
|
||||
|
||||
|
||||
func (srv *Server) CmdTar(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
cmd := rcli.Subcmd(stdout,
|
||||
"tar", "CONTAINER",
|
||||
|
@ -592,7 +589,6 @@ func (srv *Server) CmdReset(stdin io.ReadCloser, stdout io.Writer, args ...strin
|
|||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (srv *Server) CmdLogs(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
cmd := rcli.Subcmd(stdout, "logs", "[OPTIONS] CONTAINER", "Fetch the logs of a container")
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
|
@ -615,7 +611,6 @@ 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 *image.Image, tty bool, openStdin bool, comment string, cmd string, args ...string) (*docker.Container, error) {
|
||||
id := future.RandomId()[:8]
|
||||
container, err := srv.containers.Create(id, cmd, args, img.Layers,
|
||||
|
@ -658,7 +653,7 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
return err
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() { io.Copy(c_stdin, stdin); wg.Add(-1); }()
|
||||
go func() { io.Copy(c_stdin, stdin); wg.Add(-1) }()
|
||||
}
|
||||
if *fl_o {
|
||||
c_stdout, err := container.StdoutPipe()
|
||||
|
@ -666,7 +661,7 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
return err
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() { io.Copy(stdout, c_stdout); wg.Add(-1); }()
|
||||
go func() { io.Copy(stdout, c_stdout); wg.Add(-1) }()
|
||||
}
|
||||
if *fl_e {
|
||||
c_stderr, err := container.StderrPipe()
|
||||
|
@ -674,7 +669,7 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
return err
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() { io.Copy(stdout, c_stderr); wg.Add(-1); }()
|
||||
go func() { io.Copy(stdout, c_stderr); wg.Add(-1) }()
|
||||
}
|
||||
wg.Wait()
|
||||
return nil
|
||||
|
@ -690,7 +685,7 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
return nil
|
||||
}
|
||||
name := cmd.Arg(0)
|
||||
var cmdline[]string
|
||||
var cmdline []string
|
||||
if len(cmd.Args()) >= 2 {
|
||||
cmdline = cmd.Args()[1:]
|
||||
}
|
||||
|
@ -723,7 +718,7 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
if *fl_attach {
|
||||
future.Go(func() error {
|
||||
log.Printf("CmdRun(): start receiving stdin\n")
|
||||
_, err := io.Copy(cmd_stdin, stdin);
|
||||
_, err := io.Copy(cmd_stdin, stdin)
|
||||
log.Printf("CmdRun(): done receiving stdin\n")
|
||||
cmd_stdin.Close()
|
||||
return err
|
||||
|
@ -744,11 +739,11 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
return err
|
||||
}
|
||||
sending_stdout := future.Go(func() error {
|
||||
_, err := io.Copy(stdout, cmd_stdout);
|
||||
_, err := io.Copy(stdout, cmd_stdout)
|
||||
return err
|
||||
})
|
||||
sending_stderr := future.Go(func() error {
|
||||
_, err := io.Copy(stdout, cmd_stderr);
|
||||
_, err := io.Copy(stdout, cmd_stderr)
|
||||
return err
|
||||
})
|
||||
err_sending_stdout := <-sending_stdout
|
||||
|
@ -770,6 +765,11 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
}
|
||||
|
||||
func main() {
|
||||
if docker.SelfPath() == "/sbin/init" {
|
||||
// Running in init mode
|
||||
docker.SysInit()
|
||||
return
|
||||
}
|
||||
future.Seed()
|
||||
flag.Parse()
|
||||
d, err := New()
|
||||
|
@ -845,9 +845,7 @@ func (srv *Server) CmdWeb(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
return nil
|
||||
}
|
||||
|
||||
|
||||
type Server struct {
|
||||
containers *docker.Docker
|
||||
images *image.Store
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ lxc.utsname = {{.Id}}
|
|||
#lxc.network.ipv4 = {ip_address}/{ip_prefix_len}
|
||||
|
||||
# root filesystem
|
||||
lxc.rootfs = {{.Filesystem.RootFS}}
|
||||
{{$ROOTFS := .Filesystem.RootFS}}
|
||||
lxc.rootfs = {{$ROOTFS}}
|
||||
|
||||
# use a dedicated pts for the container (and limit the number of pseudo terminal
|
||||
# available)
|
||||
|
@ -66,15 +67,18 @@ lxc.cgroup.devices.allow = c 10:200 rwm
|
|||
|
||||
|
||||
# standard mount point
|
||||
lxc.mount.entry = proc {{.Filesystem.RootFS}}/proc proc nosuid,nodev,noexec 0 0
|
||||
lxc.mount.entry = sysfs {{.Filesystem.RootFS}}/sys sysfs nosuid,nodev,noexec 0 0
|
||||
lxc.mount.entry = devpts {{.Filesystem.RootFS}}/dev/pts devpts newinstance,ptmxmode=0666,nosuid,noexec 0 0
|
||||
#lxc.mount.entry = varrun {{.Filesystem.RootFS}}/var/run tmpfs mode=755,size=4096k,nosuid,nodev,noexec 0 0
|
||||
#lxc.mount.entry = varlock {{.Filesystem.RootFS}}/var/lock tmpfs size=1024k,nosuid,nodev,noexec 0 0
|
||||
#lxc.mount.entry = shm {{.Filesystem.RootFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
|
||||
lxc.mount.entry = proc {{$ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
|
||||
lxc.mount.entry = sysfs {{$ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
|
||||
lxc.mount.entry = devpts {{$ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,nosuid,noexec 0 0
|
||||
#lxc.mount.entry = varrun {{$ROOTFS}}/var/run tmpfs mode=755,size=4096k,nosuid,nodev,noexec 0 0
|
||||
#lxc.mount.entry = varlock {{$ROOTFS}}/var/lock tmpfs size=1024k,nosuid,nodev,noexec 0 0
|
||||
#lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
|
||||
|
||||
# Inject docker-init
|
||||
lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/sbin/init none bind,ro 0 0
|
||||
|
||||
# In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
|
||||
lxc.mount.entry = /etc/resolv.conf {{.Filesystem.RootFS}}/etc/resolv.conf none bind,ro 0 0
|
||||
lxc.mount.entry = /etc/resolv.conf {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0
|
||||
|
||||
|
||||
# drop linux capabilities (apply mainly to the user root in the container)
|
||||
|
|
29
sysinit.go
Normal file
29
sysinit.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Sys Init code
|
||||
// This code is run INSIDE the container and is responsible for setting
|
||||
// up the environment before running the actual process
|
||||
func SysInit() {
|
||||
if len(os.Args) <= 1 {
|
||||
fmt.Println("You should not invoke docker-init manually")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(os.Args[1])
|
||||
if err != nil {
|
||||
log.Printf("Unable to locate %v", os.Args[1])
|
||||
os.Exit(127)
|
||||
}
|
||||
|
||||
if err := syscall.Exec(path, os.Args[1:], os.Environ()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
15
utils.go
15
utils.go
|
@ -4,7 +4,9 @@ import (
|
|||
"bytes"
|
||||
"container/list"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
@ -34,6 +36,19 @@ func Tar(path string) (io.Reader, error) {
|
|||
return output, nil
|
||||
}
|
||||
|
||||
// Figure out the absolute path of our own binary
|
||||
func SelfPath() string {
|
||||
path, err := exec.LookPath(os.Args[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
path, err = filepath.Abs(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
type nopWriteCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue