Esempio n. 1
0
// 处理系统信号
// 监听系统信号,重启或停止服务
func trapSignal(server client.Encoder) {
	sch := make(chan os.Signal, 10)
	signal.Notify(sch, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGINT,
		syscall.SIGHUP, syscall.SIGSTOP, syscall.SIGQUIT)
	go func(ch <-chan os.Signal) {
		sig := <-ch
		server.Shutdown("signal recieved " + sig.String() + ", at: " + time.Now().String())
		if sig == syscall.SIGHUP {
			server.Info("autoencode restart now...")
			procAttr := new(os.ProcAttr)
			procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
			procAttr.Dir = os.Getenv("PWD")
			procAttr.Env = os.Environ()
			process, err := os.StartProcess(os.Args[0], os.Args, procAttr)
			if err != nil {
				server.Info("autoencode restart process failed:" + err.Error())
				return
			}
			waitMsg, err := process.Wait()
			if err != nil {
				server.Info("autoencode restart wait error:" + err.Error())
			}
			server.Info(waitMsg)
		} else {
			server.Info("autoencode shutdown now...")
		}
	}(sch)
}
Esempio n. 2
0
func (e *Environment) Spawn(cmd []string, extraVars map[string]string) (*int, error) {
	if len(cmd) == 0 {
		return nil, ErrInvalidCommand
	}

	// lookup the path of the executable
	cmdpath, err := exec.LookPath(cmd[0])
	if err != nil {
		return nil, fmt.Errorf("Cannot find executable %s: %v", cmd[0], err)
	}

	// copy the extra vars so we can mutate it
	vars := make(map[string]string)
	for key, value := range extraVars {
		vars[key] = value
	}

	// start the agent
	sock, err := e.startProxyKeyring()
	if err != nil {
		return nil, err
	}

	vars["SSH_AUTH_SOCK"] = sock

	// start the process
	var attr os.ProcAttr
	attr.Env = e.buildEnviron(vars)
	attr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}

	proc, err := os.StartProcess(cmdpath, cmd, &attr)
	if err != nil {
		return nil, fmt.Errorf("Failed to execute command: %v", err)
	}

	// wait for the process to exit
	state, _ := proc.Wait()

	var exitStatus int
	if !state.Success() {
		if status, ok := state.Sys().(syscall.WaitStatus); ok {
			exitStatus = status.ExitStatus()
		} else {
			exitStatus = 255
		}
	}

	// we only return an error if spawning the process failed, not if
	// the spawned command returned a failure status code.
	return &exitStatus, nil
}
Esempio n. 3
0
// 执行截图
func exec(url, pic, width, height, delay string) (string, error) {
	if url == "" {
		return "", errors.New("url is none.")
	}
	if width == "" {
		width = strconv.Itoa(conf.width)
	}
	if height == "" {
		height = strconv.Itoa(conf.height)
	}
	if delay == "" {
		delay = strconv.Itoa(conf.delay)
	}
	procAttr := new(os.ProcAttr)
	procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
	procAttr.Dir = os.Getenv("PWD")
	procAttr.Env = os.Environ()
	var args []string
	args = make([]string, 7)
	args[0] = PHANTOMJS
	args[1] = conf.dir + "/" + SNAP_JS
	args[2] = url
	args[3] = pic
	args[4] = delay
	args[5] = width
	args[6] = height
	process, err := os.StartProcess(PHANTOMJS, args, procAttr)
	if err != nil {
		if conf.debug == true {
			log.Println("PhantomJS start failed:" + err.Error())
		}
		return "", err
	}
	waitMsg, err := process.Wait()
	if err != nil {
		if conf.debug == true {
			log.Println("PhantomJS start wait error:" + err.Error())
		}
		return "", err
	}
	if conf.debug == true {
		log.Println(waitMsg)
	}
	return args[3], nil
}
Esempio n. 4
0
func doExecution(task *TaskRequest, completionChannel chan<- *TaskResponse) {
	// we must notify the parent when we exit.
	defer func(c chan<- *TaskResponse, task *TaskRequest) { c <- task.MyResponse }(completionChannel, task)

	// first of all, verify that the score exists at all.
	score, exists := Scores[task.Score]
	if !exists {
		o.Warn("job%d: request for unknown score: %s", task.Id, task.Score)
		task.MyResponse.State = RESP_FAILED_UNKNOWN_SCORE
		return
	}
	si := NewScoreInterface(task)
	if si == nil {
		o.Warn("job%d: couldn't initialise score interface", task.Id)
		task.MyResponse.State = RESP_FAILED_HOST_ERROR
		return
	}
	if !si.Prepare() {
		o.Warn("job%d: couldn't prepare score interface", task.Id)
		task.MyResponse.State = RESP_FAILED_HOST_ERROR
		return
	}
	defer si.Cleanup()

	eenv := si.SetupProcess()
	task.MyResponse.State = RESP_RUNNING

	procenv := new(os.ProcAttr)
	// Build the default environment.
	procenv.Env = peSetEnv(procenv.Env, "PATH", "/usr/bin:/usr/sbin:/bin:/sbin")
	procenv.Env = peSetEnv(procenv.Env, "IFS", " \t\n")
	pwd, err := os.Getwd()
	if err != nil {
		task.MyResponse.State = RESP_FAILED_HOST_ERROR
		o.Warn("job%d: couldn't resolve PWD: %s", task.Id, err)
		return
	}
	procenv.Env = peSetEnv(procenv.Env, "PWD", pwd)
	// copy in the environment overrides
	for k, v := range eenv.Environment {
		procenv.Env = peSetEnv(procenv.Env, k, v)
	}

	// attach FDs to procenv.
	procenv.Files = make([]*os.File, 3)

	// first off, attach /dev/null to stdin and stdout
	devNull, err := os.OpenFile(os.DevNull, os.O_RDWR|os.O_APPEND, 0666)
	o.MightFail(err, "couldn't open DevNull")
	defer devNull.Close()
	for i := 0; i < 2; i++ {
		procenv.Files[i] = devNull
	}
	// attach STDERR to to our logger via pipe.
	lr, lw, err := os.Pipe()
	o.MightFail(err, "Couldn't create pipe")
	defer lw.Close()
	// lr will be closed by the logger.
	procenv.Files[2] = lw
	// check the environment's configuration and allow it to override stdin, stdout, and FDs 3+
	if nil != eenv.Files {
		for i := range eenv.Files {
			if i < 2 {
				procenv.Files[i] = eenv.Files[i]
			} else {
				procenv.Files = append(procenv.Files, eenv.Files[i])
			}
		}
	}
	var args []string
	args = append(args, eenv.Arguments...)

	o.Info("job%d: executing %s...", task.Id, score.Executable)
	go batchLogger(task.Id, lr)
	proc, err := os.StartProcess(score.Executable, args, procenv)
	if err != nil {
		o.Warn("job%d: failed to start process", task.Id)
		task.MyResponse.State = RESP_FAILED_HOST_ERROR
		return
	}
	wm, err := proc.Wait()
	if err != nil {
		o.Warn("job%d: error waiting for process", task.Id)
		task.MyResponse.State = RESP_FAILED_UNKNOWN
		// Worse of all, we don't even know if we succeeded.
		return
	}
	ws, _ := wm.Sys().(syscall.WaitStatus)
	if !(ws.Signaled() || ws.Exited()) {
		o.Assert("Non Terminal notification received when not expected.")
		return
	}
	if ws.Signaled() {
		o.Warn("job%d: process got signalled", task.Id)
		task.MyResponse.State = RESP_FAILED_UNKNOWN
		return
	}
	if ws.Exited() {
		if 0 == ws.ExitStatus() {
			o.Warn("job%d: process exited OK", task.Id)
			task.MyResponse.State = RESP_FINISHED
		} else {
			o.Warn("job%d: process exited with failure", task.Id)
			task.MyResponse.State = RESP_FAILED
		}
		return
	}
	o.Assert("Should never get here.")
}