/*input: ocidirectory output:rktdirectrory */ func (this *oci2rkt) makeRktBundle() (err error) { //this.RktBunldePath = "/var/lib/rkt/rktbunld" stage1Path := this.RktBundlePath + "/stage1" err = os.MkdirAll(stage1Path, 0755) if err != nil { return err } //extra stage1.aci r, err := os.Open(this.Stage1Image) if err != nil { return err } defer r.Close() dr, err := aci.NewCompressedReader(r) if err != nil { return fmt.Errorf("error decompressing image: %v", err) } err = ptar.ExtractTar(dr, stage1Path, true, uid.NewBlankUidRange(), nil) if err != nil { fmt.Printf("extra stage1 image error,%v\n", err) return err } return nil }
func (ms *ConversionStore) WriteACI(path string) (string, error) { f, err := os.Open(path) if err != nil { return "", err } defer f.Close() cr, err := aci.NewCompressedReader(f) if err != nil { return "", err } defer cr.Close() h := sha512.New() r := io.TeeReader(cr, h) // read the file so we can get the hash if _, err := io.Copy(ioutil.Discard, r); err != nil { return "", fmt.Errorf("error reading ACI: %v", err) } im, err := aci.ManifestFromImage(f) if err != nil { return "", err } key := ms.HashToKey(h) ms.acis[key] = &aciInfo{path: path, key: key, ImageManifest: im} return key, nil }
func (ms *ConversionStore) ReadStream(key string) (io.ReadCloser, error) { img, ok := ms.acis[key] if !ok { return nil, fmt.Errorf("stream for key: %s not found", key) } f, err := os.Open(img.path) if err != nil { return nil, fmt.Errorf("error opening aci: %s", img.path) } tr, err := aci.NewCompressedReader(f) if err != nil { return nil, err } return tr, nil }
// WriteACI takes an ACI encapsulated in an io.Reader, decompresses it if // necessary, and then stores it in the store under a key based on the image ID // (i.e. the hash of the uncompressed ACI) // latest defines if the aci has to be marked as the latest. For example an ACI // discovered without asking for a specific version (latest pattern). func (s Store) WriteACI(r io.ReadSeeker, latest bool) (string, error) { dr, err := aci.NewCompressedReader(r) if err != nil { return "", fmt.Errorf("error decompressing image: %v", err) } // Write the decompressed image (tar) to a temporary file on disk, and // tee so we can generate the hash h := sha512.New() tr := io.TeeReader(dr, h) fh, err := s.TmpFile() if err != nil { return "", fmt.Errorf("error creating image: %v", err) } if _, err := io.Copy(fh, tr); err != nil { return "", fmt.Errorf("error copying image: %v", err) } im, err := aci.ManifestFromImage(fh) if err != nil { return "", fmt.Errorf("error extracting image manifest: %v", err) } if err := fh.Close(); err != nil { return "", fmt.Errorf("error closing image: %v", err) } // Import the uncompressed image into the store at the real key key := s.HashToKey(h) keyLock, err := lock.ExclusiveKeyLock(s.imageLockDir, key) if err != nil { return "", fmt.Errorf("error locking image: %v", err) } defer keyLock.Close() if err = s.stores[blobType].Import(fh.Name(), key, true); err != nil { return "", fmt.Errorf("error importing image: %v", err) } // Save the imagemanifest using the same key used for the image imj, err := json.Marshal(im) if err != nil { return "", fmt.Errorf("error marshalling image manifest: %v", err) } if err = s.stores[imageManifestType].Write(key, imj); err != nil { return "", fmt.Errorf("error importing image manifest: %v", err) } // Save aciinfo if err = s.db.Do(func(tx *sql.Tx) error { aciinfo := &ACIInfo{ BlobKey: key, AppName: im.Name.String(), ImportTime: time.Now(), Latest: latest, } return WriteACIInfo(tx, aciinfo) }); err != nil { return "", fmt.Errorf("error writing ACI Info: %v", err) } // The treestore for this ACI is not written here as ACIs downloaded as // dependencies of another ACI will be exploded also if never directly used. // Users of treestore should call s.RenderTreeStore before using it. return key, nil }