Example #1
0
func main() {
	sw := ui.NewSpinningWriter("", ioutil.Discard)
	defer sw.Close()
	if _, err := io.Copy(sw, os.Stdin); err != nil {
		fmt.Println(err)
	}
}
Example #2
0
//  Write ACI to `, return its hash. If packlist file is nil, writes
//  flat ACI (and manifest omits the dependencies).
func (img *Image) writeACI(w io.Writer, packlist *os.File) (*types.Hash, error) {
	var sink io.WriteCloser
	var faucet io.Reader

	sw := ui.NewSpinningWriter("Writing ACI", w)
	defer sw.Close()
	sink = sw

	tarArgs := []string{"-C", img.Path(), "-c", "--null", "-f", "-"}
	if packlist != nil {
		img.ui.Debug("Writing an incremental ACI")
		tarArgs = append(tarArgs, "-n", "-T", "-")
	} else {
		img.ui.Debug("Writing a flat ACI")

		// no packlist -> flat ACI
		manifest := img.Manifest
		manifest.Dependencies = nil
		manifest.PathWhitelist = nil

		manifestF, err := ioutil.TempFile(img.Path(), "manifest.flat.")
		if err != nil {
			return nil, errors.Trace(err)
		}
		defer os.Remove(manifestF.Name())

		if manifestB, err := json.Marshal(manifest); err != nil {
			manifestF.Close()
			return nil, errors.Trace(err)
		} else {
			_, err := manifestF.Write(manifestB)
			manifestF.Close()
			if err != nil {
				return nil, errors.Trace(err)
			}
		}

		manifestN := filepath.Base(manifestF.Name())
		tarArgs = append(tarArgs, "-s", "/^"+manifestN+"$/manifest/", manifestN, "rootfs")
	}

	tar := run.Command("tar", tarArgs...).ReadFrom(packlist)
	if tarPipe, err := tar.StdoutPipe(); err != nil {
		return nil, errors.Trace(err)
	} else {
		faucet = tarPipe
	}

	hash := sha512.New()
	faucet = io.TeeReader(faucet, hash)

	var compressor *run.Cmd = nil
	if compression := Config().GetString("images.aci.compression", "no"); compression != "none" {
		switch compression {
		case "xz":
			compressor = run.Command("xz", "-z", "-c")
		case "bzip2":
			compressor = run.Command("bzip2", "-z", "-c")
		case "gz":
		case "gzip":
			compressor = run.Command("gzip", "-c")
		default:
			return nil, errors.Errorf("Invalid setting images.aci.compression=%#v (allowed values: xz, bzip2, gzip, none)", compression)
		}

		compressor.Cmd.Stdout = sink
		if cin, err := compressor.StdinPipe(); err != nil {
			return nil, errors.Trace(err)
		} else {
			sink = cin
		}
	}

	if err := tar.Start(); err != nil {
		return nil, errors.Trace(err)
	}

	if compressor != nil {
		if err := compressor.Start(); err != nil {
			tar.Kill()
			return nil, errors.Trace(err)
		}
	}

	if _, err := io.Copy(sink, faucet); err != nil {
		sink.Close()
		tar.Kill()
		compressor.Kill()
		return nil, errors.Trace(err)
	}

	if err := tar.Wait(); err != nil {
		sink.Close()
		compressor.Kill()
		return nil, errors.Trace(err)
	}

	sink.Close()

	if err := compressor.Wait(); err != nil {
		return nil, errors.Trace(err)
	}

	if hash, err := types.NewHash(fmt.Sprintf("sha512-%x", hash.Sum(nil))); err != nil {
		// CAN'T HAPPEN, srsly
		return nil, errors.Trace(err)
	} else {
		img.ui.Debug("Saved", hash)
		return hash, nil
	}
}