func SecureYamlCmd(c *cli.Context, client drone.Client) error { var ( repo = c.String("repo") inFile = c.String("in") outFile = c.String("out") ymlFile = c.String("yaml") checksum = c.BoolT("checksum") ) owner, name, err := parseRepo(repo) if err != nil { return err } keypair, err := client.RepoKey(owner, name) if err != nil { return err } key, err := toPublicKey(keypair.Public) if err != nil { return err } // read the .drone.sec.yml file (plain text) plaintext, err := readInput(inFile) if err != nil { return err } // parse the .drone.sec.yml file sec := new(secure.Secure) err = yaml.Unmarshal(plaintext, sec) if err != nil { return err } // read the .drone.yml file and caclulate the // checksum. add to the .drone.sec.yml file. yml, err := ioutil.ReadFile(ymlFile) if err == nil && checksum { sec.Checksum = sha256sum(string(yml)) } // re-marshal the .drone.sec.yml file since we've // added the checksum plaintext, err = yaml.Marshal(sec) if err != nil { return err } // encrypt the .drone.sec.yml file ciphertext, err := encrypt(plaintext, key) if err != nil { return err } // write the encrypted .drone.sec.yml file to .drone.sec return writeOutput(outFile, ciphertext) }
func serve(c *cli.Context) { // Ensure api socket directory exists; if not, create it apiSocket := getApiSocket(c) if _, err := os.Stat(apiSocket); os.IsNotExist(err) { os.MkdirAll(path.Dir(apiSocket), 0777) } d := dokku.New() // If caching is enabled, create cache socket if necessary and launch cache // server in the background if !c.BoolT("enable-cache") { cacheSocket := getCacheSocket(c) if _, err := os.Stat(cacheSocket); os.IsNotExist(err) { os.MkdirAll(path.Dir(cacheSocket), 0777) } go func() { err := listenCache(d, cacheSocket) if err != nil { panic(err) } }() } // Start api server err := listenAPI(d, apiSocket) if err != nil { panic(err) } }
// Migrate runs migrations func Migrate(ctx *cli.Context) { if ctx.BoolT("d") { // run migrations migration.DropTables() } migration.MigrateTables() query.PopulateDB() }
// helper function to setup the GitHub remote from the CLI arguments. func setupGithub(c *cli.Context) (remote.Remote, error) { return github.New(github.Opts{ URL: c.String("github-server"), Client: c.String("github-client"), Secret: c.String("github-sercret"), Scopes: c.StringSlice("github-scope"), Username: c.String("github-git-username"), Password: c.String("github-git-password"), PrivateMode: c.Bool("github-private-mode"), SkipVerify: c.Bool("github-skip-verify"), MergeRef: c.BoolT("github-merge-ref"), }) }
func cmdLogsStream(c *cli.Context) { _, app, err := stdcli.DirApp(c, ".") if err != nil { stdcli.Error(err) return } err = rackClient(c).StreamAppLogs(app, c.String("filter"), c.BoolT("follow"), c.Duration("since"), os.Stdout) if err != nil { stdcli.Error(err) return } }
func getOptions(c *cli.Context) ([]magpie.Option, error) { var options []magpie.Option if c.IsSet(tagFlag) { options = append(options, magpie.Tags(c.StringSlice(tagFlag))) } if c.IsSet(prefixFlag) { options = append(options, magpie.Prefix(c.String(prefixFlag))) } if c.IsSet(packageNameFlag) { options = append(options, magpie.PackageName(c.String(packageNameFlag))) } if c.IsSet(unsafeFlag) { options = append(options, magpie.Unsafe(c.Bool(unsafeFlag))) } if c.IsSet(compressFlag) { options = append(options, magpie.Compress(c.BoolT(compressFlag))) } if c.IsSet(fileModeFlag) { fileMode := c.String(fileModeFlag) if fileMode != "" { n, err := strconv.ParseUint(fileMode, 10, 32) if err != nil { return nil, err } options = append(options, magpie.OverrideFileMode(uint(n))) } } if c.IsSet(fileModTimeFlag) { fileMod := c.String(fileModTimeFlag) if fileMod != "" { n, err := strconv.ParseInt(fileMod, 10, 64) if err != nil { return nil, err } options = append(options, magpie.OverrideFileModTime(n)) } } if c.IsSet(outputFlag) { options = append(options, magpie.OutputFile(c.String(outputFlag))) } if c.IsSet(ignoreFlag) { options = append(options, magpie.Ignore(c.StringSlice(ignoreFlag))) } return options, nil }
func server(ctx *cli.Context) { cfgFile := configName if first := ctx.Args().First(); first != "" { cfgFile = first } cfg, err := getConfig(cfgFile) if err != nil { fmt.Println(err) return } s := hero.NewServer(cfg, &hero.SimpleTokenGen{}, nil) if ctx.BoolT("migrate") { s.Migrate() } s.Run() }
func create(c *cli.Context) { checkArgs(c) d := dogo.Droplet{ Name: c.Args().First(), ImageID: c.Int("image"), SizeID: dogo.SizesMap[c.String("size")], RegionID: dogo.RegionsMap[c.String("region")], BackupsActive: c.BoolT("backups"), } keys := c.IntSlice("keys") network := c.BoolT("network") _, err := docli.CreateDroplet(d, keys, network) if err != nil { fatalf(err.Error()) } fmt.Printf("Successfully queued %s for creation ... \n", d.Name) }
func clirun(c *cli.Context) { config := &Config{ Dest: c.String("dest"), Name: c.String("name"), Data: make(map[string]string), OpenEditor: c.BoolT("open-editor"), } src := c.String("src") if len(src) > 0 { config.Source = &DirectorySource{Path: src} } else { config.Source = &GithubReleaseSource{ Tag: c.String("gh-tag"), Owner: c.String("gh-owner"), Repo: c.String("gh-repo"), Name: c.String("skel"), } } data := c.String("data") if len(data) > 0 { info, err := os.Stat(data) if err != nil || info.IsDir() { log.Printf("Couldn't open %s. Skipping.\n", data) } else { content, err := ioutil.ReadFile(data) if err != nil { log.Printf("Failed to read data file. Skipping. Error was: %s\n", err) } err = yaml.Unmarshal(content, &config.Data) if err != nil { log.Printf("Failed to unmarshall data file: %s.\n", err) } } } if err := Run(config); err != nil { log.Fatal(err) } }
func LoadConfig(ctx *cli.Context) { var contents []byte if _, err := os.Stat(CONFIG_FILE); err != nil && CONFIG_FILE != "/dev/null" { fmt.Printf("Unable to find config file. Resorting to defaults.\n") } else { contents = handle_err(ioutil.ReadFile(CONFIG_FILE)).([]byte) err := json.Unmarshal(contents, &RC) if err != nil && CONFIG_FILE != "/dev/null" { fmt.Printf("Error reading config file (%s): %v.\n", CONFIG_FILE, err) } } // Override config file values with CLI options if &RC.Host == nil || ctx.IsSet("host") { RC.Host = ctx.String("host") } if &RC.Port == nil || ctx.IsSet("port") { RC.Port = ctx.Int("port") } if &RC.Nick == nil || ctx.IsSet("nick") { RC.Nick = ctx.String("nick") } if &RC.Channel == nil || ctx.IsSet("channel") { RC.Channel = ctx.String("channel") } if &RC.SSL == nil { RC.SSL = ctx.BoolT("insecure") } if &RC.Verbose == nil { RC.Verbose = ctx.Bool("verbose") } RC.VTClient = govt.Client{Apikey: RC.VTAPIKey, Url: "https://www.virustotal.com/vtapi/v2/"} }
func doAlertsList(c *cli.Context) error { conffile := c.GlobalString("conf") filterServices := c.StringSlice("service") filterStatuses := c.StringSlice("host-status") client := newMackerel(conffile) alerts, err := client.FindAlerts() logger.DieIf(err) joinedAlerts := joinMonitorsAndHosts(client, alerts) for _, joinAlert := range joinedAlerts { if len(filterServices) > 0 { found := false for _, filterService := range filterServices { if joinAlert.Host != nil { if _, ok := joinAlert.Host.Roles[filterService]; ok { found = true } } else if joinAlert.Monitor.Service == filterService { found = true } } if !found { continue } } if len(filterStatuses) > 0 { found := false for _, filterStatus := range filterStatuses { if joinAlert.Host != nil && joinAlert.Host.Status == filterStatus { found = true } } if !found { continue } } fmt.Println(formatJoinedAlert(joinAlert, c.BoolT("color"))) } return nil }
func AddAttachment(c *cli.Context) { objectId := helper.ValidId(c.Args().First()) attachmentPath := c.Args().Get(1) object, err := data.GetObject(objectId) helper.ErrExit(err != nil, fmt.Sprintf("Invalid object ID %s!\n", objectId)) dbFile, err := data.Files().Create("") helper.ErrPanic(err) file, err := os.Open(attachmentPath) helper.ErrPanic(err) defer file.Close() _, err = io.Copy(dbFile, file) helper.ErrPanic(err) err = dbFile.Close() helper.ErrPanic(err) var ( content = "" metadata = make(map[string]string) ) if strings.ToLower(filepath.Ext(file.Name())) == ".pdf" { if c.BoolT("extract-pdf-text") { content, metadata, err = helper.ConvertPDF(file) helper.ErrPanic(err) } } attachment := data.CreateAttachment(dbFile, path.Base(attachmentPath), content, metadata) object.Attachments = append(object.Attachments, *attachment) object.Update() fmt.Println(attachment.Id.Hex()) }
func loadConfig(c *cli.Context) { if len(c.Args()) > 0 { config_path := c.Args()[0] _, err := toml.DecodeFile(config_path, &Config) checkErr(err) log.Printf("loaded configuration from %s %+v\n", config_path, Config) } if c.IsSet("db-log") == true { Config.DBLog = c.Bool("db-log") } if c.IsSet("development") == true { Config.Development = c.BoolT("development") } if c.IsSet("database") == true { Config.DBPath = c.String("database") } if c.IsSet("port") == true { Config.Port = c.Int("port") } }
// New TODO func New(context *cli.Context) *Config { // TODO: parse this more gracefully loggingLevel := logrus.DebugLevel logLevelArg := context.String(logLevel) var err error loggingLevel, err = logrus.ParseLevel(logLevelArg) if err != nil { loggingLevel = logrus.DebugLevel } return &Config{ ServiceName: context.String(serviceName), ServiceVerion: context.String(serviceVersion), EndpointHost: context.String(endpointHost), EndpointPort: context.Int(endpointPort), LogstashServer: context.String(logstashServer), Register: context.BoolT(register), Proxy: context.BoolT(proxy), Log: context.BoolT(log), Supervise: context.Bool(supervise), Controller: Controller{ URL: context.String(controllerURL), Poll: context.Duration(controllerPoll), }, Tenant: Tenant{ ID: context.String(tenantID), Token: context.String(tenantToken), TTL: context.Duration(tenantTTL), Heartbeat: context.Duration(tenantHeartbeat), }, Registry: Registry{ URL: context.String(registryURL), Token: context.String(registryToken), }, Kafka: Kafka{ Username: context.String(kafkaUsername), Password: context.String(kafkaPassword), APIKey: context.String(kafkaToken), RestURL: context.String(kafkaRestURL), Brokers: context.StringSlice(kafkaBrokers), SASL: context.Bool(kafkaSASL), }, Nginx: Nginx{ Port: context.Int(nginxPort), }, LogLevel: loggingLevel, AppArgs: context.Args(), } }
func server(ctx *cli.Context) { cfgFile := configName if first := ctx.Args().First(); first != "" { cfgFile = first } cfg, err := getConfig(cfgFile) if err != nil { fmt.Println(err) return } s := hero.NewServer(cfg, &hero.SimpleTokenGen{}, nil) if ctx.BoolT("dev") { v, err := hero.NewDefaultView(cfg.TemplatesDir, true) if err != nil { fmt.Println(err) return } s = hero.NewServer(cfg, &hero.SimpleTokenGen{}, v) } if ctx.BoolT("migrate") { s.Migrate() } if ctx.BoolT("https") { cert := ctx.String("cert") _, ferr := os.Stat(cert) if ferr != nil { fmt.Println(ferr) return } key := ctx.String("key") _, ferr = os.Stat(cert) if ferr != nil { fmt.Println(ferr) return } s.RunTLS(cert, key) return } s.Run() }
func pinCommand(ctx *cli.Context) { initLogs(ctx) var ( vars template.Vars data []byte output = ctx.String("output") format = ctx.String("type") local = ctx.BoolT("local") hub = ctx.BoolT("hub") fd = os.Stdout ) if output == "-" && !ctx.GlobalIsSet("verbose") { log.SetLevel(log.WarnLevel) } dockerCli := initDockerClient(ctx) config := initComposeConfig(ctx, dockerCli) auth := initAuthConfig(ctx) compose, err := compose.New(&compose.Config{ Manifest: config, Docker: dockerCli, Auth: auth, }) if err != nil { log.Fatal(err) } if vars, err = compose.PinAction(local, hub); err != nil { log.Fatal(err) } if output != "-" { if fd, err = os.Create(output); err != nil { log.Fatal(err) } defer fd.Close() if ext := filepath.Ext(output); !ctx.IsSet("type") && ext == ".json" { format = "json" } } switch format { case "yaml": if data, err = yaml.Marshal(vars); err != nil { log.Fatal(err) } case "json": if data, err = json.Marshal(vars); err != nil { log.Fatal(err) } default: log.Fatalf("Possible tyoes are `yaml` and `json`, unknown type `%s`", format) } if _, err := io.Copy(fd, bytes.NewReader(data)); err != nil { log.Fatal(err) } }
func defaultAction(c *cli.Context) { thisCfg := new(AppCfg) thisCfg.Lines = c.Int("lines") thisCfg.Fail = c.Bool("fail") thisCfg.Color = c.BoolT("color") // If no flag, get current username u := c.String("user") if len(u) == 0 { usr, err := user.Current() if err == nil { u = usr.Username } } // Load SSH keys auths, err := getKeyAuths(c.GlobalStringSlice("key")...) if err != nil { log.Error("Error loading key", err) } if len(auths) == 0 { log.Error("No keys defined, cannot continue!", nil) cli.ShowAppHelp(c) os.Exit(2) } for _, target := range c.StringSlice("server") { thisHost := &HostConfig{ User: u, Auths: auths, Addr: portAddrCheck(target), } thisCfg.Hosts = append(thisCfg.Hosts, thisHost) } // host(s) is required if len(thisCfg.Hosts) == 0 { log.Error("At least one host is required", nil) cli.ShowAppHelp(c) os.Exit(2) } // At least one command is required if len(c.Args().First()) == 0 { log.Error("At least one command is required", nil) cli.ShowAppHelp(c) os.Exit(2) } // append list of commands to argList thisCfg.Cmds = append([]string{c.Args().First()}, c.Args().Tail()...) done := make(chan bool, len(thisCfg.Hosts)) for _, h := range thisCfg.Hosts { go handleHost(h, thisCfg.Cmds, thisCfg.Color, thisCfg.Lines, thisCfg.Fail, done) } // Drain chan before exiting for i := 0; i < len(thisCfg.Hosts); i++ { <-done } }
func getCert(c *cli.Context) { configPath := c.String("config-file") environment := c.String("environment") certRequestID := c.Args().First() allConfig := make(map[string]ssh_ca_util.RequesterConfig) err := ssh_ca_util.LoadConfig(configPath, &allConfig) wrongTypeConfig, err := ssh_ca_util.GetConfigForEnv(environment, &allConfig) if err != nil { fmt.Println(err) os.Exit(1) } config := wrongTypeConfig.(ssh_ca_util.RequesterConfig) getResp, err := http.Get(config.SignerUrl + "cert/requests/" + certRequestID) if err != nil { fmt.Println("Didn't get a valid response", err) os.Exit(1) } getRespBuf, err := ioutil.ReadAll(getResp.Body) if err != nil { fmt.Println("Error reading response body", err) os.Exit(1) } getResp.Body.Close() if getResp.StatusCode != 200 { fmt.Println("Error getting that request id:", string(getRespBuf)) os.Exit(1) } pubKey, _, _, _, err := ssh.ParseAuthorizedKey(getRespBuf) if err != nil { fmt.Println("Trouble parsing response", err) os.Exit(1) } cert := pubKey.(*ssh.Certificate) secondsRemaining := int64(cert.ValidBefore) - int64(time.Now().Unix()) if secondsRemaining < 1 { fmt.Println("This certificate has already expired.") os.Exit(1) } pubKeyPath, err := findKeyLocally(cert.Key) if err != nil { fmt.Println(err) os.Exit(1) } pubKeyPath = strings.Replace(pubKeyPath, ".pub", "-cert.pub", 1) err = ioutil.WriteFile(pubKeyPath, getRespBuf, 0644) if err != nil { fmt.Printf("Couldn't write certificate file to %s: %s\n", pubKeyPath, err) } ssh_ca_util.PrintForInspection(*cert) if c.BoolT("add-key") { privKeyPath := strings.Replace(pubKeyPath, "-cert.pub", "", 1) cmd := exec.Command("ssh-add", "-t", fmt.Sprintf("%d", secondsRemaining), privKeyPath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin err = cmd.Run() if err != nil { fmt.Println("Error in ssh-add") os.Exit(1) } } }
func (b *base) listGo(ctx *cli.Context) { if ctx.BoolT("i") { writeLn("list") } }
// New TODO func New(context *cli.Context) *Config { // TODO: parse this more gracefully loggingLevel := logrus.DebugLevel logLevelArg := context.String(logLevel) var err error loggingLevel, err = logrus.ParseLevel(logLevelArg) if err != nil { loggingLevel = logrus.DebugLevel } endpointHost := context.String(endpointHost) if endpointHost == "" { for { endpointHost = LocalIP() if endpointHost != "" { break } logrus.Warn("Could not obtain local IP") time.Sleep(time.Second * 10) } } var name string var version string i := strings.Index(context.String(serviceName), ":") if i == -1 { name = context.String(serviceName) } else { name = context.String(serviceName)[:i] version = context.String(serviceName)[i+1:] } return &Config{ ServiceName: name, ServiceVersion: version, EndpointHost: endpointHost, EndpointPort: context.Int(endpointPort), EndpointType: context.String(endpointType), LogstashServer: context.String(logstashServer), Register: context.BoolT(register), Proxy: context.BoolT(proxy), Log: context.BoolT(log), Supervise: context.Bool(supervise), Controller: Controller{ URL: context.String(controllerURL), Poll: context.Duration(controllerPoll), }, Tenant: Tenant{ Token: context.String(tenantToken), TTL: context.Duration(tenantTTL), Heartbeat: context.Duration(tenantHeartbeat), }, Registry: Registry{ URL: context.String(registryURL), Token: context.String(registryToken), }, Kafka: Kafka{ Username: context.String(kafkaUsername), Password: context.String(kafkaPassword), APIKey: context.String(kafkaToken), RestURL: context.String(kafkaRestURL), Brokers: context.StringSlice(kafkaBrokers), SASL: context.Bool(kafkaSASL), }, Nginx: Nginx{ Port: context.Int(nginxPort), }, LogLevel: loggingLevel, AppArgs: context.Args(), ForceUpdate: context.Bool(forceUpdate), } }
func start(c *cli.Context) { // debug level if requested by user if c.Bool("debug") { logrus.SetLevel(logrus.DebugLevel) } else { logrus.SetLevel(logrus.WarnLevel) } var accessToken string if c.String("drone-secret") != "" { secretToken := c.String("drone-secret") accessToken, _ = token.New(token.AgentToken, "").Sign(secretToken) } else { accessToken = c.String("drone-token") } logrus.Infof("Connecting to %s with token %s", c.String("drone-server"), accessToken, ) client := client.NewClientToken( c.String("drone-server"), accessToken, ) tls, err := dockerclient.TLSConfigFromCertPath(c.String("docker-cert-path")) if err == nil { tls.InsecureSkipVerify = c.Bool("docker-tls-verify") } docker, err := dockerclient.NewDockerClient(c.String("docker-host"), tls) if err != nil { logrus.Fatal(err) } go func() { for { if err := client.Ping(); err != nil { logrus.Warnf("unable to ping the server. %s", err.Error()) } time.Sleep(c.Duration("ping")) } }() var wg sync.WaitGroup for i := 0; i < c.Int("docker-max-procs"); i++ { wg.Add(1) go func() { r := pipeline{ drone: client, docker: docker, config: config{ platform: c.String("docker-os") + "/" + c.String("docker-arch"), timeout: c.Duration("timeout"), namespace: c.String("namespace"), privileged: c.StringSlice("privileged"), pull: c.BoolT("pull"), logs: int64(c.Int("max-log-size")) * 1000000, }, } for { if err := r.run(); err != nil { dur := c.Duration("backoff") logrus.Warnf("reconnect in %v. %s", dur, err.Error()) time.Sleep(dur) } } }() } handleSignals() wg.Wait() }
func exec(c *cli.Context) error { sigterm := make(chan os.Signal, 1) cancelc := make(chan bool, 1) signal.Notify(sigterm, os.Interrupt) go func() { <-sigterm cancelc <- true }() path := c.Args().First() if path == "" { path = ".drone.yml" } path, _ = filepath.Abs(path) dir := filepath.Dir(path) file, err := ioutil.ReadFile(path) if err != nil { return err } engine, err := docker.New( c.String("docker-host"), c.String("docker-cert-path"), c.Bool("docker-tls-verify"), ) if err != nil { return err } a := agent.Agent{ Update: agent.NoopUpdateFunc, Logger: agent.TermLoggerFunc, Engine: engine, Timeout: c.Duration("timeout.inactivity"), Platform: "linux/amd64", Namespace: c.String("namespace"), Disable: c.StringSlice("plugin"), Escalate: c.StringSlice("privileged"), Netrc: []string{}, Local: dir, Pull: c.Bool("pull"), } payload := &model.Work{ Yaml: string(file), Verified: c.BoolT("yaml.verified"), Signed: c.BoolT("yaml.signed"), Repo: &model.Repo{ FullName: c.String("repo.fullname"), Owner: c.String("repo.owner"), Name: c.String("repo.name"), Kind: c.String("repo.type"), Link: c.String("repo.link"), Branch: c.String("repo.branch"), Avatar: c.String("repo.avatar"), Timeout: int64(c.Duration("timeout").Minutes()), IsPrivate: c.Bool("repo.private"), IsTrusted: c.Bool("repo.trusted"), Clone: c.String("remote.url"), }, System: &model.System{ Link: c.GlobalString("server"), }, Secrets: getSecrets(c), Netrc: &model.Netrc{ Login: c.String("netrc.username"), Password: c.String("netrc.password"), Machine: c.String("netrc.machine"), }, Build: &model.Build{ Commit: c.String("commit.sha"), Branch: c.String("commit.branch"), Ref: c.String("commit.ref"), Link: c.String("commit.link"), Message: c.String("commit.message"), Author: c.String("commit.author.name"), Email: c.String("commit.author.email"), Avatar: c.String("commit.author.avatar"), Number: c.Int("build.number"), Event: c.String("build.event"), Deploy: c.String("build.deploy"), }, BuildLast: &model.Build{ Number: c.Int("prev.build.number"), Status: c.String("prev.build.status"), Commit: c.String("prev.commit.sha"), }, } if len(c.StringSlice("matrix")) > 0 { p := *payload p.Job = &model.Job{ Environment: getMatrix(c), } return a.Run(&p, cancelc) } axes, err := yaml.ParseMatrix(file) if err != nil { return err } if len(axes) == 0 { axes = append(axes, yaml.Axis{}) } var jobs []*model.Job count := 0 for _, axis := range axes { jobs = append(jobs, &model.Job{ Number: count, Environment: axis, }) count++ } for _, job := range jobs { fmt.Printf("Running Matrix job #%d\n", job.Number) p := *payload p.Job = job if err := a.Run(&p, cancelc); err != nil { return err } } return nil }
func start(c *cli.Context) { log := redlog.New(os.Stderr) log.SetLevel(0) logger.SetLogger(log) // debug level if requested by user if c.Bool("debug") { logrus.SetLevel(logrus.DebugLevel) log.SetLevel(1) } else { logrus.SetLevel(logrus.WarnLevel) } var accessToken string if c.String("drone-secret") != "" { // secretToken := c.String("drone-secret") accessToken = c.String("drone-secret") // accessToken, _ = token.New(token.AgentToken, "").Sign(secretToken) } else { accessToken = c.String("drone-token") } logger.Noticef("connecting to server %s", c.String("drone-server")) server := strings.TrimRight(c.String("drone-server"), "/") tls, err := dockerclient.TLSConfigFromCertPath(c.String("docker-cert-path")) if err == nil { tls.InsecureSkipVerify = c.Bool("docker-tls-verify") } docker, err := dockerclient.NewDockerClient(c.String("docker-host"), tls) if err != nil { logrus.Fatal(err) } var client *stomp.Client handler := func(m *stomp.Message) { running.Add(1) defer func() { running.Done() client.Ack(m.Ack) }() r := pipeline{ drone: client, docker: docker, config: config{ platform: c.String("docker-os") + "/" + c.String("docker-arch"), timeout: c.Duration("timeout"), namespace: c.String("namespace"), privileged: c.StringSlice("privileged"), pull: c.BoolT("pull"), logs: int64(c.Int("max-log-size")) * 1000000, }, } work := new(model.Work) m.Unmarshal(work) r.run(work) } handleSignals() backoff := c.Duration("backoff") for { // dial the drone server to establish a TCP connection. client, err = stomp.Dial(server) if err != nil { logger.Warningf("connection failed, retry in %v. %s", backoff, err) <-time.After(backoff) continue } opts := []stomp.MessageOption{ stomp.WithCredentials("x-token", accessToken), } // initialize the stomp session and authenticate. if err = client.Connect(opts...); err != nil { logger.Warningf("session failed, retry in %v. %s", backoff, err) <-time.After(backoff) continue } opts = []stomp.MessageOption{ stomp.WithAck("client"), stomp.WithPrefetch( c.Int("docker-max-procs"), ), } if filter := c.String("filter"); filter != "" { opts = append(opts, stomp.WithSelector(filter)) } // subscribe to the pending build queue. client.Subscribe("/queue/pending", stomp.HandlerFunc(func(m *stomp.Message) { go handler(m) // HACK until we a channel based Subscribe implementation }), opts...) logger.Noticef("connection established, ready to process builds.") <-client.Done() logger.Warningf("connection interrupted, attempting to reconnect.") } }