Beispiel #1
0
func (d *daemon) Run() {
	var lastStart time.Time
	for d.stop != true {
		d.log.Notice(">> starting...")
		since := time.Now().Sub(lastStart)
		if since < MinRestart {
			time.Sleep(MinRestart - since)
		}
		lastStart = time.Now()

		c, err := shell.Command(d.shell, d.conf.Command)
		if err != nil {
			d.log.Shout("%s", err)
			return
		}
		stdo, err := c.StdoutPipe()
		if err != nil {
			d.log.Shout("%s", err)
			continue
		}
		stde, err := c.StderrPipe()
		if err != nil {
			d.log.Shout("%s", err)
			continue
		}
		wg := sync.WaitGroup{}
		wg.Add(2)
		go logOutput(&wg, stde, d.log.Warn)
		go logOutput(&wg, stdo, d.log.Say)

		d.Lock()
		err = c.Start()
		if err != nil {
			d.log.Shout("%s", err)
			d.Unlock()
			continue
		}
		d.cmd = c
		d.Unlock()

		wg.Wait()
		err = c.Wait()
		if err != nil {
			if _, ok := err.(*exec.ExitError); ok {
				d.log.Warn("exited: %s", c.ProcessState.String())
			} else {
				d.log.Shout("exited: %s", err)
			}
		} else {
			d.log.Warn("exited: %s", c.ProcessState.String())
		}
	}
}
Beispiel #2
0
// RunProc runs a process to completion, sending output to log
func RunProc(cmd, shellMethod string, log termlog.Stream) error {
	log.Header()

	c, err := shell.Command(shellMethod, cmd)
	if err != nil {
		return err
	}
	stdo, err := c.StdoutPipe()
	if err != nil {
		return err
	}
	stde, err := c.StderrPipe()
	if err != nil {
		return err
	}
	buff := new(bytes.Buffer)
	mut := sync.Mutex{}
	err = c.Start()
	if err != nil {
		return err
	}
	wg := sync.WaitGroup{}
	wg.Add(2)
	go logOutput(
		&wg, stde,
		func(s string, args ...interface{}) {
			log.Warn(s)

			mut.Lock()
			defer mut.Unlock()
			buff.WriteString(s + "\n")
		},
	)
	go logOutput(&wg, stdo, log.Say)
	wg.Wait()
	err = c.Wait()
	if err != nil {
		log.Shout("%s", c.ProcessState.String())
		return ProcError{err.Error(), buff.String()}
	}
	log.Notice(">> done (%s)", c.ProcessState.UserTime())
	return nil
}
Beispiel #3
0
func (d *daemon) Run() {
	var lastStart time.Time
	delay := MinRestart
	for d.stop != true {
		d.log.Notice(">> starting...")
		since := time.Now().Sub(lastStart)
		if since < delay {
			time.Sleep(delay - since)
		}
		lastStart = time.Now()

		c, err := shell.Command(d.shell, d.conf.Command)
		if err != nil {
			d.log.Shout("%s", err)
			return
		}
		c.Dir = d.indir
		stdo, err := c.StdoutPipe()
		if err != nil {
			d.log.Shout("%s", err)
			continue
		}
		stde, err := c.StderrPipe()
		if err != nil {
			d.log.Shout("%s", err)
			continue
		}
		wg := sync.WaitGroup{}
		wg.Add(2)
		go logOutput(&wg, stde, d.log.Warn)
		go logOutput(&wg, stdo, d.log.Say)

		d.Lock()
		err = c.Start()
		if err != nil {
			d.log.Shout("%s", err)
			d.Unlock()
			continue
		}
		d.cmd = c
		d.Unlock()

		wg.Wait()
		err = c.Wait()
		if err != nil {
			if _, ok := err.(*exec.ExitError); ok {
				d.log.Warn("exited: %s", c.ProcessState.String())
			} else {
				d.log.Shout("exited: %s", err)
			}
			// unclean restart; increase backoff
			delay *= MulRestart
			if delay > MaxRestart {
				delay = MaxRestart
			}
		} else {
			d.log.Warn("exited: %s", c.ProcessState.String())
			// clean restart; reset backoff
			delay = MinRestart
		}
	}
}