func init() { execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error { var container *libcontainer.Config 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 := syncpipe.NewSyncPipeFromFd(0, uintptr(args.Pipe)) if err != nil { return err } if err := namespaces.Init(container, rootfs, args.Console, syncPipe, args.Args); err != nil { return err } return nil }) }
func initAction(context *cli.Context) { runtime.LockOSThread() container, err := loadConfig() if err != nil { log.Fatal(err) } rootfs, err := os.Getwd() if err != nil { log.Fatal(err) } pipeFd, err := strconv.Atoi(rawPipeFd) if err != nil { log.Fatal(err) } syncPipe, err := syncpipe.NewSyncPipeFromFd(0, uintptr(pipeFd)) if err != nil { log.Fatalf("unable to create sync pipe: %s", err) } if err := namespaces.Init(container, rootfs, console, syncPipe, []string(context.Args())); err != nil { log.Fatalf("unable to initialize for container: %s", err) } }
// init runs the libcontainer initialization code because of the busybox style needs // to work around the go runtime and the issues with forking func init() { if len(os.Args) < 2 || os.Args[1] != "init" { return } runtime.LockOSThread() container, err := loadConfig() if err != nil { log.Fatal(err) } rootfs, err := os.Getwd() if err != nil { log.Fatal(err) } syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3) if err != nil { log.Fatalf("unable to create sync pipe: %s", err) } if err := namespaces.Init(container, rootfs, "", syncPipe, os.Args[3:]); err != nil { log.Fatalf("unable to initialize for container: %s", err) } os.Exit(1) }
// loadConfigFromFd loads a container's config from the sync pipe that is provided by // fd 3 when running a process func loadConfigFromFd() (*libcontainer.Config, error) { syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3) if err != nil { return nil, err } var config *libcontainer.Config if err := syncPipe.ReadFromParent(&config); err != nil { return nil, err } return config, nil }
// this expects that we already have our namespaces setup by the C initializer // we are expected to finalize the namespace and exec the user's application func nsenter() { syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3) if err != nil { log.Fatalf("unable to create sync pipe: %s", err) } var config *libcontainer.Config if err := syncPipe.ReadFromParent(&config); err != nil { log.Fatalf("reading container config from parent: %s", err) } if err := namespaces.FinalizeSetns(config, findUserArgs()); err != nil { log.Fatalf("failed to nsenter: %s", err) } }
func initializer() { runtime.LockOSThread() var ( pipe = flag.Int("pipe", 0, "sync pipe fd") console = flag.String("console", "", "console (pty slave) path") root = flag.String("root", ".", "root path for configuration files") ) flag.Parse() var container *libcontainer.Config f, err := os.Open(filepath.Join(*root, "container.json")) if err != nil { writeError(err) } if err := json.NewDecoder(f).Decode(&container); err != nil { f.Close() writeError(err) } f.Close() rootfs, err := os.Getwd() if err != nil { writeError(err) } syncPipe, err := syncpipe.NewSyncPipeFromFd(0, uintptr(*pipe)) if err != nil { writeError(err) } if err := namespaces.Init(container, rootfs, *console, syncPipe, flag.Args()); err != nil { writeError(err) } panic("Unreachable") }
func execMonitor() { log.Debugf("Starting docker monitor %v", os.Args) var ( root string socketGroup string ID string err error ) flag.StringVar(&root, "root", "/var/lib/docker", "docker root directory") flag.StringVar(&socketGroup, "group", "docker", "socket user group") flag.StringVar(&ID, "id", "", "container id") flag.Parse() initLogging(true) if ID == "" || root == "" { log.Errorf("%s: container id can't be null", dockerMonitor) flag.Usage() os.Exit(1) } monitorCfg.ID = ID monitorCfg.Root = root monitorCfg.SocketGroup = socketGroup syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3) if err != nil { log.Errorf("%s: open sync pipe failed: %v", dockerMonitor, err) os.Exit(1) } watching := daemon.NewStateWatcher() log.Debugf("MonitorConfig: %v", *monitorCfg) monitor := daemon.InitDockerMonitor(monitorCfg, watching) if monitor == nil { log.Errorf("Initial docker monitor return nil") os.Exit(1) } srv := apiserver.NewMonitorServer(&apiserver.ServerConfig{ Logging: true, EnableCors: true, Version: dockerversion.VERSION, SocketGroup: monitorCfg.SocketGroup, }, monitor, watching) signal.Trap(srv.Shutdown) // notify monitor proxy when server is setup go func() { select { case <-srv.Start(): log.Debugf("Monitor server is up, notify monitor proxy") syncPipe.CloseChild() } }() //srvAPIWait := make(chan error) // setup Monitor server protoAddrs := []string{fmt.Sprintf("unix://%s/%s.sock", daemon.MonitorSockDir, ID)} go func() { if err := srv.ServeApi(protoAddrs); err != nil { log.Errorf("ServeAPI error: %v", err) //srvAPIWait <- err srv.Notify(err) } }() srv.AcceptConnections() err = srv.Wait() log.Infof("docker monitor exit, with error: %v", err) }