func (s *Service) prepareNodesAsJsonMap() { if s.manifest.Nodes == nil || len(s.manifest.Nodes.([]interface{})) == 0 { logs.WithFields(s.fields).Warn("No nodes defined in service") return } tmpRes, err := utils.TransformYamlToJson(s.manifest.Nodes) var res []interface{} = tmpRes.([]interface{}) if err != nil { logs.WithEF(err, s.fields).Fatal("Cannot transform yaml to json") } if res[0].(map[string]interface{})[NODE_HOSTNAME].(string) == "*" { if len(res) > 1 { logs.WithFields(s.fields).Fatal("You cannot mix all nodes with single node. Yet ?") } newNodes := *new([]interface{}) machines, err := s.env.ListMachineNames() if err != nil { logs.WithEF(err, s.fields).Fatal("Cannot list machines to generate units") } for _, machine := range machines { node := utils.CopyMap(res[0].(map[string]interface{})) node[NODE_HOSTNAME] = machine newNodes = append(newNodes, node) } res = newNodes } s.nodesAsJsonMap = res }
func (u *Unit) Update(command string) error { if err := u.Service.Generate(); err != nil { logs.WithEF(err, u.Fields).Fatal("Generate failed") } logs.WithFields(u.Fields).Debug("Update") u.runHook(EARLY, command, "update") defer u.runHook(LATE, command, "update") u.Service.Lock(command, 1*time.Hour, "Update "+u.Name) defer u.Service.Unlock(command) same, err := u.IsLocalContentSameAsRemote() if err != nil { logs.WithEF(err, u.Fields).Warn("Cannot compare local and remote service") } if same { logs.WithFields(u.Fields).Info("Remote service is already up to date") if !u.IsRunning() { logs.WithFields(u.Fields).Info("But service is not running") } else if !BuildFlags.Force { return nil } } u.UpdateInside(command) return nil }
func (p *Pod) Push() { logs.WithF(p.fields).Info("Pushing") p.Build() checkVersion := make(chan bool, 1) for _, e := range p.manifest.Pod.Apps { aci, err := NewAciWithManifest(p.path+"/"+e.Name, p.args, p.toAciManifest(e), &checkVersion) if err != nil { logs.WithEF(err, p.fields.WithField("name", e.Name)).Fatal("Cannot prepare aci") } aci.podName = &p.manifest.Name aci.Push() } for range p.manifest.Pod.Apps { <-checkVersion } if err := utils.ExecCmd("curl", "-i", "-F", "r=releases", "-F", "hasPom=false", "-F", "e=pod", "-F", "g=com.blablacar.aci.linux.amd64", "-F", "p=pod", "-F", "v="+p.manifest.Name.Version(), "-F", "a="+p.manifest.Name.ShortName(), "-F", "file=@"+p.target+"/pod-manifest.json", "-u", cnt.Home.Config.Push.Username+":"+cnt.Home.Config.Push.Password, cnt.Home.Config.Push.Url+"/service/local/artifact/maven/content"); err != nil { logs.WithEF(err, p.fields).Fatal("Cannot push pod") } }
func (s *Service) runNotify() { s.runNotifyMutex.Lock() defer s.runNotifyMutex.Unlock() s.giveUpWarmup() if s.currentStatus == nil { logs.WithF(s.fields).Info("No status to notify") return } if (*s.currentStatus == nil && s.disabled == nil) || s.forceEnable { logs.WithF(s.fields).Info("Service is available") if len(s.PreAvailableCommand) > 0 { if err := ExecCommand(s.PreAvailableCommand, s.PreAvailableMaxDurationInMilli); err != nil { s.nerve.execFailureCount.WithLabelValues(s.Name, "pre-available", s.Host, strconv.Itoa(s.Port)).Inc() logs.WithEF(err, s.fields).Warn("Pre available command failed") } } s.warmup() } else { if !s.NoMetrics { s.nerve.availableGauge.WithLabelValues(s.Name, s.Host, strconv.Itoa(s.Port)).Set(0) } s.currentWeightIndex = 0 logs.WithEF(*s.currentStatus, s.fields).Warn("Service is not available") s.reportAndTellIfAtLeastOneReported(true) } }
func NewHome(path string) HomeStruct { logs.WithField("path", path).Debug("Loading home") var config Config if source, err := ioutil.ReadFile(path + "/config.yml"); err == nil { err = yaml.Unmarshal([]byte(source), &config) if err != nil { logs.WithEF(err, data.WithField("path", path+"/config.yml")).Fatal("Failed to process configuration file") } } else if source, err := ioutil.ReadFile(DefaultHomeFolder("cnt") + "/config.yml"); err == nil { logs.WithField("old", DefaultHomeFolder("cnt")+"/config.yml").WithField("new", DefaultHomeFolder("")).Warn("You are using old home folder") err = yaml.Unmarshal([]byte(source), &config) if err != nil { logs.WithEF(err, data.WithField("path", path+"/config.yml")).Fatal("Failed to process configuration file") } } if Args.NoStore { config.Rkt.NoStore = true } if Args.StoreOnly { config.Rkt.StoreOnly = true } rkt, err := common.NewRktClient(config.Rkt) if err != nil { logs.WithEF(err, data.WithField("config", config.Rkt)).Fatal("Rkt access failed") } return HomeStruct{ path: path, Config: config, Rkt: rkt, } }
func (c *CheckCommon) CommonRun(checker Checker, statusChange chan<- Check, stop <-chan struct{}, doneWait *sync.WaitGroup) { logs.WithF(c.fields).Info("Starting check") doneWait.Add(1) defer doneWait.Done() for { status := checker.Check() if logs.IsTraceEnabled() { logs.WithEF(status, c.fields).Trace("Check done") } if status != nil { logs.WithEF(status, c.fields).Debug("Failed check") } if status != nil && !c.service.NoMetrics { c.service.nerve.checkerFailureCount.WithLabelValues(c.service.Name, c.Host, strconv.Itoa(c.Port), c.Type).Inc() } c.saveStatus(status) current := c.stableStatus latest := c.latestStatuses if (latest[0] == nil && sameLastStatusCount(latest) >= c.Rise && (current == nil || *current != nil)) || (latest[0] != nil && sameLastStatusCount(latest) >= c.Fall && (current == nil || *current == nil)) { c.stableStatus = &status statusChange <- Check{checker, *c.stableStatus} } select { case <-stop: logs.WithFields(c.fields).Debug("Stopping check") return case <-time.After(time.Duration(c.CheckIntervalInMilli) * time.Millisecond): } } }
func (s *Service) Lock(command string, ttl time.Duration, message string) { userAndHost := "[" + ggn.GetUserAndHost() + "] " message = userAndHost + message logs.WithFields(s.fields).WithField("ttl", ttl).WithField("message", message).Info("Locking") s.runHook(EARLY, command, "lock") defer s.runHook(LATE, command, "lock") kapi := s.env.EtcdClient() resp, err := kapi.Get(context.Background(), s.lockPath, nil) if cerr, ok := err.(*client.ClusterError); ok { logs.WithEF(cerr, s.fields).Fatal("Server error reading on fleet") } else if err != nil { _, err := kapi.Set(context.Background(), s.lockPath, message, &client.SetOptions{TTL: ttl}) if err != nil { logs.WithEF(cerr, s.fields).Fatal("Cannot write lock") } } else if strings.HasPrefix(resp.Node.Value, userAndHost) { _, err := kapi.Set(context.Background(), s.lockPath, message, &client.SetOptions{TTL: ttl}) if err != nil { logs.WithEF(cerr, s.fields).Fatal("Cannot write lock") } } else { logs.WithFields(s.fields).WithField("message", resp.Node.Value). WithField("ttl", resp.Node.TTLDuration().String()). Fatal("Service is already locked") } }
func (w Work) ListEnvs() []string { path := ggn.Home.Config.WorkPath + PATH_ENV if _, err := os.Stat(path); os.IsNotExist(err) { logs.WithEF(err, w.fields).WithField("path", path).Fatal("env directory not found") } files, err := ioutil.ReadDir(path) if err != nil { logs.WithEF(err, w.fields).WithField("path", path).Fatal("Cannot read env directory") } var envs []string for _, file := range files { if file.Mode()&os.ModeSymlink == os.ModeSymlink { followed_file, err := os.Readlink(path + "/" + file.Name()) if err != nil { continue } if followed_file[0] != '/' { followed_file = path + "/" + followed_file } file, err = os.Lstat(followed_file) if err != nil { continue } logs.WithField("followed_link", file.Name()).Trace("Followed Link") } if !file.IsDir() { continue } envs = append(envs, file.Name()) } return envs }
func (e *Env) loadAttributes() { files, err := utils.AttributeFiles(e.path + PATH_ATTRIBUTES) if err != nil { logs.WithEF(err, e.fields).WithField("path", e.path+PATH_ATTRIBUTES).Fatal("Cannot load attribute files") } files, err = e.addIncludeFiles(files) if err != nil { logs.WithEF(err, e.fields).WithField("path", e.path+PATH_ATTRIBUTES).Fatal("Cannot load include files") } e.attributes = attributes.MergeAttributesFiles(files) logs.WithFields(e.fields).WithField("attributes", e.attributes).Debug("Attributes loaded") }
func (w *WatcherZookeeper) watchNode(node string, stop <-chan struct{}, doneWaiter *sync.WaitGroup) { doneWaiter.Add(1) defer doneWaiter.Done() fields := w.fields.WithField("node", node) logs.WithF(fields).Debug("New node watcher") for { content, stats, childEvent, err := w.connection.Conn.GetW(node) if err != nil { if err == zk.ErrNoNode { logs.WithEF(err, fields).Warn("Node disappear before watching") w.reports.removeNode(node) return } w.service.synapse.watcherFailures.WithLabelValues(w.service.Name, PrometheusLabelWatch).Inc() logs.WithEF(err, fields).Warn("Failed to watch node, retry in 1s") <-time.After(time.Duration(1000) * time.Millisecond) if isStopped(stop) { return } continue } w.reports.addRawReport(node, content, fields, stats.Ctime) //if context.oneshot { // go func() { // <-rootEvents // }() // return //} select { case e := <-childEvent: logs.WithF(fields.WithField("event", e)).Trace("Receiving event from node") switch e.Type { case zk.EventNodeDataChanged | zk.EventNodeCreated | zk.EventNotWatching: // loop case zk.EventNodeDeleted: logs.WithF(fields).Debug("Node deleted") w.reports.removeNode(node) return } case <-stop: return } } }
func (aci *Aci) RunBuilderCommand(command common.BuilderCommand) error { defer aci.giveBackUserRightsToTarget() logs.WithF(aci.fields).Info("Building") if err := os.MkdirAll(aci.target, 0777); err != nil { return errs.WithEF(err, aci.fields, "Cannot create target directory") } if err := ioutil.WriteFile(aci.target+common.PathManifestYmlTmpl, []byte(aci.manifestTmpl), 0644); err != nil { return errs.WithEF(err, aci.fields.WithField("file", aci.target+common.PathManifestYmlTmpl), "Failed to write manifest template") } stage1Hash, err := aci.prepareStage1aci() if err != nil { return errs.WithEF(err, aci.fields, "Failed to prepare stage1 image") } builderHash, err := aci.prepareBuildAci() if err != nil { return errs.WithEF(err, aci.fields, "Failed to prepare build image") } logs.WithF(aci.fields).Info("Calling rkt to start build") defer aci.cleanupRun(builderHash, stage1Hash) if err := Home.Rkt.Run(aci.prepareRktRunArguments(command, builderHash, stage1Hash)); err != nil { return errs.WithEF(err, aci.fields, "Builder container return with failed status") } content, err := common.ExtractManifestContentFromAci(aci.target + pathImageAci) if err != nil { logs.WithEF(err, aci.fields).Warn("Failed to write manifest.json") } if err := ioutil.WriteFile(aci.target+pathManifestJson, content, 0644); err != nil { logs.WithEF(err, aci.fields).Warn("Failed to write manifest.json") } im := &schema.ImageManifest{} if err = im.UnmarshalJSON(content); err != nil { return errs.WithEF(err, aci.fields.WithField("content", string(content)), "Cannot unmarshall json content") } fullname := common.ExtractNameVersionFromManifest(im) logs.WithField("fullname", *fullname).Info("Finished building aci") if err := ioutil.WriteFile(aci.target+pathVersion, []byte(*fullname), 0644); err != nil { return errs.WithEF(err, aci.fields, "Failed to write version file in target") } return nil }
func (s *Service) loadAttributes() { attr := utils.CopyMap(s.env.GetAttributes()) files, err := utils.AttributeFiles(s.path + PATH_ATTRIBUTES) if err != nil { logs.WithEF(err, s.fields).WithField("path", s.path+PATH_ATTRIBUTES).Fatal("Cannot load Attributes files") } files, err = s.addIncludeFiles(files) if err != nil { logs.WithEF(err, s.fields).WithField("path", s.path+PATH_ATTRIBUTES).Fatal("Cannot load include files") } attr = attributes.MergeAttributesFilesForMap(attr, files) s.attributes = attr logs.WithFields(s.fields).WithField("attributes", s.attributes).Debug("Attributes loaded") }
func (u *Unit) Generate(tmpl *template.Templating) error { u.generatedMutex.Lock() defer u.generatedMutex.Unlock() if u.generated { return nil } logs.WithFields(u.Fields).Debug("Generate") data := u.GenerateAttributes() aciList, err := u.Service.PrepareAcis() if err != nil { return err } acis := "" for _, aci := range aciList { acis += aci + " " } data["aciList"] = aciList data["acis"] = acis out, err := json.Marshal(data) if err != nil { logs.WithEF(err, u.Fields).Panic("Cannot marshall attributes") } res := strings.Replace(string(out), "\\\"", "\\\\\\\"", -1) res = strings.Replace(res, "'", `\'`, -1) data["attributes"] = res data["attributesBase64"] = "base64," + base64.StdEncoding.EncodeToString([]byte(out)) data["environmentAttributes"], data["environmentAttributesVars"] = u.prepareEnvironmentAttributes(data["attributes"].(string), "ATTR_") data["environmentAttributesBase64"], data["environmentAttributesVarsBase64"] = u.prepareEnvironmentAttributes(data["attributesBase64"].(string), "ATTR_BASE64_") var b bytes.Buffer err = tmpl.Execute(&b, data) if err != nil { logs.WithEF(err, u.Fields).Error("Failed to run templating") } ok, err := utils.Exists(u.path) if !ok || err != nil { os.Mkdir(u.path, 0755) } err = ioutil.WriteFile(u.path+"/"+u.Filename, b.Bytes(), 0644) if err != nil { logs.WithEF(err, u.Fields).WithField("path", u.path+"/"+u.Filename).Error("Cannot writer unit") } u.generated = true return nil }
func (p *Pod) buildAci(e spec.RuntimeApp) *Aci { path := p.path + "/" + e.Name if dir, err := os.Stat(path); err != nil || !dir.IsDir() { if err := os.Mkdir(path, 0777); err != nil { logs.WithEF(err, p.fields).WithField("path", path).Fatal("Cannot created pod's aci directory") } } aci, err := NewAciWithManifest(p.path+"/"+e.Name, p.args, p.toAciManifest(e), nil) if err != nil { logs.WithEF(err, p.fields).WithField("aci", path).Fatal("Failed to prepare aci") } aci.podName = &p.manifest.Name aci.Build() return aci }
func (e Env) Fleetctl(args []string) { logs.WithFields(e.fields).Debug("Running fleetctl") err := e.RunFleetCmd(args...) if err != nil { logs.WithEF(err, e.fields).Error("Fleetctl command failed") } }
func (aci *Aci) Clean() { logs.WithF(aci.fields).Debug("Cleaning") if err := os.RemoveAll(aci.target + "/"); err != nil { logs.WithEF(err, aci.fields).WithField("dir", aci.target).Warn("Cannot remove directory") } }
func (aci *Aci) copyAttributes() { files, err := utils.AttributeFiles(aci.path + PATH_ATTRIBUTES) if err != nil { logs.WithEF(err, aci.fields).Fatal("Cannot read attribute files") } for _, file := range files { targetPath := aci.rootfs + PATH_CNT + PATH_ATTRIBUTES + "/" + aci.manifest.NameAndVersion.ShortName() err = os.MkdirAll(targetPath, 0755) if err != nil { logs.WithEF(err, aci.fields.WithField("path", targetPath)).Fatal("Cannot create target attribute directory") } if err := utils.CopyFile(file, targetPath+"/"+filepath.Base(file)); err != nil { logs.WithEF(err, aci.fields.WithField("file", file)).Fatal("Cannot copy attribute file") } } }
func (b *Builder) tarAci() error { upperId, err := b.upperTreeStoreId() if err != nil { return err } upperPath := b.pod.Root + PATH_OVERLAY + "/" + upperId + PATH_UPPER upperNamedRootfs := upperPath + "/" + manifestApp(b.pod).Name.String() upperRootfs := upperPath + common.PathRootfs if err := os.Rename(upperNamedRootfs, upperRootfs); err != nil { // TODO this is dirty and can probably be renamed during tar return errs.WithEF(err, b.fields.WithField("path", upperNamedRootfs), "Failed to rename rootfs") } defer os.Rename(upperRootfs, upperNamedRootfs) dir, err := os.Getwd() if err != nil { return errs.WithEF(err, b.fields, "Failed to get current working directory") } defer func() { if err := os.Chdir(dir); err != nil { logs.WithEF(err, b.fields.WithField("path", dir)).Warn("Failed to chdir back") } }() if err := os.Chdir(upperPath); err != nil { return errs.WithEF(err, b.fields.WithField("path", upperPath), "Failed to chdir to upper base path") } if err := common.Tar(b.aciTargetPath+common.PathImageAci, common.PathManifest[1:], common.PathRootfs[1:]+"/"); err != nil { return errs.WithEF(err, b.fields, "Failed to tar aci") } logs.WithField("path", dir).Debug("chdir") return nil }
func (e Env) ListUnits() map[string]UnitStatus { mutex.Lock() defer mutex.Unlock() if statusCache != nil { return statusCache } stdout, _, err := e.RunFleetCmdGetOutput("list-units", "-no-legend") if err != nil { logs.WithEF(err, e.fields).Debug("Cannot list units") } var lines []string scanner := bufio.NewScanner(strings.NewReader(stdout)) for scanner.Scan() { lines = append(lines, scanner.Text()) } status := make(map[string]UnitStatus) for _, line := range lines { split := strings.Fields(line) status[split[0]] = UnitStatus{Unit: split[0], Machine: split[1], Active: split[2], Sub: split[3]} } statusCache = status return status }
func (r *RouterHaProxy) Update(serviceReports []ServiceReport) error { reloadNeeded := r.socketPath == "" for _, report := range serviceReports { front, back, err := r.toFrontendAndBackend(report) if err != nil { return errs.WithEF(err, r.RouterCommon.fields.WithField("report", report), "Failed to prepare frontend and backend") } r.Frontend[report.Service.Name+"_"+strconv.Itoa(report.Service.id)] = front r.Backend[report.Service.Name+"_"+strconv.Itoa(report.Service.id)] = back if !r.isSocketUpdatable(report) { reloadNeeded = true } } if reloadNeeded { if err := r.Reload(); err != nil { return errs.WithEF(err, r.RouterCommon.fields, "Failed to reload haproxy") } } else if err := r.SocketUpdate(); err != nil { r.synapse.routerUpdateFailures.WithLabelValues(r.Type + PrometheusLabelSocketSuffix).Inc() logs.WithEF(err, r.RouterCommon.fields).Error("Update by Socket failed. Reloading instead") if err := r.Reload(); err != nil { return errs.WithEF(err, r.RouterCommon.fields, "Failed to reload haproxy") } } return nil }
func NewPod(path string, args BuildArgs) (*Pod, error) { fullPath, err := filepath.Abs(path) if err != nil { logs.WithE(err).WithField("path", path).Fatal("Cannot get fullpath") } manifest, err := readPodManifest(fullPath + POD_MANIFEST) if err != nil { return nil, errors.Annotate(err, "Failed to read pod manifest") } fields := data.WithField("pod", manifest.Name.String()) target := path + PATH_TARGET if cnt.Home.Config.TargetWorkDir != "" { currentAbsDir, err := filepath.Abs(cnt.Home.Config.TargetWorkDir + "/" + manifest.Name.ShortName()) if err != nil { logs.WithEF(err, fields).Panic("invalid target path") } target = currentAbsDir } pod := &Pod{ fields: fields, path: fullPath, args: args, target: target, manifest: *manifest, } return pod, nil }
func (p *Pod) Install() ([]string, error) { logs.WithF(p.fields).Info("Installing") hashs := []string{} if err := p.CleanAndBuild(); err != nil { return hashs, err } for _, e := range p.manifest.Pod.Apps { tmpl, err := p.toAciManifestTemplate(e) if err != nil { return nil, err } aci, err := NewAciWithManifest(p.path+"/"+e.Name, p.args, tmpl, p.checkWg) if err != nil { logs.WithEF(err, p.fields.WithField("name", e.Name)).Fatal("Cannot prepare aci") } aci.podName = &p.manifest.Name hash, err := aci.Install() if err != nil { return hashs, err } hashs = append(hashs, hash...) } return hashs, nil }
func (aci *Aci) cleanupTest(testerHash string, hashAcis []string) { if !Args.KeepBuilder { if _, _, err := Home.Rkt.RmFromFile(aci.target + pathTesterUuid); err != nil { logs.WithEF(err, aci.fields).Warn("Failed to remove test container") } } for _, hash := range hashAcis { if err := Home.Rkt.ImageRm(hash); err != nil { logs.WithEF(err, aci.fields.WithField("hash", hash)).Warn("Failed to remove container image") } } if err := Home.Rkt.ImageRm(testerHash); err != nil { logs.WithEF(err, aci.fields.WithField("hash", testerHash)).Warn("Failed to remove test container image") } }
func (aci *Aci) cleanupRun(builderHash string, stage1Hash string) { if !Args.KeepBuilder { if _, _, err := Home.Rkt.RmFromFile(aci.target + pathBuilderUuid); err != nil { logs.WithEF(err, aci.fields).Warn("Failed to remove build container") } } if err := Home.Rkt.ImageRm(builderHash); err != nil { logs.WithEF(err, aci.fields.WithField("hash", builderHash)).Warn("Failed to remove build container image") } if stage1Hash != "" { if err := Home.Rkt.ImageRm(stage1Hash); err != nil { logs.WithEF(err, aci.fields.WithField("hash", stage1Hash)).Warn("Failed to remove stage1 container image") } } }
func (s *Service) Diff() { if err := s.Generate(); err != nil { logs.WithEF(err, s.fields).Fatal("Generate failed") } for _, unitName := range s.ListUnits() { unit := s.LoadUnit(unitName) unit.Diff("service/diff") } }
func (u *Unit) Ssh(command string) { logs.WithFields(u.Fields).Debug("ssh") u.runHook(EARLY, command, "ssh") defer u.runHook(LATE, command, "ssh") err := u.Service.GetEnv().RunFleetCmd("ssh", u.Filename) if err != nil { logs.WithEF(err, u.Fields).Fatal("Failed to run status") } }
func (s *Service) loadManifest() { manifest := ServiceManifest{} path := s.manifestPath() source, err := ioutil.ReadFile(path) if err != nil { logs.WithEF(err, s.fields).WithField("path", path).Warn("Cannot find manifest for service") } err = yaml.Unmarshal([]byte(source), &manifest) if err != nil { logs.WithEF(err, s.fields).Fatal("Cannot Read service manifest") } if manifest.ConcurrentUpdater == 0 { manifest.ConcurrentUpdater = 1 } logs.WithFields(s.fields).WithField("manifest", manifest).Debug("Manifest loaded") s.manifest = manifest }
func (e *Env) loadPartials() { if ok, err := common.IsDirEmpty(e.path + PATH_TEMPLATES); ok || err != nil { return } tmplDir, err := template.NewTemplateDir(e.path+PATH_TEMPLATES, "", false) if err != nil { logs.WithEF(err, e.fields).WithField("path", e.path+PATH_ATTRIBUTES).Fatal("Failed to load partial templating") } e.Partials = tmplDir.Partials }
func (hap *HaProxyClient) SocketUpdate() error { if hap.socketPath == "" { return errs.WithF(hap.fields, "No socket file specified. Cannot update") } logs.WithF(hap.fields).Debug("Updating haproxy by socket") if err := hap.writeConfig(); err != nil { // just to stay in sync logs.WithEF(err, hap.fields).Warn("Failed to write configuration file") } conn, err := net.Dial("unix", hap.socketPath) if err != nil { return errs.WithEF(err, hap.fields.WithField("socket", hap.socketPath), "Failed to connect to haproxy socket") } defer conn.Close() i := 0 b := bytes.Buffer{} for name, servers := range hap.Backend { for _, server := range servers { res := hap.weightRegex.FindStringSubmatch(server) if len(res) == 3 { i++ b.WriteString("set weight " + name + "/" + res[1] + " " + res[2] + "\n") } } } if b.Len() == 0 { logs.WithF(hap.fields).Debug("Nothing to update by socket. No weight set") return nil } commands := b.Bytes() logs.WithF(hap.fields.WithField("command", string(commands))).Trace("Running command on hap socket") count, err := conn.Write(commands) if count != len(commands) || err != nil { return errs.WithEF(err, hap.fields. WithField("written", count). WithField("len", len(commands)). WithField("command", string(commands)), "Failed to write command to haproxy") } buff := bufio.NewReader(conn) line, prefix, err := buff.ReadLine() if err != nil || prefix { return errs.WithEF(err, hap.fields.WithField("line-too-long", prefix), "Failed to read hap socket response") } if string(line) != "" { return errs.WithF(hap.fields.WithField("response", string(line)), "Bad response for haproxy socket command") } return nil }
func (e Env) FleetctlListMachines() { stdout, _, err := e.RunFleetCmdGetOutput("-strict-host-key-checking=false", "list-machines", "--full", "--no-legend") if err != nil { logs.WithEF(err, e.fields).Fatal("Failed to list-machines") } machines := strings.Split(stdout, "\n") for _, machine := range machines { fmt.Println(machine) } }