Beispiel #1
0
func ExecCommandFull(cmd []string, env []string, timeoutInMilli int) error {
	command := exec.Command(cmd[0], cmd[1:]...)
	var b bytes.Buffer
	command.Stdout = &b
	command.Stderr = &b
	command.Env = env

	if err := command.Start(); err != nil {
		return errs.WithEF(err, data.WithField("cmd", cmd), "Failed to start command")
	}

	var after *errs.EntryError
	timer := time.AfterFunc(time.Duration(timeoutInMilli)*time.Millisecond, func() {
		data := data.WithField("command", strings.Join(cmd, " ")).WithField("timeout", timeoutInMilli)
		logs.WithF(data).Debug("Command timeout")
		after = errs.WithF(data, "Exec command timeout")
		command.Process.Kill()
	})

	err := command.Wait()
	timer.Stop()
	if logs.IsTraceEnabled() {
		logs.WithField("cmd", cmd).WithField("output", string(b.Bytes())).Trace("Command output")
	}
	if err != nil {
		return errs.WithEF(err, data.WithField("cmd", cmd).
			WithField("output", string(b.Bytes())), "Command failed").
			WithErr(after)
	}
	return nil
}
Beispiel #2
0
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):
		}
	}
}
Beispiel #3
0
func (f *TemplateFile) runTemplate(dst string, attributes map[string]interface{}) error {
	if logs.IsTraceEnabled() {
		logs.WithF(f.fields).WithField("attributes", attributes).Trace("templating with attributes")
	}
	fields := f.fields.WithField("dst", dst)

	logs.WithF(fields).Info("Templating file")

	out, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, f.srcMode)
	if err != nil {
		return errs.WithEF(err, fields, "Cannot open destination file")
	}
	defer func() { out.Close() }()

	buff := bytes.Buffer{}
	writer := bufio.NewWriter(&buff)
	if err := f.template.Execute(writer, attributes); err != nil {
		return errs.WithEF(err, fields, "Templating execution failed")
	}

	if err := writer.Flush(); err != nil {
		return errs.WithEF(err, fields, "Failed to flush buffer")
	}

	b := buff.Bytes()
	if logs.IsTraceEnabled() {
		logs.WithF(f.fields).WithField("result", string(b)).Trace("templating done")
	}
	if bytes.Contains(b, []byte("<no value>")) {
		return errs.WithF(fields, "Templating result have <no value>")
	}
	out.Write(b)

	if err = out.Sync(); err != nil {
		return errs.WithEF(err, fields, "Failed to sync output file")
	}
	return nil
}
Beispiel #4
0
func (hap *HaProxyClient) writeConfig() error {
	var b bytes.Buffer
	writer := bufio.NewWriter(&b)
	if err := hap.template.Execute(writer, hap); err != nil {
		return errs.WithEF(err, hap.fields, "Failed to template haproxy configuration file")
	}
	if err := writer.Flush(); err != nil {
		return errs.WithEF(err, hap.fields, "Failed to flush buffer")
	}

	templated := b.Bytes()
	if logs.IsTraceEnabled() {
		logs.WithF(hap.fields.WithField("templated", string(templated))).Trace("Templated configuration file")
	}
	if err := ioutil.WriteFile(hap.ConfigPath, templated, 0644); err != nil {
		return errs.WithEF(err, hap.fields, "Failed to write configuration file")
	}
	return nil
}
Beispiel #5
0
func (f *TemplateFile) runTemplate(dst string, attributes map[string]interface{}) error {
	if logs.IsTraceEnabled() {
		logs.WithF(f.fields).WithField("attributes", attributes).Trace("templating with attributes")
	}
	fields := f.fields.WithField("dst", dst)

	logs.WithF(fields).Info("Templating file")

	out, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, f.Mode)
	if err != nil {
		return errs.WithEF(err, fields, "Cannot open destination file")
	}
	defer func() { out.Close() }()

	buff := bytes.Buffer{}
	writer := bufio.NewWriter(&buff)
	if err := f.template.Execute(writer, attributes); err != nil {
		return errs.WithEF(err, fields, "Templating execution failed")
	}

	if err := writer.Flush(); err != nil {
		return errs.WithEF(err, fields, "Failed to flush buffer")
	}
	buff.WriteByte('\n')

	b := buff.Bytes()

	if logs.IsTraceEnabled() {
		logs.WithF(f.fields).WithField("result", string(b)).Trace("templating done")
	}

	scanner := bufio.NewScanner(bytes.NewReader(b)) // TODO this sux
	scanner.Split(bufio.ScanLines)
	for i := 1; scanner.Scan(); i++ {
		text := scanner.Text()
		if bytes.Contains([]byte(text), []byte("<no value>")) {
			return errs.WithF(fields.WithField("line", i).WithField("text", text), "Templating result have <no value>")
		}
	}

	if length, err := out.Write(b); length != len(b) || err != nil {
		return errs.WithEF(err, fields, "Write to file failed")
	}

	if err = out.Sync(); err != nil {
		return errs.WithEF(err, fields, "Failed to sync output file")
	}
	if err = os.Chmod(dst, f.Mode); err != nil {
		return errs.WithEF(err, fields.WithField("file", dst), "Failed to set mode on file")
	}
	if err = os.Chown(dst, f.Uid, f.Gid); err != nil {
		return errs.WithEF(err, fields.WithField("file", dst), "Failed to set owner of file")
	}

	if f.CheckCmd != "" {
		cmd := exec.Command("/dgr/bin/busybox", "sh", "-c", f.CheckCmd)
		cmd.Stdout = os.Stdout
		cmd.Stdin = os.Stdin
		cmd.Stderr = os.Stderr
		if err = cmd.Run(); err != nil {
			return errs.WithEF(err, fields.WithField("file", dst), "Check command failed after templating")
		}
	}
	return nil
}