コード例 #1
0
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)
	}
}
コード例 #2
0
		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))
		})
コード例 #3
0
	. "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())