예제 #1
0
func (a *Agent) Prepare() {
	if state.Local() {
		err := createCleanDir(a.dir)
		if err != nil {
			log.Fatal(err)
		}
	}
	log.Printf("Going to run %s as %s", a.Name, a.args)
}
예제 #2
0
func (a *Agent) start() {
	if a.cmd != nil {
		log.Fatal("Cannot call start(): program already running!")
	}
	if a.killcount > 0 {
		return
	}
	cmd := exec.Command(a.args[0], a.args[1:]...)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal("Unable to open pipe to stdout: %v", err)
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal("Unable to open pipe to stderr: %v", err)
	}
	if state.Local() {
		cmd.Dir = a.dir
	}
	go copyLines(a.Name, stdout)
	go copyLines(a.Name, stderr)
	log.Printf("Starting %v", a)
	err = cmd.Start()
	if err != nil {
		log.Fatalf("Could't spawn %v: %s", a, err)
	}
	go func() {
		err := cmd.Wait()
		a.Lock()
		defer a.Unlock()

		// Not the active command
		if a.cmd != cmd {
			return
		}

		var d string
		if err != nil {
			d = fmt.Sprintf("Command exited unexpectedly: %s (%s)", cmd, err)
		} else {
			d = fmt.Sprintf("Command exited unexpectedly (but cleanly!): %s", cmd)
		}
		state.RecordDisqualifier(d)

		state.WaitGroup().Exit()
	}()

	a.cmd = cmd
}
예제 #3
0
func (a *Agent) Freeze() {
	a.Lock()
	defer a.Unlock()

	if a.stopcount == 0 && a.cmd != nil {
		if state.Local() {
			a.cmd.Process.Signal(syscall.SIGTSTP)
		} else {
			file, err := os.Open(a.freezefile)
			if err != nil {
				log.Printf("freeze error: %v", err)
				return
			}
			file.WriteString("FROZEN\n")
			file.Close()
		}
	}

	a.stopcount++
}
예제 #4
0
func NewAgent(i uint) *Agent {
	args := make([]string, 0)
	var container string

	if !state.Local() {
		// Run under LXC remotely
		homedir := fmt.Sprintf("/home/%s", state.Username())
		container = state.ContainerIds()[i]
		args = append(args,
			"lxc-attach", "-n", container,
			"--clear-env", "--",
			"/ctf3/shell.sh", state.Username(), homedir,
		)
	}
	args = append(args, state.Sqlcluster())
	args = append(args,
		"-l", SocketName(i),
		"-d", ContainerWorkingDir(i))
	if i != 0 {
		args = append(args, "--join="+SocketName(0))
	}
	args = append(args, state.Args()...)

	cs, err := unix.Encode(SocketPath(i, i))
	if err != nil {
		log.Fatalf("Couldn't create node %d: %s", i, err)
	}

	return &Agent{
		Name:             NodeName(i),
		ConnectionString: cs,
		args:             args,
		dir:              WorkingDir(i),
		// This is going to contain nonsense if container is empty, but
		// it won't matter
		freezefile: "/sys/fs/cgroup/freezer/lxc/" + container +
			"/freezer.state",
	}
}
예제 #5
0
func (a *Agent) Thaw() {
	a.Lock()
	defer a.Unlock()

	a.stopcount--

	if a.stopcount == 0 && a.cmd == nil {
		a.start()
	} else if a.stopcount == 0 {
		if state.Local() {
			a.cmd.Process.Signal(syscall.SIGCONT)
		} else {
			file, err := os.Open(a.freezefile)
			if err != nil {
				log.Printf("thaw error: %v", err)
				return
			}
			file.WriteString("THAWED\n")
			file.Close()
		}
	}
}