further refactor of building and copying pilosactl

This commit is contained in:
jaffee 2016-12-23 11:49:33 -06:00
parent 9ffbe241e8
commit a126df414c
3 changed files with 90 additions and 35 deletions

View file

@ -13,7 +13,6 @@ import (
"log"
"math/rand"
"os"
"os/exec"
"os/signal"
"path"
"path/filepath"
@ -1374,10 +1373,6 @@ func (cmd *BspawnCommand) ParseFlags(args []string) error {
if err != nil {
return err
}
// handle pilosa creation
// handle agent creation
return nil
}
@ -1432,43 +1427,22 @@ func (cmd *BspawnCommand) Run(ctx context.Context) error {
}
}
func copyBinary(agentConnections []*pilosactl.SSH, pkg, goos, goarch string) error {
binName := path.Base(pkg)
binLoc := path.Join(os.TempDir(), binName)
com := exec.Command("go", "build", "-o", binLoc, pkg)
com.Env = append([]string{"GOOS=" + goos, "GOARCH=" + goarch}, os.Environ()...)
err := com.Run()
func copyBinary(fleet pilosactl.SSHFleet, pkg, goos, goarch string) error {
bin, err := pilosactl.BuildBinary(pkg, goos, goarch)
if err != nil {
return err
}
agentWriters := make([]io.Writer, len(agentConnections))
for i, conn := range agentConnections {
agentWriters[i], err = conn.OpenFile(binName, "+x")
if err != nil {
return err
}
}
f, err := os.Open(binLoc)
if err != nil {
return err
}
_, err = io.Copy(io.MultiWriter(agentWriters...), f)
wc, err := fleet.OpenFile(path.Base(pkg), "+x")
if err != nil {
return err
}
for _, w := range agentWriters {
if wc, ok := w.(io.WriteCloser); ok {
err = wc.Close()
if err != nil {
return err
}
}
_, err = io.Copy(wc, bin)
if err != nil {
return err
}
return nil
return wc.Close()
}
func (cmd *BspawnCommand) spawnRemote(ctx context.Context, runUUID uuid.UUID) error {

29
pilosactl/build.go Normal file
View file

@ -0,0 +1,29 @@
package pilosactl
import (
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
)
func BuildBinary(pkg, goos, goarch string) (io.Reader, error) {
binFile, err := ioutil.TempFile("", "pilosactl")
if err != nil {
return nil, fmt.Errorf("build binary: %v", err)
}
com := exec.Command("go", "build", "-o", binFile.Name(), pkg)
com.Env = append([]string{"GOOS=" + goos, "GOARCH=" + goarch}, os.Environ()...)
err = com.Run()
if err != nil {
return nil, err
}
f, err := os.Open(binFile.Name())
if err != nil {
return nil, err
}
return f, nil
}

View file

@ -8,6 +8,8 @@ import (
"os/user"
"strings"
"errors"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
@ -57,7 +59,9 @@ func NewSSH(host, username, keyfile string, stderr io.Writer) (*SSH, error) {
return &SSH{client: client, Stderr: stderr}, nil
}
func SSHClients(hosts []string, username, keyfile string, stderr io.Writer) ([]*SSH, error) {
type SSHFleet []*SSH
func SSHClients(hosts []string, username, keyfile string, stderr io.Writer) (SSHFleet, error) {
clients := make([]*SSH, len(hosts))
for i, host := range hosts {
client, err := NewSSH(host, username, keyfile, stderr)
@ -96,7 +100,7 @@ func (r *remoteFile) Close() error {
// will be passed directly to chmod to set the file permissions. rm, touch,
// chmod, cat and support for semicolons, double ampersand, and output
// redirection (>>) must be available in the remote shell.
func (s *SSH) OpenFile(name string, perm string) (io.WriteCloser, error) {
func (s *SSH) OpenFile(name, perm string) (io.WriteCloser, error) {
sess, err := s.NewSession()
if err != nil {
return nil, err
@ -115,3 +119,51 @@ func (s *SSH) OpenFile(name string, perm string) (io.WriteCloser, error) {
return &remoteFile{w: w, sess: sess}, nil
}
type multiWriteCloser struct {
wcs []io.WriteCloser
ws []io.Writer
}
func newMultiWriteCloser() *multiWriteCloser {
return &multiWriteCloser{
wcs: make([]io.WriteCloser, 0),
ws: make([]io.Writer, 0),
}
}
func (mwc *multiWriteCloser) add(wc io.WriteCloser) {
mwc.wcs = append(mwc.wcs, wc)
mwc.ws = append(mwc.ws, wc)
}
func (mwc *multiWriteCloser) Write(p []byte) (n int, err error) {
mw := io.MultiWriter(mwc.ws...)
return mw.Write(p)
}
func (mwc *multiWriteCloser) Close() error {
errStr := ""
for _, wc := range mwc.wcs {
err := wc.Close()
if err != nil {
errStr = errStr + "; " + err.Error()
}
}
if errStr != "" {
return errors.New(errStr)
}
return nil
}
func (sf SSHFleet) OpenFile(name, perm string) (io.WriteCloser, error) {
writers := newMultiWriteCloser()
for _, cli := range sf {
wc, err := cli.OpenFile(name, "+x")
if err != nil {
return nil, err
}
writers.add(wc)
}
return writers, nil
}