Esempio n. 1
0
func Build(cfg *config.BuildConfig) error {
	// Prepare sh script
	t := template.New("_")
	template.Must(t.Parse(build_sh_src))
	var w bytes.Buffer
	if err := t.Execute(&w, cfg); err != nil {
		panic(err.Error())
	}
	build_sh := string(w.Bytes())

	if cfg.Show {
		println(build_sh)
	}

	// Execute remotely
	cmd := exec.Command("ssh", cfg.Host, "sh")
	cmd.Stdin = bytes.NewBufferString(build_sh)

	// Capture stdout and stderr
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return err
	}
	prefix := fmt.Sprintf("%s:4build/err| ", cfg.Host)
	posix.ForwardStderr(prefix, stderr)

	if err = cmd.Start(); err != nil {
		return err
	}

	// Read result (remote directory of built bundle) from stdout
	result, _ := ioutil.ReadAll(stdout)
	if err = cmd.Wait(); err != nil {
		return err
	}

	// Fetch the built shipping bundle
	if err = os.MkdirAll(cfg.ShipDir, 0700); err != nil {
		return err
	}

	// Make ship directory if not present
	if err := os.MkdirAll(cfg.ShipDir, 0755); err != nil {
		return err
	}

	// Clean the ship directory
	if _, _, err = posix.Shell(`rm -f ` + cfg.ShipDir + `/*`); err != nil {
		return err
	}

	// Cleanup remote dir of built files
	r := strings.TrimSpace(string(result))
	if r == "" {
		return errors.New("empty shipping source directory")
	}

	// Download files
	println("Downloading from", r)
	if err = posix.DownloadDir(cfg.Host, r, cfg.ShipDir); err != nil {
		return err
	}
	println("Download successful.")
	return nil
}
Esempio n. 2
0
func (c *Config) Spawn(host string, anchors ...string) (circuit.Addr, error) {

	cmd := exec.Command("ssh", host, "sh")

	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}

	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, err
	}
	//posix.ForwardStderrBatch(stderr)
	id := circuit.ChooseWorkerID()

	// Forward the stderr of the ssh process to this process' stderr
	posix.ForwardStderr(fmt.Sprintf("%s:kicker/err| ", id), stderr)

	// Start process
	if err := cmd.Start(); err != nil {
		return nil, err
	}
	defer cmd.Wait() /// Make sure that ssh does not remain zombie

	// Feed shell script to execute circuit binary
	bindir, _ := path.Split(c.Binary)
	if bindir == "" {
		panic("binary path not absolute")
	}
	var sh string
	if c.LibPath == "" {
		sh = fmt.Sprintf("cd %s\n%s=%s %s\n", bindir, config.RoleEnv, config.Daemonizer, c.Binary)
	} else {
		sh = fmt.Sprintf(
			"cd %s\nLD_LIBRARY_PATH=%s DYLD_LIBRARY_PATH=%s %s=%s %s\n",
			bindir, c.LibPath, c.LibPath, config.RoleEnv, config.Daemonizer, c.Binary)
	}
	stdin.Write([]byte(sh))

	// Write worker configuration to stdin of running worker process
	wc := &config.WorkerConfig{
		Spark: &config.SparkConfig{
			ID:       id,
			BindAddr: "",
			Host:     host,
			Anchor:   append(anchors, fmt.Sprintf("/host/%s", host)),
		},
		Zookeeper: config.Config.Zookeeper,
		Deploy:    config.Config.Deploy,
	}
	if err := json.NewEncoder(stdin).Encode(wc); err != nil {
		return nil, err
	}

	// Close stdin
	if err = stdin.Close(); err != nil {
		return nil, err
	}

	// Read the first two lines of stdout. They should hold the Port and PID of the runtime process.
	stdoutBuffer := bufio.NewReader(stdout)

	// First line equals PID
	line, err := stdoutBuffer.ReadString('\n')
	if err != nil {
		return nil, err
	}
	line = line[:len(line)-1]
	pid, err := strconv.Atoi(line)
	if err != nil {
		return nil, err
	}

	// Second line equals port
	line, err = stdoutBuffer.ReadString('\n')
	if err != nil {
		return nil, err
	}
	line = line[:len(line)-1]
	port, err := strconv.Atoi(line)
	if err != nil {
		return nil, err
	}

	addr, err := transport.NewAddr(id, pid, fmt.Sprintf("%s:%d", host, port))
	if err != nil {
		return nil, err
	}

	return addr.(*transport.Addr), nil
}