func init() { execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error { var container *libcontainer.Container f, err := os.Open(filepath.Join(args.Root, "container.json")) if err != nil { return err } if err := json.NewDecoder(f).Decode(&container); err != nil { f.Close() return err } f.Close() rootfs, err := os.Getwd() if err != nil { return err } syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(args.Pipe)) if err != nil { return err } if err := nsinit.Init(container, rootfs, args.Console, syncPipe, args.Args); err != nil { return err } return nil }) }
func main() { if len(os.Args) < 2 { log.Fatalf("invalid number of arguments %d", len(os.Args)) } container, err := loadContainer() if err != nil { log.Fatalf("unable to load container: %s", err) } switch os.Args[1] { case "exec": // this is executed outside of the namespace in the cwd var nspid, exitCode int if nspid, err = readPid(); err != nil && !os.IsNotExist(err) { log.Fatalf("unable to read pid: %s", err) } if nspid > 0 { exitCode, err = nsinit.ExecIn(container, nspid, os.Args[2:]) } else { term := nsinit.NewTerminal(os.Stdin, os.Stdout, os.Stderr, container.Tty) exitCode, err = nsinit.Exec(container, term, "", dataPath, os.Args[2:], nsinit.DefaultCreateCommand, nil) } if err != nil { log.Fatalf("failed to exec: %s", err) } os.Exit(exitCode) case "init": // this is executed inside of the namespace to setup the container // by default our current dir is always our rootfs rootfs, err := os.Getwd() if err != nil { log.Fatal(err) } pipeFd, err := strconv.Atoi(rawPipeFd) if err != nil { log.Fatal(err) } syncPipe, err := nsinit.NewSyncPipeFromFd(0, uintptr(pipeFd)) if err != nil { log.Fatalf("unable to create sync pipe: %s", err) } if err := nsinit.Init(container, rootfs, console, syncPipe, os.Args[2:]); err != nil { log.Fatalf("unable to initialize for container: %s", err) } default: log.Fatalf("command not supported for nsinit %s", os.Args[0]) } }