func main() { flagSet := flag.NewFlagSet("flags", flag.ContinueOnError) flagSet.Var(&recursors, "recursor", "specifies the address of an upstream DNS `server`, may be specified multiple times") flagSet.StringVar(&configFile, "config-file", "", "specifies the config `file`") flagSet.BoolVar(&foreground, "foreground", false, "if true confab will wait for consul to exit") if len(os.Args) < 2 { printUsageAndExit("invalid number of arguments", flagSet) } if err := flagSet.Parse(os.Args[2:]); err != nil { os.Exit(1) } configFileContents, err := ioutil.ReadFile(configFile) if err != nil { stderr.Printf("error reading configuration file: %s", err) os.Exit(1) } cfg, err := config.ConfigFromJSON(configFileContents) if err != nil { stderr.Printf("error reading configuration file: %s", err) os.Exit(1) } path, err := exec.LookPath(cfg.Path.AgentPath) if err != nil { printUsageAndExit(fmt.Sprintf("\"agent_path\" %q cannot be found", cfg.Path.AgentPath), flagSet) } if len(cfg.Path.PIDFile) == 0 { printUsageAndExit("\"pid_file\" cannot be empty", flagSet) } logger := lager.NewLogger("confab") logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.INFO)) agentRunner := &agent.Runner{ Path: path, PIDFile: cfg.Path.PIDFile, ConfigDir: cfg.Path.ConsulConfigDir, Recursors: recursors, Stdout: os.Stdout, Stderr: os.Stderr, Logger: logger, } consulAPIClient, err := api.NewClient(api.DefaultConfig()) if err != nil { panic(err) // not tested, NewClient never errors } agentClient := &agent.Client{ ExpectedMembers: cfg.Consul.Agent.Servers.LAN, ConsulAPIAgent: consulAPIClient.Agent(), ConsulRPCClient: nil, Logger: logger, } retrier := utils.NewRetrier(clock.NewClock(), 1*time.Second) controller := chaperon.Controller{ AgentRunner: agentRunner, AgentClient: agentClient, Retrier: retrier, EncryptKeys: cfg.Consul.EncryptKeys, Logger: logger, ServiceDefiner: config.ServiceDefiner{logger}, ConfigDir: cfg.Path.ConsulConfigDir, Config: cfg, } keyringRemover := chaperon.NewKeyringRemover(cfg.Path.KeyringFile, logger) configWriter := chaperon.NewConfigWriter(cfg.Path.ConsulConfigDir, logger) var r runner = chaperon.NewClient(controller, consulagent.NewRPCClient, keyringRemover, configWriter) if controller.Config.Consul.Agent.Mode == "server" { bootstrapChecker := chaperon.NewBootstrapChecker(logger, agentClient, status.Client{ConsulAPIStatus: consulAPIClient.Status()}, time.Sleep) r = chaperon.NewServer(controller, configWriter, consulagent.NewRPCClient, bootstrapChecker) } switch os.Args[1] { case "start": _, err = os.Stat(controller.Config.Path.ConsulConfigDir) if err != nil { printUsageAndExit(fmt.Sprintf("\"consul_config_dir\" %q could not be found", controller.Config.Path.ConsulConfigDir), flagSet) } if utils.IsRunningProcess(agentRunner.PIDFile) { stderr.Println("consul_agent is already running, please stop it first") os.Exit(1) } if len(agentClient.ExpectedMembers) == 0 { printUsageAndExit("at least one \"expected-member\" must be provided", flagSet) } timeout := utils.NewTimeout(time.After(time.Duration(controller.Config.Confab.TimeoutInSeconds) * time.Second)) if err := r.Start(cfg, timeout); err != nil { stderr.Printf("error during start: %s", err) r.Stop() os.Exit(1) } if foreground { if err := agentRunner.Wait(); err != nil { stderr.Printf("error during wait: %s", err) r.Stop() os.Exit(1) } } case "stop": if err := r.Stop(); err != nil { stderr.Printf("error during stop: %s", err) os.Exit(1) } default: printUsageAndExit(fmt.Sprintf("invalid COMMAND %q", os.Args[1]), flagSet) } }
agentClient = &fakes.AgentClient{} agentClient.VerifySyncedCalls.Returns.Errors = []error{nil} agentRunner = &fakes.AgentRunner{} agentRunner.RunCalls.Returns.Errors = []error{nil} serviceDefiner = &fakes.ServiceDefiner{} confabConfig := config.Config{} confabConfig.Node = config.ConfigNode{Name: "node", Index: 0} controller = chaperon.Controller{ AgentClient: agentClient, AgentRunner: agentRunner, Retrier: utils.NewRetrier(clock, 10*time.Millisecond), EncryptKeys: []string{"key 1", "key 2", "key 3"}, Logger: logger, ConfigDir: "/tmp/config", ServiceDefiner: serviceDefiner, Config: confabConfig, } }) Describe("ConfigureClient", func() { It("writes the pid file", func() { err := controller.ConfigureClient() Expect(err).NotTo(HaveOccurred()) Expect(agentRunner.WritePIDCall.CallCount).To(Equal(1)) })
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("TryUntil", func() { var ( clock *fakes.Clock retrier utils.Retrier retryDelay time.Duration timeout utils.Timeout ) BeforeEach(func() { clock = &fakes.Clock{} retryDelay = 0 timeout = utils.NewTimeout(make(chan time.Time)) retrier = utils.NewRetrier(clock, retryDelay) }) It("retries till the function is succesful within given timeout", func() { callCount := 0 errorProneFunction := func() error { callCount++ if callCount < 10 { return errors.New("some error occurred") } return nil } err := retrier.TryUntil(timeout, errorProneFunction) Expect(err).NotTo(HaveOccurred())