func (pkg *smPackage) writeTargetState(client connection.Client) error { sess, err := client.NewSession() if err != nil { return err } defer sess.Close() stdin, err := sess.StdinPipe() if err != nil { return errors.Wrap(err, "failed to receive stdin pipe") } tstamp := time.Now().UTC().Format("20060102T150405") filename := fmt.Sprintf("/var/lib/smutje/%s.%s.log", pkg.ID, tstamp) cmd := fmt.Sprintf(`bash -c "cat - > %[1]s && ln -sf %[1]s /var/lib/smutje/%[2]s.log"`, filename, pkg.ID) if err := sess.Start(cmd); err != nil { return err } if _, err := io.WriteString(stdin, strings.Join(pkg.state, "\n")+"\n"); err != nil { return errors.Wrap(err, "failed to send script to target") } stdin.Close() return sess.Wait() }
func (s *bashScript) Exec(l logger.Logger, client connection.Client) error { sess, err := client.NewLoggedSession(l) if err != nil { return err } defer sess.Close() stdin, err := sess.StdinPipe() if err != nil { return errors.Wrap(err, "failed to receive stdin pipe") } defer stdin.Close() fname := fmt.Sprintf("/var/lib/smutje/%s.sh", s.hash) cmd := fmt.Sprintf(`bash -c "cat - > %[1]s && bash -l %[1]s"`, fname) if err := sess.Start(cmd); err != nil { return err } switch n, err := io.WriteString(stdin, s.Script); { case err != nil: return errors.Wrap(err, "failed to send script to target") case n != len(s.Script): return errors.Errorf("expected to send %d bytes, sent %d", len(s.Script), n) default: stdin.Close() return sess.Wait() } }
func runCommand(client connection.Client, cmd string) error { sess, err := client.NewSession() if err != nil { return err } defer sess.Close() if err := sess.Start(cmd); err != nil { return err } return sess.Wait() }
func (pkg *smPackage) readPackageState(client connection.Client) ([]string, error) { sess, err := client.NewSession() if err != nil { return nil, err } defer sess.Close() stdout, err := sess.StdoutPipe() if err != nil { return nil, err } fname := fmt.Sprintf("/var/lib/smutje/%s.log", pkg.ID) cmd := fmt.Sprintf(`bash -c "if [[ -f %[1]q ]]; then cat %[1]s; else mkdir -p /var/lib/smutje; fi"`, fname) if err := sess.Start(cmd); err != nil { return nil, err } buf := bytes.NewBuffer(nil) if _, err := io.Copy(buf, stdout); err != nil { return nil, errors.Wrap(err, "failed to copy output of command") } if err := sess.Wait(); err != nil { return nil, err } state := []string{} sc := bufio.NewScanner(buf) for sc.Scan() { l := sc.Text() switch l[0] { case '+', '.': state = append(state, l) case '-': //ignore default: return nil, errors.Errorf("invalid token read: %s", l) } } return state, errors.Wrap(sc.Err(), "failed to scan output") }
func (a *execJenkinsArtifactCmd) Exec(l logger.Logger, client connection.Client) error { sess, err := client.NewLoggedSession(l) if err != nil { return err } defer sess.Close() l.Printf("downloading file %q from %q", a.Target, a.url) setFilePerms := "" // TODO is possible to set only one of the both? if a.Owner != "" && a.Umask != "" { setFilePerms = " && chown " + a.Owner + " %[1]s && chmod " + a.Umask + " %[1]s" } cmd := fmt.Sprintf(`bash -c "{ dir=$(dirname %[1]s); test -d \${dir} || mkdir -p \${dir}; } && curl -sSL %[2]s -o %[1]s`+setFilePerms+`"`, a.Target, a.url) if err := sess.Start(cmd); err != nil { return err } return sess.Wait() }
func (a *execWriteFileCmd) Exec(l logger.Logger, clients connection.Client) error { r, err := a.read() if err != nil { return err } defer r.Close() sess, err := clients.NewLoggedSession(l) if err != nil { return err } defer sess.Close() stdin, err := sess.StdinPipe() if err != nil { return errors.Wrap(err, "failed to receive stdin pipe") } l.Printf("writing file %q", a.Target) setFilePerms := "" // TODO is possible to set only one of the both? if a.Owner != "" && a.Umask != "" { setFilePerms = " && chown " + a.Owner + " %[1]s && chmod " + a.Umask + " %[1]s" } cmd := fmt.Sprintf(`bash -c "{ dir=$(dirname %[1]s); test -d \${dir} || mkdir -p \${dir}; } && cat - > %[1]s`+setFilePerms+`"`, a.Target) if err := sess.Start(cmd); err != nil { return err } if _, err := io.Copy(stdin, r); err != nil { return errors.Wrap(err, "failed to send script to target") } stdin.Close() // TODO validate all bytes written // TODO use compression on the wire return sess.Wait() }