Skip to content
Permalink
Browse files

Add "jail" execdriver for supporting FreeBSD

Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi <kato.kazuyoshi@gmail.com> (github: kzys)
  • Loading branch information...
kzys committed Jun 22, 2014
1 parent 9387eaa commit f8c4d49fda9eb7e35c88532c174fa8dca9d831ba
Showing with 167 additions and 2 deletions.
  1. +3 −0 daemon/execdriver/execdrivers/execdrivers.go
  2. +162 −0 daemon/execdriver/jail/driver.go
  3. +2 −2 docker/docker.go
@@ -3,6 +3,7 @@ package execdrivers
import (
"fmt"
"github.com/dotcloud/docker/daemon/execdriver"
"github.com/dotcloud/docker/daemon/execdriver/jail"
"github.com/dotcloud/docker/daemon/execdriver/lxc"
"github.com/dotcloud/docker/daemon/execdriver/native"
"github.com/dotcloud/docker/pkg/sysinfo"
@@ -18,6 +19,8 @@ func NewDriver(name, root, initPath string, sysInfo *sysinfo.SysInfo) (execdrive
return lxc.NewDriver(root, sysInfo.AppArmor)
case "native":
return native.NewDriver(path.Join(root, "execdriver", "native"), initPath)
case "jail":
return jail.NewDriver(path.Join(root, "execdriver", "jail"), initPath)
}
return nil, fmt.Errorf("unknown exec driver %s", name)
}
@@ -0,0 +1,162 @@
package jail

import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"runtime"
"syscall"

"github.com/dotcloud/docker/daemon/execdriver"
)

const DriverName = "jail"

func init() {
execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error {
runtime.LockOSThread()

This comment has been minimized.

Copy link
@bradfitz

path, err := exec.LookPath(args.Args[0])
if err != nil {
log.Printf("Unable to locate %v", args.Args[0])
os.Exit(127)
}
if err := syscall.Exec(path, args.Args, os.Environ()); err != nil {
return fmt.Errorf("dockerinit unable to execute %s - %s", path, err)
}
panic("Unreachable")
})
}

type driver struct {
root string
initPath string
}

func NewDriver(root, initPath string) (*driver, error) {
if err := os.MkdirAll(root, 0700); err != nil {
return nil, err
}

return &driver{
root: root,
initPath: initPath,
}, nil
}

func (d *driver) Name() string {
return DriverName
}

func copyFile(src string, dest string) error {

This comment has been minimized.

Copy link
@bradfitz

bradfitz Mar 28, 2015

this slurps the whole file into memory instead of streaming it from src to dst.

Also (src, dest string) instead of repeating string twice.

Also, Go style is generally to have the dest first.

content, err := ioutil.ReadFile(src)
if err != nil {
return err
}

err = ioutil.WriteFile(dest, content, 0755)
if err != nil {
return err
}

return nil
}

func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
if err := execdriver.SetTerminal(c, pipes); err != nil {
return -1, err
}

root := c.Rootfs

init := path.Join(root, ".dockerinit")
if err := copyFile(os.Args[0], init); err != nil {
return -1, err
}

devDir := path.Join(root, "dev")
if err := os.MkdirAll(devDir, 0755); err != nil {
return -1, err
}

params := []string{
"/usr/sbin/jail",
"-c",
"name=" + c.ID,
"path=" + root,
"command=" + c.InitPath,
"-driver",
DriverName,
}

if c.User != "" {
params = append(params, "-u", c.User)
}

if c.Privileged {
params = append(params, "-privileged")
}

if c.WorkingDir != "" {
params = append(params, "-w", c.WorkingDir)
}

params = append(params, "--", c.Entrypoint)
params = append(params, c.Arguments...)

c.Path = "/usr/sbin/jail"
c.Args = params

if err := c.Run(); err != nil {
return -1, err
}

return getExitCode(c), nil
}

func getExitCode(c *execdriver.Command) int {
if c.ProcessState == nil {
return -1
}
return c.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
}

func (d *driver) Kill(c *execdriver.Command, sig int) error {
return nil
}

func (d *driver) Pause(c *execdriver.Command) error {
return nil
}

func (d *driver) Unpause(c *execdriver.Command) error {
return nil
}

func (d *driver) Terminate(c *execdriver.Command) error {
return nil
}

func (d *driver) GetPidsForContainer(id string) ([]int, error) {
return nil, nil
}

type info struct {
ID string
driver *driver
}

func (d *driver) Info(id string) execdriver.Info {
return &info{ID: id, driver: d}
}

func (info *info) IsRunning() bool {
if err := exec.Command("jls", "-j", info.ID).Run(); err != nil {

This comment has been minimized.

Copy link
@cyphar

cyphar Jul 11, 2014

Shouldn't this also use the absolute path /usr/sbin/jail?

return true
}

return false
}
@@ -109,8 +109,8 @@ func main() {
}

if *flDaemon {
if runtime.GOOS != "linux" {
log.Fatalf("The Docker daemon is only supported on linux")
if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
log.Fatalf("The Docker daemon is only supported on linux and freebsd")
}
if os.Geteuid() != 0 {
log.Fatalf("The Docker daemon needs to be run as root")

5 comments on commit f8c4d49

@mikeal

This comment has been minimized.

Copy link

replied Sep 9, 2014

what is the state of this branch? is it working? will it be sent as a pull request any time soon?

@kzys

This comment has been minimized.

Copy link
Owner Author

replied Sep 11, 2014

@mikeal

This comment has been minimized.

Copy link

replied Sep 11, 2014

thanks for the update :)

@maci0

This comment has been minimized.

Copy link

replied Sep 30, 2014

interesting.
do images just work as they do on linux ?
i guess it should be possible to have bsd images as well

@mpasternacki

This comment has been minimized.

Copy link

replied Oct 9, 2014

Please let me know if you need a helping hand - I'm very interested in having Docker work on FreeBSD.

Due to Docker's internal API changes, this doesn't build after master merge - trying to get this fixed, you may get a PR :)

Please sign in to comment.
You can’t perform that action at this time.