func runShell(version string) { if os.Getenv("GOBU") != "" { log.Fatalln("Already in boostraped env!") } os.Setenv("GOBU", "1") log.Println(">> You are now in a new GOBU shell. To exit, type 'exit'") shell := os.Getenv("SHELL") if runtime.GOOS == "windows" { parentID := os.Getppid() parentProcess, err := ps.FindProcess(parentID) if err != nil { log.Fatalln(err) } shell = parentProcess.Executable() } shellBinary := resolveBinary(shell) run(version, shellBinary, []string{shellBinary}) log.Println("Exited gobu shell") }
func destroy(c *cli.Context) { log.Infoln("Destroy") additionalEnvs, err := config.CreateEnvItemsModelFromSlice(MachineParamsAdditionalEnvs.Get()) if err != nil { log.Fatalf("Invalid Environment parameter: %s", err) } configModel, err := config.ReadMachineConfigFileFromDir(MachineWorkdir.Get(), additionalEnvs) if err != nil { log.Fatalln("Failed to read Config file: ", err) } isOK, err := pathutil.IsPathExists(path.Join(MachineWorkdir.Get(), "Vagrantfile")) if err != nil { log.Fatalln("Failed to check 'Vagrantfile' in the WorkDir: ", err) } if !isOK { log.Fatalln("Vagrantfile not found in the WorkDir!") } log.Infof("configModel: %#v", configModel) if err := doCleanup(configModel, "will-be-destroyed"); err != nil { log.Fatalf("Failed to Cleanup: %s", err) } if err := doDestroy(configModel); err != nil { log.Fatalf("Failed to Destroy: %s", err) } log.Infoln("=> Destroy DONE - OK") }
// OnDisconnect event. Terminates MumbleDJ process or retries connection if // automatic connection retries are enabled. func (dj *MumbleDJ) OnDisconnect(e *gumble.DisconnectEvent) { dj.Queue.Reset() if viper.GetBool("connection.retry_enabled") && (e.Type == gumble.DisconnectError || e.Type == gumble.DisconnectKicked) { logrus.WithFields(logrus.Fields{ "interval_secs": fmt.Sprintf("%d", viper.GetInt("connection.retry_interval")), "attempts": fmt.Sprintf("%d", viper.GetInt("connection.retry_attempts")), }).Warnln("Disconnected from server. Retrying connection...") success := false for retries := 0; retries < viper.GetInt("connection.retry_attempts"); retries++ { logrus.Infoln("Retrying connection...") if client, err := gumble.DialWithDialer(new(net.Dialer), viper.GetString("connection.address")+":"+viper.GetString("connection.port"), dj.GumbleConfig, dj.TLSConfig); err == nil { dj.Client = client logrus.Infoln("Successfully reconnected to the server!") success = true break } time.Sleep(time.Duration(viper.GetInt("connection.retry_interval")) * time.Second) } if !success { dj.KeepAlive <- true logrus.Fatalln("Could not reconnect to server. Exiting...") } } else { dj.KeepAlive <- true logrus.Fatalln("Disconnected from server. No reconnect attempts will be made.") } }
func (rs *RingSyndicates) launchSyndicates(k int) { rs.Syndics[k].Lock() defer rs.waitGroup.Done() rs.waitGroup.Add(1) l, err := net.Listen("tcp", fmt.Sprintf(":%d", rs.Syndics[k].config.Port)) if err != nil { log.Fatalln(err) return } var opts []grpc.ServerOption creds, err := credentials.NewServerTLSFromFile(rs.Syndics[k].config.CertFile, rs.Syndics[k].config.KeyFile) if err != nil { log.Fatalln("Error load cert or key:", err) } opts = []grpc.ServerOption{grpc.Creds(creds)} rs.Syndics[k].gs = grpc.NewServer(opts...) if rs.Syndics[k].config.Master { pb.RegisterSyndicateServer(rs.Syndics[k].gs, rs.Syndics[k].server) log.Println("Master starting up on", rs.Syndics[k].config.Port) rs.Syndics[k].gs.Serve(l) } else { //pb.RegisterRingDistServer(s, newRingDistServer()) //log.Printf("Starting ring slave up on %d...\n", cfg.Port) //s.Serve(l) log.Fatalln("Syndicate slaves not implemented yet") } rs.Syndics[k].Unlock() }
func (c *ArtifactsDownloaderCommand) Execute(context *cli.Context) { formatter.SetRunnerFormatter() if len(c.URL) == 0 || len(c.Token) == 0 { logrus.Fatalln("Missing runner credentials") } if c.ID <= 0 { logrus.Fatalln("Missing build ID") } // Create temporary file file, err := ioutil.TempFile("", "artifacts") if err != nil { logrus.Fatalln(err) } file.Close() defer os.Remove(file.Name()) // Download artifacts file err = c.doRetry(func() (bool, error) { return c.download(file.Name()) }) if err != nil { logrus.Fatalln(err) } // Extract artifacts file err = archives.ExtractZipFile(file.Name()) if err != nil { logrus.Fatalln(err) } }
func main() { flag.Parse() cpus := runtime.NumCPU() runtime.GOMAXPROCS(cpus) log.SetFormatter(&log.JSONFormatter{}) log.SetOutput(os.Stderr) if *env == "production" { log.SetLevel(log.WarnLevel) } else { log.SetLevel(log.DebugLevel) } log.Infoln("Starting server...") // load config d, err := ioutil.ReadFile(*configFile) if err != nil { log.Fatalln("[ERROR] read config.yml", err) } cfg, err := config.Load(bytes.NewReader(d), *env) if err != nil { log.Fatalln("[ERROR] config Load", err) } psAll := sphinx.NewSphinx(cfg.PSConfig, cpus) ctx := context.Background() ctx = sphinx.NewContext(ctx, psAll) kami.Context = ctx kami.Serve() }
func (p *Client) Chain() []byte { certs := make([][]byte, len(chainURLs)) var wg sync.WaitGroup for i, url := range chainURLs { wg.Add(1) go func(i int, url string) { defer wg.Done() resp, err := http.Get(url) if err != nil { log.Fatalln(err) return } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatalln(err) return } certs[i] = data }(i, url) } wg.Wait() result := make([]byte, 0, 1024*1024) for _, data := range certs { result = append(result, data...) if result[len(result)-1] != 10 { result = append(result, 10) } } return result }
//NewDBSession creates a new session to manage database data func NewDBSession(database string) *r.Session { conn, err := r.Connect(r.ConnectOpts{ Address: GetKeyValue("database", "address"), Database: database, MaxOpen: 40, }) if err != nil { log.Fatalln(err) return nil } log.Infof("Connected to RethinkDB %s", GetKeyValue("database", "address")) status, err := createDB(database, conn) if err != nil { log.Fatalln(err) } else { log.Info(status) } tables := []string{"Trip", "Place", "User"} total, err := createTables(database, tables, conn) if err != nil { log.Fatalln(err) } else { log.Infof("%d new table(s) created", total) } return conn }
func waitForInterrupts(finished *bool, abortSignal chan os.Signal, doneSignal chan int) { signals := make(chan os.Signal) signal.Notify(signals, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) interrupt := <-signals if finished != nil { *finished = true } // request stop, but wait for force exit for interrupt == syscall.SIGQUIT { log.Warningln("Requested quit, waiting for builds to finish") interrupt = <-signals } log.Warningln("Requested exit:", interrupt) go func() { for { abortSignal <- interrupt } }() select { case newSignal := <-signals: log.Fatalln("forced exit:", newSignal) case <-time.After(common.ShutdownTimeout * time.Second): log.Fatalln("shutdown timedout") case <-doneSignal: } }
// open opens a new database connection with the specified // driver and connection string and returns a store. func open(driver, config string) *sql.DB { db, err := sql.Open(driver, config) if err != nil { logrus.Errorln(err) logrus.Fatalln("database connection failed") } if driver == "mysql" { // per issue https://github.com/go-sql-driver/mysql/issues/257 db.SetMaxIdleConns(0) } setupMeddler(driver) if err := pingDatabase(db); err != nil { logrus.Errorln(err) logrus.Fatalln("database ping attempts failed") } if err := setupDatabase(driver, db); err != nil { logrus.Errorln(err) logrus.Fatalln("migration failed") } cleanupDatabase(db) return db }
func (c *UnregisterCommand) Execute(context *cli.Context) { if !common.DeleteRunner(c.URL, c.Token) { log.Fatalln("Failed to delete runner") } err := c.loadConfig() if err != nil { log.Warningln(err) return } runners := []*common.RunnerConfig{} for _, otherRunner := range c.config.Runners { if otherRunner.RunnerCredentials == c.RunnerCredentials { continue } runners = append(runners, otherRunner) } // check if anything changed if len(c.config.Runners) == len(runners) { return } c.config.Runners = runners // save config file err = c.saveConfig() if err != nil { log.Fatalln("Failed to update", c.ConfigFile, err) } log.Println("Updated", c.ConfigFile) }
func (c *ArchiveCommand) Execute(context *cli.Context) { logrus.SetFormatter( &logrus.TextFormatter{ ForceColors: true, DisableTimestamp: false, }, ) wd, err := os.Getwd() if err != nil { logrus.Fatalln("Failed to get current working directory:", err) } if c.Output == "" { logrus.Fatalln("Missing archive file name!") } c.wd = wd c.files = make(map[string]os.FileInfo) c.processPaths() c.processUntracked() ai, err := os.Stat(c.Output) if err != nil && !os.IsNotExist(err) { logrus.Fatalln("Failed to verify archive:", c.Output, err) } if ai != nil { if !c.isChanged(ai.ModTime()) { logrus.Infoln("Archive is up to date!") return } } c.archive() }
func (c *RunCommand) Execute(context *cli.Context) { svcConfig := &service.Config{ Name: c.ServiceName, DisplayName: c.ServiceName, Description: defaultDescription, Arguments: []string{"run"}, } service, err := service_helpers.New(c, svcConfig) if err != nil { log.Fatalln(err) } if c.Syslog { logger, err := service.SystemLogger(nil) if err == nil { log.AddHook(&ServiceLogHook{logger}) } else { log.Errorln(err) } } err = service.Run() if err != nil { log.Fatalln(err) } }
func doSetup(c *cli.Context) { PrintBitriseHeaderASCIIArt() log.Infoln("[BITRISE_CLI] - Setup") log.Infoln("Detected OS:", runtime.GOOS) switch runtime.GOOS { case "darwin": if err := doSetupOnOSX(); err != nil { log.Fatalln("Setup failed:", err) } case "linux": if err := doSetupOnLinux(); err != nil { log.Fatalln("Setup failed:", err) } default: log.Fatalln("Sorry, unsupported platform :(") } // guide fmt.Println() log.Infoln("We're ready to rock!!") fmt.Println() log.Infoln("To start using bitrise:") log.Infoln("* cd into your project's directory (if you're not there already)") log.Infoln("* call: bitrise init") log.Infoln("* follow the guide") fmt.Println() log.Infoln("That's all :)") }
func (c *VerifyCommand) Execute(context *cli.Context) { userModeWarning(true) err := c.loadConfig() if err != nil { log.Fatalln(err) return } // verify if runner exist runners := []*common.RunnerConfig{} for _, runner := range c.config.Runners { if c.network.VerifyRunner(runner.RunnerCredentials) { runners = append(runners, runner) } } if !c.DeleteNonExisting { return } // check if anything changed if len(c.config.Runners) == len(runners) { return } c.config.Runners = runners // save config file err = c.saveConfig() if err != nil { log.Fatalln("Failed to update", c.ConfigFile, err) } log.Println("Updated", c.ConfigFile) }
func (mr *RunCommand) Execute(context *cli.Context) { svcConfig := &service.Config{ Name: mr.ServiceName, DisplayName: mr.ServiceName, Description: defaultDescription, Arguments: []string{"run"}, Option: service.KeyValue{ "RunWait": mr.runWait, }, } service, err := service_helpers.New(mr, svcConfig) if err != nil { log.Fatalln(err) } if mr.Syslog { log.SetFormatter(new(log.TextFormatter)) logger, err := service.SystemLogger(nil) if err == nil { log.AddHook(&ServiceLogHook{logger, log.InfoLevel}) } else { log.Errorln(err) } } log.AddHook(&mr.sentryLogHook) err = service.Run() if err != nil { log.Fatalln(err) } }
func runVerify(c *cli.Context) { config := common.NewConfig() err := config.LoadConfig(c.String("config")) if err != nil { log.Fatalln(err) return } // verify if runner exist runners := []*common.RunnerConfig{} for _, runner := range config.Runners { if common.VerifyRunner(runner.URL, runner.Token) { runners = append(runners, runner) } } if !c.Bool("delete") { return } // check if anything changed if len(config.Runners) == len(runners) { return } config.Runners = runners // save config file err = config.SaveConfig(c.String("config")) if err != nil { log.Fatalln("Failed to update", c.String("config"), err) } log.Println("Updated", c.String("config")) }
func (s *serv) listen() { switch s.proto { case tcp: ln, err := net.Listen("tcp", s.addr) if err != nil { logrus.Fatalln("net.Listen error", s.addr, err) } s.setalive() if logrus.GetLevel() >= logrus.DebugLevel { logrus.Debugln("listen to", s.addr) } go acceptTCP(ln, s.tcphandler) case udp: udpaddr, err := net.ResolveUDPAddr("udp", s.addr) if err != nil { logrus.Fatalln("net.ResolveUDPAddr error", s.addr, err) } udpconn, err := net.ListenUDP("udp", udpaddr) if err != nil { logrus.Fatalln("net.ListenUDP error", udpaddr, err) } s.setalive() go func() { for { s.udphandler(udpconn) } }() } }
func gameChangeState(ctx *cli.Context) error { connect(true, false) defer closeConn() if len(ctx.Args()) != 3 { logrus.Fatalln("you must enter exactly three arguments, ex: 'otsimoctl game change-state sample-game 0.1.2 validated'") } uniqueName := ctx.Args().Get(0) version := ctx.Args().Get(1) state := ctx.Args().Get(2) ns, err := stringToState(state) if err != nil { logrus.Fatalln("invalid state name:", state) } game, err := registryClient.Get(context.Background(), &apipb.GetGameRequest{UniqueName: uniqueName}) if err != nil { logrus.Fatalf("failed to get game by name. \nname='%s'\nerror=%v", uniqueName, err) } resp, err := registryClient.ChangeReleaseState(context.Background(), &apipb.ValidateRequest{ GameId: game.Id, GameVersion: version, NewState: ns, }) if err != nil { logrus.Fatalf("failed to change state.\nerror=%+v", err) } fmt.Printf("finished, result=%+v\n", resp.Message) return nil }
func dockerClient(c *cli.Context) *docker.Client { if c.String("docker") == "" { log.Fatalln("daemon is required!") } var client *docker.Client var err error if c.Bool("tls") { cert := c.String("cert") if cert == "" { log.Fatalln("cert directory is required!") } cer := fmt.Sprintf("%s/cert.pem", cert) key := fmt.Sprintf("%s/key.pem", cert) ca := fmt.Sprintf("%s/ca.pem", cert) if client, err = docker.NewTLSClient(c.String("docker"), cer, key, ca); err != nil { log.Fatalln(err.Error()) } } else { if client, err = docker.NewClient(c.String("docker")); err != nil { log.Fatalln(err.Error()) } } return client }
func trigger(c *cli.Context) { PrintBitriseHeaderASCIIArt(c.App.Version) if !bitrise.CheckIsSetupWasDoneForVersion(c.App.Version) { log.Warnln(colorstring.Yellow("Setup was not performed for this version of bitrise, doing it now...")) if err := bitrise.RunSetup(c.App.Version, false); err != nil { log.Fatalln("Setup failed:", err) } } startTime := time.Now() // ------------------------ // Input validation // Inventory validation inventoryEnvironments, err := CreateInventoryFromCLIParams(c) if err != nil { log.Fatalf("Failed to create inventory, err: %s", err) } if err := checkCIAndPRModeFromSecrets(inventoryEnvironments); err != nil { log.Fatalf("Failed to check PR and CI mode, err: %s", err) } // Config validation bitriseConfig, err := CreateBitriseConfigFromCLIParams(c) if err != nil { log.Fatalf("Failed to create bitrise cofing, err: %s", err) } // Trigger filter validation triggerPattern := "" if len(c.Args()) < 1 { log.Errorln("No workfow specified!") } else { triggerPattern = c.Args()[0] } if triggerPattern == "" { // no trigger filter specified // list all the available ones and then exit printAvailableTriggerFilters(bitriseConfig.TriggerMap) } workflowToRunID, err := GetWorkflowIDByPattern(bitriseConfig, triggerPattern) if err != nil { log.Fatalf("Faild to select workflow by pattern (%s), err: %s", triggerPattern, err) } log.Infof("Pattern (%s) triggered workflow (%s) ", triggerPattern, workflowToRunID) // Run selected configuration if _, err := runWorkflowWithConfiguration(startTime, workflowToRunID, bitriseConfig, inventoryEnvironments); err != nil { log.Fatalln("Error: ", err) } }
func catalogValidate(ctx *cli.Context) error { if !ctx.Args().Present() { log.Fatalln("enter a valid catalog file path") } _, err := readCatalogFile(ctx.Args().First()) if err != nil { log.Fatalln("error while reading catalog file, error:", err) } fmt.Println("catalog is valid") return nil }
// Run runs the server func (s *Server) Run() error { channel := make(syslog.LogPartsChannel) handler := syslog.NewChannelHandler(channel) server := syslog.NewServer() server.SetFormat(syslog.RFC5424) server.SetHandler(handler) address := viper.GetString("address") switch strings.ToLower(viper.GetString("socket-type")) { case "tcp": if err := server.ListenTCP(address); err != nil { log.Fatalln(err) } case "udp": if err := server.ListenUDP(address); err != nil { log.Fatalln(err) } default: if err := server.ListenTCP(address); err != nil { log.Fatalln(err) } if err := server.ListenUDP(address); err != nil { log.Fatalln(err) } } server.Boot() log.Infof("tinysyslog listening on %s", address) filter := FilterFactory() sink := SinkFactory() mutator := MutatorFactory() go func(channel syslog.LogPartsChannel) { for logParts := range channel { formatted := mutator.Mutate(logParts) filtered := formatted if viper.GetString("filter-type") == "regex" { filtered = filter.Filter(formatted) } if len(filtered) > 0 { if err := sink.Write([]byte(filtered + "\n")); err != nil { log.Errorln(err) } } } }(channel) server.Wait() return nil }
// Message will be passed to server with '-' prefix via various way // + Direct message with the bots // + Use slash command `/working <message>` // + Use cli `working-on <message>` // + Might use Chrome plugin // + ... // Token is secondary param to indicate the user func addItem(c *gin.Context) { // Parse token and message var item Item text := c.PostForm("text") text = strings.TrimSpace(text) if text == "" { log.Fatalln("Message is nil") return } userID := c.PostForm("user_id") userName := c.PostForm("user_name") item.ID = bson.NewObjectId() item.CreatedAt = time.Now() item.Name = userName item.UserID = userID item.Text = text ctx, err := db.NewContext() if err != nil { panic(err) } defer ctx.Close() // Add Item to database err = ctx.C("items").Insert(item) if err != nil { log.Fatalln(err) } // Repost to the target channel channel := os.Getenv("WORKING_CHANNEL") botToken := os.Getenv("BOT_TOKEN") if botToken == "" { log.Fatal("No token provided") os.Exit(1) } s := slack.New(botToken) // <@U024BE7LH|bob> title := "*" + userName + "* is working on: " + text params := slack.PostMessageParameters{} params.IconURL = "http://i.imgur.com/fLcxkel.png" params.Username = "******" s.PostMessage(channel, title, params) }
func run(c *cli.Context) { PrintBitriseHeaderASCIIArt(c.App.Version) log.Debugln("[BITRISE_CLI] - Run") if !bitrise.CheckIsSetupWasDoneForVersion(c.App.Version) { log.Warnln(colorstring.Yellow("Setup was not performed for this version of bitrise, doing it now...")) if err := bitrise.RunSetup(c.App.Version, false); err != nil { log.Fatalln("Setup failed:", err) } } startTime := time.Now() // Inventory validation inventoryEnvironments, err := CreateInventoryFromCLIParams(c) if err != nil { log.Fatalf("Failed to create inventory, err: %s", err) } if err := checkCIAndPRModeFromSecrets(inventoryEnvironments); err != nil { log.Fatalf("Failed to check PR and CI mode, err: %s", err) } // Config validation bitriseConfig, err := CreateBitriseConfigFromCLIParams(c) if err != nil { log.Fatalf("Failed to create bitrise config, err: %s", err) } // Workflow validation workflowToRunID := "" if len(c.Args()) < 1 { log.Errorln("No workfow specified!") } else { workflowToRunID = c.Args()[0] } if workflowToRunID == "" { // no workflow specified // list all the available ones and then exit printAvailableWorkflows(bitriseConfig) } if strings.HasPrefix(workflowToRunID, "_") { // util workflow specified // print about util workflows and then exit printAboutUtilityWorkflos() } // Run selected configuration if _, err := runWorkflowWithConfiguration(startTime, workflowToRunID, bitriseConfig, inventoryEnvironments); err != nil { log.Fatalln("Error: ", err) } }
func testDial(f, s string, t *testing.T) { srv := NewServe() srv.HandleFunc(s, testDialServe0) d := NewDialer() d.Setup(f) conn, err := d.Dial() if err != nil { logrus.Fatalln("dialer dial error", err) t.Fail() return } enc := gob.NewEncoder(conn) dec := gob.NewDecoder(conn) in := test{N: 1} for { in.Buf = randomBytes(buffersize * 2) err := enc.Encode(in) if err != nil { logrus.Fatalln("dialer write error", err) t.Fail() break } out := test{} err = dec.Decode(&out) if err != nil { logrus.Warnln("dialer read error", err) t.Fail() break } if out.N != in.N+1 { t.Fail() break } if len(out.Buf) != len(in.Buf) { t.Fail() break } in.N = out.N + 1 if out.N > 100 { break } } conn.Close() }
func catalogApprove(ctx *cli.Context) error { connect(false, true) defer closeConn() if !ctx.Args().Present() { log.Fatalln("enter a valid catalog title") } title := ctx.Args().First() _, err := catalogClient.Approve(context.Background(), &apipb.CatalogApproveRequest{Title: title}) if err != nil { log.Fatalln(err) } fmt.Printf("Catalog '%s' approved\n", title) return nil }
// Open opens a new database connection with the specified // driver and connection string and returns a store. func Open(driver, config string) *sql.DB { db, err := sql.Open(driver, config) if err != nil { log.Errorln(err) log.Fatalln("database connection failed") } setupMeddler(driver) if err := setupDatabase(driver, db); err != nil { log.Errorln(err) log.Fatalln("migration failed") } return db }
func doInit(c *cli.Context) { log.Info("[BITRISE_CLI] - Init -- Work-in-progress!") bitriseConfigFileRelPath := "./bitrise.yml" if exists, err := pathutil.IsPathExists(bitriseConfigFileRelPath); err != nil { log.Fatalln("Error:", err) } else if exists { ask := fmt.Sprintf("A config file already exists at %s - do you want to overwrite it?", bitriseConfigFileRelPath) if val, err := goinp.AskForBool(ask); err != nil { log.Fatalln("Error:", err) } else if val == false { log.Infoln("Init canceled, existing file won't be overwritten.") os.Exit(0) } } projectSettingsEnvs := []models.EnvironmentItemModel{} if val, err := goinp.AskForString("What's the BITRISE_PROJECT_TITLE?"); err != nil { log.Fatalln(err) } else { projectSettingsEnvs = append(projectSettingsEnvs, models.EnvironmentItemModel{"BITRISE_PROJECT_TITLE": val, "is_expand": "no"}) } if val, err := goinp.AskForString("What's your primary development branch's name?"); err != nil { log.Fatalln(err) } else { projectSettingsEnvs = append(projectSettingsEnvs, models.EnvironmentItemModel{"BITRISE_DEV_BRANCH": val, "is_expand": "no"}) } // TODO: // generate a couple of base steps // * timestamp gen // * bash script bitriseConf := models.BitriseConfigModel{ FormatVersion: "1.0.0", // TODO: move this into a project config file! App: models.AppModel{ Environments: projectSettingsEnvs, }, Workflows: map[string]models.WorkflowModel{ "primary": models.WorkflowModel{}, }, } if err := SaveToFile(bitriseConfigFileRelPath, bitriseConf); err != nil { log.Fatalln("Failed to init:", err) } os.Exit(1) }
func createApi(cmd *cobra.Command) *api.Api { log.Debug("create api") c, err := config.NewFromCli(cmd) if err != nil { log.Fatalln(errors.Annotate(err, "new config")) } api, err := api.New(c) if err != nil { log.Fatalln(errors.Annotate(err, "new api")) } return api }