func (cmd *GuardianCommand) Run(signals <-chan os.Signal, ready chan<- struct{}) error { logger, reconfigurableSink := cmd.Logger.Logger("guardian") if cmd.Server.Rootless { logger.Info("rootless-mode-on") } if err := exec.Command("modprobe", "aufs").Run(); err != nil { logger.Error("unable-to-load-aufs", err) } propManager, err := cmd.loadProperties(logger, cmd.Containers.PropertiesPath) if err != nil { return err } portPoolState, err := ports.LoadState(cmd.Network.PortPoolPropertiesPath) if err != nil { logger.Error("failed-to-parse-port-pool-properties", err) } portPool, err := ports.NewPool( cmd.Network.PortPoolStart, cmd.Network.PortPoolSize, portPoolState, ) if err != nil { return fmt.Errorf("invalid pool range: %s", err) } networker, iptablesStarter, err := cmd.wireNetworker(logger, propManager, portPool) if err != nil { logger.Error("failed-to-wire-networker", err) return err } restorer := gardener.NewRestorer(networker) if cmd.Containers.DestroyContainersOnStartup { restorer = &gardener.NoopRestorer{} } var volumeCreator gardener.VolumeCreator = nil if !cmd.Server.Rootless { volumeCreator = cmd.wireVolumeCreator(logger, cmd.Graph.Dir.Path(), cmd.Docker.InsecureRegistries, cmd.Graph.PersistentImages) } starters := []gardener.Starter{} if !cmd.Server.Rootless { starters = []gardener.Starter{cmd.wireRunDMCStarter(logger), iptablesStarter} } backend := &gardener.Gardener{ UidGenerator: cmd.wireUidGenerator(), Starters: starters, SysInfoProvider: sysinfo.NewProvider(cmd.Containers.Dir.Path()), Networker: networker, VolumeCreator: volumeCreator, Containerizer: cmd.wireContainerizer(logger, cmd.Containers.Dir.Path(), cmd.Bin.Dadoo.Path(), cmd.Bin.Runc, cmd.Bin.NSTar.Path(), cmd.Bin.Tar.Path(), cmd.Containers.DefaultRootFSDir.Path(), cmd.Containers.ApparmorProfile, propManager), PropertyManager: propManager, MaxContainers: cmd.Limits.MaxContainers, Restorer: restorer, Logger: logger, } var listenNetwork, listenAddr string if cmd.Server.BindIP != nil { listenNetwork = "tcp" listenAddr = fmt.Sprintf("%s:%d", cmd.Server.BindIP.IP(), cmd.Server.BindPort) } else { listenNetwork = "unix" listenAddr = cmd.Server.BindSocket } gardenServer := server.New(listenNetwork, listenAddr, cmd.Containers.DefaultGraceTime, backend, logger.Session("api")) cmd.initializeDropsonde(logger) metricsProvider := cmd.wireMetricsProvider(logger, cmd.Containers.Dir.Path(), cmd.Graph.Dir.Path()) metronNotifier := cmd.wireMetronNotifier(logger, metricsProvider) metronNotifier.Start() if cmd.Server.DebugBindIP != nil { addr := fmt.Sprintf("%s:%d", cmd.Server.DebugBindIP.IP(), cmd.Server.DebugBindPort) metrics.StartDebugServer(addr, reconfigurableSink, metricsProvider) } err = gardenServer.Start() if err != nil { logger.Error("failed-to-start-server", err) return err } close(ready) logger.Info("started", lager.Data{ "network": listenNetwork, "addr": listenAddr, }) <-signals gardenServer.Stop() cmd.saveProperties(logger, cmd.Containers.PropertiesPath, propManager) portPoolState = portPool.RefreshState() ports.SaveState(cmd.Network.PortPoolPropertiesPath, portPoolState) return nil }
tmpDir, err = ioutil.TempDir("", "") Expect(err).NotTo(HaveOccurred()) filePath = path.Join(tmpDir, "ports.json") }) AfterEach(func() { Expect(os.RemoveAll(tmpDir)).To(Succeed()) }) Describe("NewState", func() { It("should parse the provided file", func() { Expect(ioutil.WriteFile(filePath, []byte(`{ "offset": 10 }`), 0660)).To(Succeed()) portPoolState, err := ports.LoadState(filePath) Expect(err).NotTo(HaveOccurred()) Expect(portPoolState.Offset).To(BeNumerically("==", 10)) }) Context("when the file does not exist", func() { It("should return a wrapped error", func() { _, err := ports.LoadState("/path/to/not/existing/banana") Expect(err).To(MatchError(ContainSubstring("openning state file"))) }) }) Context("when the file is invalid", func() { It("should return a wrapped error", func() { Expect(ioutil.WriteFile(filePath, []byte(`{