Пример #1
0
func (res *smResource) Provision(l logger.Logger) (err error) {
	l = l.Tag(res.ID)

	for _, pkg := range res.Packages {
		if err := pkg.Provision(l, res.client); err != nil {
			return err
		}
	}
	return nil
}
Пример #2
0
func (lsess *loggedSession) readStream(l logger.Logger, stream io.Reader) {
	defer lsess.wg.Done()

	sc := bufio.NewScanner(stream)
	for sc.Scan() {
		l.Printf(sc.Text())
	}

	if err := sc.Err(); err != nil {
		l.Printf("failed scanning stderr: %s", err)
	}
}
Пример #3
0
func (res *smResource) Prepare(l logger.Logger) error {
	l = l.Tag(res.ID)

	if err := res.initializeClient(); err != nil {
		return err
	}

	for _, pkg := range res.Packages {
		if err := pkg.Prepare(res.client, res.Attributes); err != nil {
			return err
		}
	}
	return nil
}
Пример #4
0
func newLoggedSession(l logger.Logger, sess Session) (Session, error) {
	s := &loggedSession{Session: sess, wg: new(sync.WaitGroup)}

	stdout, err := s.Session.StdoutPipe()
	if err != nil {
		return nil, errors.Wrap(err, "failed to build stdout pipe")
	}

	stderr, err := s.Session.StderrPipe()
	if err != nil {
		return nil, errors.Wrap(err, "failed to build stderr pipe")
	}

	s.wg.Add(2)
	go s.readStream(l.Tag("stdout"), stdout)
	go s.readStream(l.Tag("stderr"), stderr)

	return s, nil
}
Пример #5
0
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()
}
Пример #6
0
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()
}
Пример #7
0
func (pkg *smPackage) Provision(l logger.Logger, client connection.Client) (err error) {
	l = l.Tag(pkg.ID)

	oldState := pkg.state
	pkg.state = make([]string, len(pkg.Scripts))

	allCached := true

	defer func() {
		if allCached {
			return
		}

		e := pkg.writeTargetState(client)
		if err == nil {
			err = e
		}
	}()

	for i, s := range pkg.Scripts {
		hash := s.Hash()

		if allCached && i < len(oldState) && oldState[i][1:] == hash {
			l.Printf("step %d cached", i)
			pkg.state[i] = "." + hash
			continue
		}

		allCached = false
		if err = s.Exec(l, client); err != nil {
			l.Printf("failed in %s", hash)
			pkg.state[i] = "-" + hash
			pkg.state = pkg.state[:i+1]
			return err
		}
		pkg.state[i] = "+" + hash
	}
	return nil
}
Пример #8
0
func (hp *smartOS) Create(l logger.Logger, blueprint string) (string, error) {
	m := map[string]interface{}{}
	if err := json.Unmarshal([]byte(blueprint), &m); err != nil {
		return "", errors.Wrap(err, "failed to unmarshal the blueprint")
	}

	l.Printf("updating the image database")
	if err := runCommand(hp.client, "imgadm update"); err != nil {
		return "", err
	}

	imgUUID := m["image_uuid"].(string)
	l.Printf("importing image %s", imgUUID)
	if err := runCommand(hp.client, "imgadm import -q "+imgUUID); err != nil {
		return "", err
	}

	// determine whether the VM in question already exists
	sess, err := hp.client.NewSession()
	if err != nil {
		return "", err
	}
	defer sess.Close()

	wg := new(sync.WaitGroup)
	wg.Add(2)

	outBuf := bytes.NewBuffer(nil)
	stderr, err := sess.StderrPipe()
	if err != nil {
		return "", errors.Wrap(err, "failed to retrieve stderr pipe")
	}
	go func() {
		defer wg.Done()
		_, _ = io.Copy(outBuf, stderr)
	}()

	stdin, err := sess.StdinPipe()
	if err != nil {
		return "", errors.Wrap(err, "failed to retrieve stdin pipe")
	}
	go func() {
		defer wg.Done()
		_, _ = io.WriteString(stdin, blueprint)
		stdin.Close()
	}()

	l.Printf("creating the virtual resource")
	if err := sess.Run("vmadm create"); err != nil {
		log.Printf("failed: %s", outBuf.String())
		return "", err
	}

	wg.Wait()

	output := strings.TrimSpace(outBuf.String())
	expResponsePrefix := "Successfully created VM "
	if !strings.HasPrefix(output, expResponsePrefix) {
		return "", errors.Errorf("wrong response received: %s", output)
	}

	return strings.TrimPrefix(output, expResponsePrefix), nil
}