예제 #1
0
파일: file.go 프로젝트: coderhaoxin/rkt
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
}
예제 #2
0
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
}
예제 #3
0
파일: file.go 프로젝트: nhlfr/rkt
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
}
예제 #4
0
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
}
예제 #5
0
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
}
예제 #6
0
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
}