// TarLayer returns a tar archive of the image's filesystem layer. func (img *Image) TarLayer() (arch archive.Archive, err error) { if img.graph == nil { return nil, fmt.Errorf("Can't load storage driver for unregistered image %s", img.ID) } driver := img.graph.driver if differ, ok := driver.(graphdriver.Differ); ok { return differ.Diff(img.ID) } imgFs, err := driver.Get(img.ID) if err != nil { return nil, err } defer func() { if err == nil { driver.Put(img.ID) } }() if img.Parent == "" { archive, err := archive.Tar(imgFs, archive.Uncompressed) if err != nil { return nil, err } return EofReader(archive, func() { driver.Put(img.ID) }), nil } parentFs, err := driver.Get(img.Parent) if err != nil { return nil, err } defer driver.Put(img.Parent) changes, err := archive.ChangesDirs(imgFs, parentFs) if err != nil { return nil, err } archive, err := archive.ExportChanges(imgFs, changes) if err != nil { return nil, err } return EofReader(archive, func() { driver.Put(img.ID) }), nil }
func (runtime *Runtime) Diff(container *Container) (archive.Archive, error) { if differ, ok := runtime.driver.(graphdriver.Differ); ok { return differ.Diff(container.ID) } changes, err := runtime.Changes(container) if err != nil { return nil, err } cDir, err := runtime.driver.Get(container.ID) if err != nil { return nil, fmt.Errorf("Error getting container rootfs %s from driver %s: %s", container.ID, container.runtime.driver, err) } archive, err := archive.ExportChanges(cDir, changes) if err != nil { return nil, err } return EofReader(archive, func() { runtime.driver.Put(container.ID) }), nil }