예제 #1
0
파일: config.go 프로젝트: mfya/autobld
func normalize(config *Config) (*Config, error) {
	if len(config.Action) == 0 {
		return nil, errors.New("no action specified, please specify an action")
	}

	// Set up a default dir config to listen for everything.
	if len(config.Matchers) == 0 {
		config.Matchers = []Matcher{{
			Patterns: []string{"*"},
		}}
	}
	config.configsMap = make(map[string]*Matcher)

	for i := range config.Matchers {
		if len(config.Matchers[i].ExcludeDirs) == 0 {
			config.Matchers[i].excludeDirMap = defaultExcludeDirMap
		} else {
			m := make(map[string]bool)
			for _, dir := range argPatterns(config.Matchers[i].ExcludeDirs) {
				m[dir] = true
			}
			config.Matchers[i].excludeDirMap = m
		}
	}
	if config.ChangeTimeout == 0 {
		config.ChangeTimeout = defaultChangeTimeout
	}
	if config.KillTimeout == 0 {
		config.KillTimeout = defaultKillTimeout
	}
	log.V("Initializing with config: %+v", config)
	return config, nil
}
예제 #2
0
// Kill kills all child processes of pgid, since there is no way to kill a process
// group in Windows.
func (t *Task) Kill() error {
	log.V("Kill task")

	// In case killing all child processes fails.
	defer t.process.Kill()

	parentMap, err := loadProcessMap()
	if err != nil {
		return err
	}
	if errs := killChildProcesses(parentMap, uint32(t.process.Pid)); len(errs) > 0 {
		log.L("killChildProcesses errors: %v", errs)
		return fmt.Errorf("failed to kill child processes: %v", errs)
	}
	return nil
}
예제 #3
0
파일: runner.go 프로젝트: mfya/autobld
func (t *SM) startTask() error {
	var err error
	t.Task, err = New(t.c.BaseDir, t.c.StdOut, t.c.StdErr, t.c.Action)
	if err != nil {
		return err
	}

	t.blockRequests.Done()

	stdinCloser := make(chan struct{})
	go copyStdin(t.Task.stdinPipe, stdinCloser)
	go func() {
		t.Task.process.Wait()
		log.V("Task is no longer running")
		t.done.Write(true)
		t.Reprocess <- struct{}{}
		t.reloadEnded <- struct{}{}
		stdinCloser <- struct{}{}
	}()

	return nil
}
예제 #4
0
파일: task.go 프로젝트: mfya/autobld
// New starts the binary specified in args, and returns a Task for the process.
func New(baseDir string, outFile string, errFile string, args []string) (*Task, error) {
	if !log.V("Starting task: %v", args) {
		log.L("Starting task")
	}
	cmd := exec.Command(args[0], args[1:]...)

	// Use a separate process group so we can kill the whole group.
	cmd.Dir = baseDir
	cmd.SysProcAttr = getSysProcAttrs()
	var err error
	if cmd.Stdout, err = getOutFile(outFile, os.Stdout); err != nil {
		return nil, err
	}
	if cmd.Stderr, err = getOutFile(errFile, os.Stderr); err != nil {
		return nil, err
	}
	stdinPipe, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	if err := cmd.Start(); err != nil {
		return nil, fmt.Errorf("error starting command: %v", err)
	}
	pgid, err := getPgID(cmd)
	if err != nil {
		// If we cannot get the pgid, kill the process and return an error.
		cmd.Process.Kill()
		return nil, err
	}

	return &Task{
		process:   cmd.Process,
		pgid:      pgid,
		stdinPipe: stdinPipe,
	}, nil
}
예제 #5
0
파일: task_other.go 프로젝트: mfya/autobld
// Kill sends a KILL signal to the task.
func (t *Task) Kill() error {
	log.V("Kill task")
	return syscall.Kill(-t.pgid, syscall.SIGKILL)
}