Example #1
0
// Stream the tarball from docker and translate it into the portable repo format
// Note that its easier to handle as a stream on the way out.
func (cli *DogestryCli) exportImageToFiles(image, root string, saveIds set) error {
	fmt.Printf("Exporting image: %v to: %v\n", image, root)

	reader, writer := io.Pipe()
	defer writer.Close()
	defer reader.Close()

	tarball := tar.NewReader(reader)

	errch := make(chan error)

	go func() {
		defer close(errch)
		for {
			header, err := tarball.Next()

			if err == io.EOF {
				break
			}

			if err != nil {
				errch <- err
				return
			}

			parts := strings.Split(header.Name, "/")
			idFromFile := remote.ID(parts[0])

			if _, ok := saveIds[idFromFile]; ok {
				if err := cli.createFileFromTar(root, header, tarball); err != nil {
					errch <- err
					return
				}
			} else {
				// Drain the reader. Is this necessary?
				if _, err := io.Copy(ioutil.Discard, tarball); err != nil {
					errch <- err
					return
				}

			}
		}

		errch <- nil
	}()

	if err := cli.Client.ExportImage(docker.ExportImageOptions{image, writer}); err != nil {
		return err
	}

	// wait for the tar reader
	if err := <-errch; err != nil {
		return err
	}

	return nil
}
Example #2
0
func (cli *DogestryCli) exportToFiles(image string, r remote.Remote, imageRoot string) error {
	imageHistory, err := cli.Client.ImageHistory(image)
	if err != nil {
		fmt.Printf("Error getting image history: %v\n", err)
		return err
	}

	fmt.Println("Checking layers on remote")

	imageID := remote.ID(imageHistory[0].ID)
	repoName, repoTag := remote.NormaliseImageName(image)

	// Check the remote to see what layers are missing. Only missing Ids will
	// need to be saved to disk when exporting the docker image.

	missingIds := make(set)

	for _, i := range imageHistory {
		id := remote.ID(i.ID)
		_, err = r.ImageMetadata(id)
		if err == nil {
			fmt.Printf("  exists   : %v\n", id)
		} else {
			fmt.Printf("  not found: %v\n", id)
			missingIds[id] = empty
		}
	}

	if len(missingIds) > 0 {
		if err := cli.exportImageToFiles(image, imageRoot, missingIds); err != nil {
			return err
		}
	}

	if err := cli.exportMetaDataToFiles(repoName, repoTag, imageID, imageRoot); err != nil {
		return err
	}

	return nil
}