// +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, 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) } // 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)) } // 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 }