func (lb *FileBackend) BuildACI(layerNumber int, layerID string, dockerURL *types.ParsedDockerURL, outputDir string, tmpBaseDir string, curPwl []string, compression common.Compression) (string, *schema.ImageManifest, error) { tmpDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return "", nil, fmt.Errorf("error creating dir: %v", err) } defer os.RemoveAll(tmpDir) j, err := getJson(lb.file, layerID) if err != nil { return "", nil, fmt.Errorf("error getting image json: %v", err) } layerData := types.DockerImageData{} if err := json.Unmarshal(j, &layerData); err != nil { return "", nil, fmt.Errorf("error unmarshaling layer data: %v", err) } tmpLayerPath := path.Join(tmpDir, layerID) tmpLayerPath += ".tar" layerFile, err := extractEmbeddedLayer(lb.file, layerID, tmpLayerPath) if err != nil { return "", nil, fmt.Errorf("error getting layer from file: %v", err) } defer layerFile.Close() log.Debug("Generating layer ACI...") aciPath, manifest, err := internal.GenerateACI(layerNumber, layerData, dockerURL, outputDir, layerFile, curPwl, compression) if err != nil { return "", nil, fmt.Errorf("error generating ACI: %v", err) } return aciPath, manifest, nil }
func (rb *RepositoryBackend) buildACIV1(layerNumber int, layerID string, dockerURL *types.ParsedDockerURL, outputDir string, tmpBaseDir string, curPwl []string, compression common.Compression) (string, *schema.ImageManifest, error) { tmpDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return "", nil, fmt.Errorf("error creating dir: %v", err) } defer os.RemoveAll(tmpDir) j, size, err := rb.getJsonV1(layerID, rb.repoData.Endpoints[0], rb.repoData) if err != nil { return "", nil, fmt.Errorf("error getting image json: %v", err) } layerData := types.DockerImageData{} if err := json.Unmarshal(j, &layerData); err != nil { return "", nil, fmt.Errorf("error unmarshaling layer data: %v", err) } layerFile, err := rb.getLayerV1(layerID, rb.repoData.Endpoints[0], rb.repoData, size, tmpDir) if err != nil { return "", nil, fmt.Errorf("error getting the remote layer: %v", err) } defer layerFile.Close() log.Debug("Generating layer ACI...") aciPath, manifest, err := internal.GenerateACI(layerNumber, layerData, dockerURL, outputDir, layerFile, curPwl, compression) if err != nil { return "", nil, fmt.Errorf("error generating ACI: %v", err) } return aciPath, manifest, nil }
func (lb *FileBackend) BuildACI(layerIDs []string, dockerURL *types.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) { if strings.Contains(layerIDs[0], ":") { return lb.BuildACIV22(layerIDs, dockerURL, outputDir, tmpBaseDir, compression) } var aciLayerPaths []string var aciManifests []*schema.ImageManifest var curPwl []string 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-- { if err := common.ValidateLayerId(layerIDs[i]); err != nil { return nil, nil, err } j, err := getJson(lb.file, layerIDs[i]) if err != nil { return nil, nil, fmt.Errorf("error getting layer json: %v", err) } layerData := types.DockerImageData{} if err := json.Unmarshal(j, &layerData); err != nil { return nil, nil, fmt.Errorf("error unmarshaling layer data: %v", err) } tmpLayerPath := path.Join(tmpDir, layerIDs[i]) tmpLayerPath += ".tar" layerTarPath := path.Join(layerIDs[i], "layer.tar") 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...") aciPath, manifest, err := internal.GenerateACI(i, layerData, dockerURL, outputDir, layerFile, curPwl, compression) 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) buildACIV2(layerNumber int, layerID string, dockerURL *types.ParsedDockerURL, outputDir string, tmpBaseDir string, curPwl []string, compression common.Compression) (string, *schema.ImageManifest, error) { manifest := rb.imageManifests[*dockerURL] layerIndex, err := getLayerIndex(layerID, manifest) if err != nil { return "", nil, err } if len(manifest.History) <= layerIndex { return "", nil, fmt.Errorf("history not found for layer %s", layerID) } layerData := types.DockerImageData{} if err := json.Unmarshal([]byte(manifest.History[layerIndex].V1Compatibility), &layerData); err != nil { return "", nil, fmt.Errorf("error unmarshaling layer data: %v", err) } tmpDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return "", nil, fmt.Errorf("error creating dir: %v", err) } defer os.RemoveAll(tmpDir) layerFile, err := rb.getLayerV2(layerID, dockerURL, tmpDir) if err != nil { return "", nil, fmt.Errorf("error getting the remote layer: %v", err) } defer layerFile.Close() log.Debug("Generating layer ACI...") aciPath, aciManifest, err := internal.GenerateACI(layerNumber, layerData, dockerURL, outputDir, layerFile, curPwl, compression) if err != nil { return "", nil, fmt.Errorf("error generating ACI: %v", err) } return aciPath, aciManifest, nil }
func (rb *RepositoryBackend) buildACIV1(layerIDs []string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) { layerFiles := make([]*os.File, len(layerIDs)) layerDatas := make([]types.DockerImageData, len(layerIDs)) tmpParentDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return nil, nil, err } defer os.RemoveAll(tmpParentDir) var doneChannels []chan error for i, layerID := range layerIDs { if err := common.ValidateLayerId(layerID); err != nil { return nil, nil, err } doneChan := make(chan error) doneChannels = append(doneChannels, doneChan) // https://github.com/golang/go/wiki/CommonMistakes i := i // golang-- layerID := layerID go func() { tmpDir, err := ioutil.TempDir(tmpParentDir, "") if err != nil { doneChan <- fmt.Errorf("error creating dir: %v", err) return } j, size, err := rb.getJsonV1(layerID, rb.repoData.Endpoints[0], rb.repoData) if err != nil { doneChan <- fmt.Errorf("error getting image json: %v", err) return } layerDatas[i] = types.DockerImageData{} if err := json.Unmarshal(j, &layerDatas[i]); err != nil { doneChan <- fmt.Errorf("error unmarshaling layer data: %v", err) return } layerFiles[i], err = rb.getLayerV1(layerID, rb.repoData.Endpoints[0], rb.repoData, size, tmpDir) if err != nil { doneChan <- fmt.Errorf("error getting the remote layer: %v", err) return } doneChan <- nil }() } for _, doneChan := range doneChannels { err := <-doneChan if err != nil { return nil, nil, err } } var aciLayerPaths []string var aciManifests []*schema.ImageManifest var curPwl []string for i := len(layerIDs) - 1; i >= 0; i-- { rb.debug.Println("Generating layer ACI...") aciPath, manifest, err := internal.GenerateACI(i, layerDatas[i], dockerURL, outputDir, layerFiles[i], curPwl, compression, rb.debug) if err != nil { return nil, nil, fmt.Errorf("error generating ACI: %v", err) } aciLayerPaths = append(aciLayerPaths, aciPath) aciManifests = append(aciManifests, manifest) curPwl = manifest.PathWhitelist layerFiles[i].Close() } return aciLayerPaths, aciManifests, nil }
func (rb *RepositoryBackend) buildACIV21(layerIDs []string, dockerURL *common.ParsedDockerURL, outputDir string, tmpBaseDir string, compression common.Compression) ([]string, []*schema.ImageManifest, error) { layerFiles := make([]*os.File, len(layerIDs)) layerDatas := make([]types.DockerImageData, len(layerIDs)) tmpParentDir, err := ioutil.TempDir(tmpBaseDir, "docker2aci-") if err != nil { return nil, nil, err } defer os.RemoveAll(tmpParentDir) copier := progressutil.NewCopyProgressPrinter() var errChannels []chan error closers := make([]io.ReadCloser, len(layerIDs)) var wg sync.WaitGroup for i, layerID := range layerIDs { if err := common.ValidateLayerId(layerID); err != nil { return nil, nil, err } wg.Add(1) errChan := make(chan error, 1) errChannels = append(errChannels, errChan) // https://github.com/golang/go/wiki/CommonMistakes i := i // golang-- layerID := layerID go func() { defer wg.Done() manifest := rb.imageManifests[*dockerURL] layerIndex, ok := rb.layersIndex[layerID] if !ok { errChan <- fmt.Errorf("layer not found in manifest: %s", layerID) return } if len(manifest.History) <= layerIndex { errChan <- fmt.Errorf("history not found for layer %s", layerID) return } layerDatas[i] = types.DockerImageData{} if err := json.Unmarshal([]byte(manifest.History[layerIndex].V1Compatibility), &layerDatas[i]); err != nil { errChan <- fmt.Errorf("error unmarshaling layer data: %v", err) return } tmpDir, err := ioutil.TempDir(tmpParentDir, "") if err != nil { errChan <- fmt.Errorf("error creating dir: %v", err) return } layerFiles[i], closers[i], err = rb.getLayerV2(layerID, dockerURL, tmpDir, copier) if err != nil { errChan <- fmt.Errorf("error getting the remote layer: %v", err) return } errChan <- nil }() } // Need to wait for all of the readers to be added to the copier (which happens during rb.getLayerV2) wg.Wait() err = copier.PrintAndWait(os.Stderr, 500*time.Millisecond, nil) if err != nil { return nil, nil, err } for _, closer := range closers { if closer != nil { closer.Close() } } for _, errChan := range errChannels { err := <-errChan 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 for i := len(layerIDs) - 1; i >= 0; i-- { rb.debug.Println("Generating layer ACI...") aciPath, aciManifest, err := internal.GenerateACI(i, layerDatas[i], dockerURL, outputDir, layerFiles[i], curPwl, compression, rb.debug) if err != nil { return nil, nil, fmt.Errorf("error generating ACI: %v", err) } aciLayerPaths = append(aciLayerPaths, aciPath) aciManifests = append(aciManifests, aciManifest) curPwl = aciManifest.PathWhitelist layerFiles[i].Close() } return aciLayerPaths, aciManifests, nil }