Example #1
0
func maybeDecompress(rs io.ReadSeeker) (io.Reader, error) {
	// TODO(jonboulle): this is a bit redundant with detectValType
	typ, err := aci.DetectFileType(rs)
	if err != nil {
		return nil, err
	}
	if _, err := rs.Seek(0, 0); err != nil {
		return nil, err
	}
	var r io.Reader
	switch typ {
	case aci.TypeGzip:
		r, err = gzip.NewReader(rs)
		if err != nil {
			return nil, fmt.Errorf("error reading gzip: %v", err)
		}
	case aci.TypeBzip2:
		r = bzip2.NewReader(rs)
	case aci.TypeXz:
		r = aci.XzReader(rs)
	case aci.TypeTar:
		r = rs
	case aci.TypeUnknown:
		return nil, errors.New("unknown filetype")
	default:
		// should never happen
		panic(fmt.Sprintf("bad type returned from DetectFileType: %v", typ))
	}
	return r, nil
}
Example #2
0
// unpackRootfs unpacks a stage1 rootfs (compressed file, pointed to by rfs)
// into dir, returning any error encountered
func unpackRootfs(rfs string, dir string) error {
	fh, err := os.Open(rfs)
	if err != nil {
		return fmt.Errorf("error opening stage1 rootfs: %v", err)
	}
	typ, err := aci.DetectFileType(fh)
	if err != nil {
		return fmt.Errorf("error detecting image type: %v", err)
	}
	if _, err := fh.Seek(0, 0); err != nil {
		return fmt.Errorf("error seeking image: %v", err)
	}
	var r io.Reader
	switch typ {
	case aci.TypeGzip:
		r, err = gzip.NewReader(fh)
		if err != nil {
			return fmt.Errorf("error reading gzip: %v", err)
		}
	case aci.TypeBzip2:
		r = bzip2.NewReader(fh)
	case aci.TypeXz:
		r = aci.XzReader(fh)
	case aci.TypeTar:
		r = fh
	case aci.TypeUnknown:
		return fmt.Errorf("error: unknown image filetype")
	default:
		// should never happen
		panic("no type returned from DetectFileType?")
	}
	return untarRootfs(r, dir)
}
Example #3
0
func (ds Store) WriteACI(tmpKey string, orig io.Reader) (string, error) {
	// We initially write the ACI into the store using a temporary key,
	// teeing a header so we can detect the filetype for decompression
	hdr := &bytes.Buffer{}
	hw := &pkgio.LimitedWriter{
		W: hdr,
		N: 512,
	}
	tr := io.TeeReader(orig, hw)

	err := ds.stores[tmpType].WriteStream(tmpKey, tr, true)
	if err != nil {
		return "", err
	}

	// Now detect the filetype so we can choose the appropriate decompressor
	typ, err := aci.DetectFileType(hdr)
	if err != nil {
		return "", err
	}
	// Read the image back out of the store to generate the hash of the decompressed tar
	rs, err := ds.stores[tmpType].ReadStream(tmpKey, false)
	if err != nil {
		return "", err
	}
	defer rs.Close()

	dr, err := decompress(rs, typ)
	if err != nil {
		return "", err
	}
	hash := sha256.New()
	_, err = io.Copy(hash, dr)
	if err != nil {
		return "", err
	}

	// Store the decompressed tar using the hash as the real key
	rs, err = ds.stores[tmpType].ReadStream(tmpKey, false)
	if err != nil {
		return "", err
	}
	defer rs.Close()
	dr, err = decompress(rs, typ)
	if err != nil {
		return "", err
	}

	key := fmt.Sprintf("sha256-%x", hash.Sum(nil))
	err = ds.stores[blobType].WriteStream(key, dr, true)
	if err != nil {
		return "", err
	}

	ds.stores[tmpType].Erase(tmpKey)

	return key, nil
}
Example #4
0
func detectValType(file *os.File) (string, error) {
	typ, err := aci.DetectFileType(file)
	if err != nil {
		return "", err
	}
	if _, err := file.Seek(0, 0); err != nil {
		return "", err
	}
	switch typ {
	case aci.TypeXz, aci.TypeGzip, aci.TypeBzip2, aci.TypeTar:
		return typeAppImage, nil
	case aci.TypeText:
		return typeManifest, nil
	default:
		return "", nil
	}
}