func (lb *FileBackend) BuildACIV22(layerIDs []string, dockerURL *types.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) { if len(layerIDs) < 2 { return nil, nil, fmt.Errorf("insufficient layers for oci image") } var aciLayerPaths []string var aciManifests []*schema.ImageManifest var curPwl []string imageID := layerIDs[0] layerIDs = layerIDs[1:] j, err := getJsonV22(lb.file, imageID) if err != nil { return nil, nil, fmt.Errorf("error getting layer from file: %v", err) } imageConfig := typesV2.ImageConfig{} if err := json.Unmarshal(j, &imageConfig); err != nil { return nil, nil, fmt.Errorf("error unmarshaling image data: %v", err) } tmpDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return nil, nil, fmt.Errorf("error creating dir: %v", err) } defer os.RemoveAll(tmpDir) for i := len(layerIDs) - 1; i >= 0; i-- { parts := strings.Split(layerIDs[i], ":") tmpLayerPath := path.Join(tmpDir, parts[1]) tmpLayerPath += ".tar" layerTarPath := path.Join(append([]string{"blobs"}, parts...)...) layerFile, err := extractEmbeddedLayer(lb.file, layerTarPath, tmpLayerPath) if err != nil { return nil, nil, fmt.Errorf("error getting layer from file: %v", err) } defer layerFile.Close() log.Debug("Generating layer ACI...") var aciPath string var manifest *schema.ImageManifest if i != 0 { aciPath, manifest, err = internal.GenerateACI22LowerLayer(dockerURL, parts[1], outputDir, layerFile, curPwl, compression) } else { aciPath, manifest, err = internal.GenerateACI22TopLayer(dockerURL, &imageConfig, parts[1], outputDir, layerFile, curPwl, compression, aciManifests) } if err != nil { return nil, nil, fmt.Errorf("error generating ACI: %v", err) } aciLayerPaths = append(aciLayerPaths, aciPath) aciManifests = append(aciManifests, manifest) curPwl = manifest.PathWhitelist } return aciLayerPaths, aciManifests, nil }
func (rb *RepositoryBackend) buildACIV22(layerIDs []string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) { layerFiles := make([]*os.File, len(layerIDs)) tmpParentDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return nil, nil, err } defer os.RemoveAll(tmpParentDir) copier := progressutil.NewCopyProgressPrinter() resultChan := make(chan layer, len(layerIDs)) for i, layerID := range layerIDs { if err := common.ValidateLayerId(layerID); err != nil { return nil, nil, err } // https://github.com/golang/go/wiki/CommonMistakes i := i // golang-- layerID := layerID go func() { tmpDir, err := ioutil.TempDir(tmpParentDir, "") if err != nil { resultChan <- layer{ index: i, err: fmt.Errorf("error creating dir: %v", err), } return } layerFile, closer, err := rb.getLayerV2(layerID, dockerURL, tmpDir, copier) if err != nil { resultChan <- layer{ index: i, err: fmt.Errorf("error getting the remote layer: %v", err), } return } resultChan <- layer{ index: i, file: layerFile, closer: closer, err: nil, } }() } var errs []error for i := 0; i < len(layerIDs); i++ { res := <-resultChan if res.closer != nil { defer res.closer.Close() } if res.file != nil { defer res.file.Close() } if res.err != nil { errs = append(errs, res.err) } layerFiles[res.index] = res.file } if len(errs) > 0 { return nil, nil, errs[0] } err = copier.PrintAndWait(os.Stderr, 500*time.Millisecond, nil) if err != nil { return nil, nil, err } for _, layerFile := range layerFiles { err := layerFile.Sync() if err != nil { return nil, nil, err } } var aciLayerPaths []string var aciManifests []*schema.ImageManifest var curPwl []string var i int for i = 0; i < len(layerIDs)-1; i++ { rb.debug.Println("Generating layer ACI...") aciPath, aciManifest, err := internal.GenerateACI22LowerLayer(dockerURL, layerIDs[i], outputDir, layerFiles[i], curPwl, compression) if err != nil { return nil, nil, fmt.Errorf("error generating ACI: %v", err) } aciLayerPaths = append(aciLayerPaths, aciPath) aciManifests = append(aciManifests, aciManifest) curPwl = aciManifest.PathWhitelist } rb.debug.Println("Generating layer ACI...") aciPath, aciManifest, err := internal.GenerateACI22TopLayer(dockerURL, rb.imageConfigs[*dockerURL], layerIDs[i], outputDir, layerFiles[i], curPwl, compression, aciManifests, rb.debug) if err != nil { return nil, nil, fmt.Errorf("error generating ACI: %v", err) } aciLayerPaths = append(aciLayerPaths, aciPath) aciManifests = append(aciManifests, aciManifest) return aciLayerPaths, aciManifests, nil }