From 537b3878effdddf121eb7af7f07173dba21c78db Mon Sep 17 00:00:00 2001 From: jaffee Date: Thu, 22 Dec 2016 12:19:18 -0600 Subject: [PATCH] build and copy pilosactl to remote agents --- cmd/pilosactl/main.go | 42 +++++++++++++++++++++++++++++++-- cmd/pilosactl/multidbspawn.json | 6 +++-- creator/remote.go | 2 +- pilosactl/ssh.go | 12 ++++++++-- 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/cmd/pilosactl/main.go b/cmd/pilosactl/main.go index c45b01a16..5494e7841 100644 --- a/cmd/pilosactl/main.go +++ b/cmd/pilosactl/main.go @@ -13,7 +13,9 @@ import ( "log" "math/rand" "os" + "os/exec" "os/signal" + "path" "path/filepath" "sort" "strconv" @@ -1328,6 +1330,8 @@ type BspawnCommand struct { // agents specified here are used. AgentHosts []string + CopyBinary bool + // Benchmarks is a slice of Spawns which specifies all of the bagent // commands to run. These will all be run in parallel, started on each // of the agents in a round robin fashion. @@ -1430,10 +1434,44 @@ func (cmd *BspawnCommand) Run(ctx context.Context) error { func (cmd *BspawnCommand) spawnRemote(ctx context.Context, runUUID uuid.UUID) error { agentIndex := 0 - agentConnections, err := pilosactl.SSHClients(cmd.AgentHosts, cmd.SSHUser, "") + agentConnections, err := pilosactl.SSHClients(cmd.AgentHosts, cmd.SSHUser, "", cmd.Stderr) if err != nil { return err } + if cmd.CopyBinary { + binLoc := path.Join(os.TempDir(), "pilosactl") + cmd := exec.Command("go", "build", "-o", binLoc, "github.com/pilosa/pilosa/cmd/pilosactl") + cmd.Env = append([]string{"GOOS=linux", "GOARCH=amd64"}, os.Environ()...) + err := cmd.Run() + if err != nil { + return err + } + agentWriters := make([]io.Writer, len(agentConnections)) + for i, conn := range agentConnections { + agentWriters[i], err = conn.OpenFile("pilosactl", "+x") + if err != nil { + return err + } + } + f, err := os.Open(binLoc) + if err != nil { + return err + } + _, err = io.Copy(io.MultiWriter(agentWriters...), f) + if err != nil { + return err + } + + for _, w := range agentWriters { + if wc, ok := w.(io.WriteCloser); ok { + err = wc.Close() + if err != nil { + return err + } + } + } + } + sessions := make([]*ssh.Session, 0) for _, sp := range cmd.Benchmarks { for i := 0; i < sp.Num; i++ { @@ -1444,7 +1482,7 @@ func (cmd *BspawnCommand) spawnRemote(ctx context.Context, runUUID uuid.UUID) er sessions = append(sessions, sess) sess.Stdout = cmd.Stdout sess.Stderr = cmd.Stderr - err = sess.Start("pilosactl bagent -agentNum=" + strconv.Itoa(i) + " -hosts=" + strings.Join(cmd.PilosaHosts, ",") + " -run-uuid=" + runUUID.String() + " " + strings.Join(sp.Args, " ")) + err = sess.Start("PATH=.:$PATH pilosactl bagent -agentNum=" + strconv.Itoa(i) + " -hosts=" + strings.Join(cmd.PilosaHosts, ",") + " -run-uuid=" + runUUID.String() + " " + strings.Join(sp.Args, " ")) if err != nil { return err } diff --git a/cmd/pilosactl/multidbspawn.json b/cmd/pilosactl/multidbspawn.json index 6be8b40f3..379fec0dd 100644 --- a/cmd/pilosactl/multidbspawn.json +++ b/cmd/pilosactl/multidbspawn.json @@ -1,6 +1,8 @@ { - "CreatorArgs": ["-hosts", "localhost:19444,localhost:19445,localhost:19446", "-log-file-prefix", "multidblog"], - "AgentHosts": ["localhost"], + "CreatorArgs": ["-hosts", "pilosa0.jaffee.sandbox.pilosa.com:15000,pilosa1.jaffee.sandbox.pilosa.com:15000,pilosa2.jaffee.sandbox.pilosa.com:15000", "-log-file-prefix", "multidblog", "-ssh-user", "ubuntu"], + "AgentHosts": ["agent0.jaffee.sandbox.pilosa.com"], + "SSHUser": "ubuntu", + "CopyBinary": true, "Benchmarks": [ { "Num": 3, diff --git a/creator/remote.go b/creator/remote.go index 41c1c9ca7..d951d7d4d 100644 --- a/creator/remote.go +++ b/creator/remote.go @@ -62,7 +62,7 @@ func (c *RemoteCluster) Start() error { return err } configname := "pilosa" + port + ".conf" - w, err := client.OpenFile(configname) + w, err := client.OpenFile(configname, "") if err != nil { return fmt.Errorf("opening remote config file: %v", err) } diff --git a/pilosactl/ssh.go b/pilosactl/ssh.go index 98ab6d18a..a42b776fc 100644 --- a/pilosactl/ssh.go +++ b/pilosactl/ssh.go @@ -91,7 +91,12 @@ func (r *remoteFile) Close() error { return nil } -func (s *SSH) OpenFile(name string) (io.WriteCloser, error) { +// OpenFile creates or truncates an existing file of the given name on the +// remote host, and returns a WriteCloser which will write to that file. perm +// 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) { sess, err := s.NewSession() if err != nil { return nil, err @@ -100,7 +105,10 @@ func (s *SSH) OpenFile(name string) (io.WriteCloser, error) { if err != nil { return nil, err } - err = sess.Start("cat > " + name) + if perm == "" { + perm = "0664" + } + err = sess.Start(fmt.Sprintf("rm %v; touch %v && chmod %v %v && cat >> %v", name, name, perm, name, name)) if err != nil { return nil, err }