| // +build windows |
| |
| package graph |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| "os" |
| |
| "github.com/Sirupsen/logrus" |
| "github.com/docker/docker/daemon/graphdriver/windows" |
| "github.com/docker/docker/image" |
| "github.com/docker/docker/pkg/archive" |
| ) |
| |
| // setupInitLayer populates a directory with mountpoints suitable |
| // for bind-mounting dockerinit into the container. T |
| func SetupInitLayer(initLayer string) error { |
| return nil |
| } |
| |
| func createRootFilesystemInDriver(graph *Graph, img *image.Image, layerData archive.ArchiveReader) error { |
| if wd, ok := graph.driver.(*windows.WindowsGraphDriver); ok { |
| if img.Container != "" && layerData == nil { |
| logrus.Debugf("Copying from container %s.", img.Container) |
| |
| var ids []string |
| if img.Parent != "" { |
| parentImg, err := graph.Get(img.Parent) |
| if err != nil { |
| return err |
| } |
| |
| ids, err = graph.ParentLayerIds(parentImg) |
| if err != nil { |
| return err |
| } |
| } |
| |
| if err := wd.CopyDiff(img.Container, img.ID, wd.LayerIdsToPaths(ids)); err != nil { |
| return fmt.Errorf("Driver %s failed to copy image rootfs %s: %s", graph.driver, img.Container, err) |
| } |
| } else if img.Parent == "" { |
| if err := graph.driver.Create(img.ID, img.Parent); err != nil { |
| return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err) |
| } |
| } |
| } else { |
| // This fallback allows the use of VFS during daemon development. |
| if err := graph.driver.Create(img.ID, img.Parent); err != nil { |
| return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err) |
| } |
| } |
| return nil |
| } |
| |
| func (graph *Graph) restoreBaseImages() ([]string, error) { |
| // TODO Windows. This needs implementing (@swernli) |
| return nil, nil |
| } |
| |
| // ParentLayerIds returns a list of all parent image IDs for the given image. |
| func (graph *Graph) ParentLayerIds(img *image.Image) (ids []string, err error) { |
| for i := img; i != nil && err == nil; i, err = graph.GetParent(i) { |
| ids = append(ids, i.ID) |
| } |
| |
| return |
| } |
| |
| // storeImage stores file system layer data for the given image to the |
| // graph's storage driver. Image metadata is stored in a file |
| // at the specified root directory. |
| func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) { |
| |
| if wd, ok := graph.driver.(*windows.WindowsGraphDriver); ok { |
| // Store the layer. If layerData is not nil and this isn't a base image, |
| // unpack it into the new layer |
| if layerData != nil && img.Parent != "" { |
| var ids []string |
| if img.Parent != "" { |
| parentImg, err := graph.Get(img.Parent) |
| if err != nil { |
| return err |
| } |
| |
| ids, err = graph.ParentLayerIds(parentImg) |
| if err != nil { |
| return err |
| } |
| } |
| |
| if img.Size, err = wd.Import(img.ID, layerData, wd.LayerIdsToPaths(ids)); err != nil { |
| return err |
| } |
| } |
| |
| if err := graph.saveSize(root, int(img.Size)); err != nil { |
| return err |
| } |
| |
| f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600)) |
| if err != nil { |
| return err |
| } |
| |
| defer f.Close() |
| |
| return json.NewEncoder(f).Encode(img) |
| } else { |
| // We keep this functionality here so that we can still work with the |
| // VFS driver during development. This will not be used for actual running |
| // of Windows containers. Without this code, it would not be possible to |
| // docker pull using the VFS driver. |
| |
| // Store the layer. If layerData is not nil, unpack it into the new layer |
| if layerData != nil { |
| if err := graph.disassembleAndApplyTarLayer(img, layerData, root); err != nil { |
| return err |
| } |
| } |
| |
| if err := graph.saveSize(root, int(img.Size)); err != nil { |
| return err |
| } |
| |
| f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600)) |
| if err != nil { |
| return err |
| } |
| |
| defer f.Close() |
| |
| return json.NewEncoder(f).Encode(img) |
| } |
| } |
| |
| // TarLayer returns a tar archive of the image's filesystem layer. |
| func (graph *Graph) TarLayer(img *image.Image) (arch archive.Archive, err error) { |
| if wd, ok := graph.driver.(*windows.WindowsGraphDriver); ok { |
| var ids []string |
| if img.Parent != "" { |
| parentImg, err := graph.Get(img.Parent) |
| if err != nil { |
| return nil, err |
| } |
| |
| ids, err = graph.ParentLayerIds(parentImg) |
| if err != nil { |
| return nil, err |
| } |
| } |
| |
| return wd.Export(img.ID, wd.LayerIdsToPaths(ids)) |
| } else { |
| // We keep this functionality here so that we can still work with the VFS |
| // driver during development. VFS is not supported (and just will not work) |
| // for Windows containers. |
| rdr, err := graph.assembleTarLayer(img) |
| if err != nil { |
| logrus.Debugf("[graph] TarLayer with traditional differ: %s", img.ID) |
| return graph.driver.Diff(img.ID, img.Parent) |
| } |
| return rdr, nil |
| } |
| } |