github.com/crquan/docker@v1.8.1/graph/graph_windows.go (about)

     1  // +build windows
     2  
     3  package graph
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"os"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/docker/docker/daemon/graphdriver/windows"
    12  	"github.com/docker/docker/image"
    13  	"github.com/docker/docker/pkg/archive"
    14  )
    15  
    16  // setupInitLayer populates a directory with mountpoints suitable
    17  // for bind-mounting dockerinit into the container. T
    18  func SetupInitLayer(initLayer string) error {
    19  	return nil
    20  }
    21  
    22  func createRootFilesystemInDriver(graph *Graph, img *image.Image, layerData archive.ArchiveReader) error {
    23  	if wd, ok := graph.driver.(*windows.WindowsGraphDriver); ok {
    24  		if img.Container != "" && layerData == nil {
    25  			logrus.Debugf("Copying from container %s.", img.Container)
    26  
    27  			var ids []string
    28  			if img.Parent != "" {
    29  				parentImg, err := graph.Get(img.Parent)
    30  				if err != nil {
    31  					return err
    32  				}
    33  
    34  				ids, err = graph.ParentLayerIds(parentImg)
    35  				if err != nil {
    36  					return err
    37  				}
    38  			}
    39  
    40  			if err := wd.CopyDiff(img.Container, img.ID, wd.LayerIdsToPaths(ids)); err != nil {
    41  				return fmt.Errorf("Driver %s failed to copy image rootfs %s: %s", graph.driver, img.Container, err)
    42  			}
    43  		} else if img.Parent == "" {
    44  			if err := graph.driver.Create(img.ID, img.Parent); err != nil {
    45  				return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err)
    46  			}
    47  		}
    48  	} else {
    49  		// This fallback allows the use of VFS during daemon development.
    50  		if err := graph.driver.Create(img.ID, img.Parent); err != nil {
    51  			return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err)
    52  		}
    53  	}
    54  	return nil
    55  }
    56  
    57  func (graph *Graph) restoreBaseImages() ([]string, error) {
    58  	// TODO Windows. This needs implementing (@swernli)
    59  	return nil, nil
    60  }
    61  
    62  // ParentLayerIds returns a list of all parent image IDs for the given image.
    63  func (graph *Graph) ParentLayerIds(img *image.Image) (ids []string, err error) {
    64  	for i := img; i != nil && err == nil; i, err = graph.GetParent(i) {
    65  		ids = append(ids, i.ID)
    66  	}
    67  
    68  	return
    69  }
    70  
    71  // storeImage stores file system layer data for the given image to the
    72  // graph's storage driver. Image metadata is stored in a file
    73  // at the specified root directory.
    74  func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) {
    75  
    76  	if wd, ok := graph.driver.(*windows.WindowsGraphDriver); ok {
    77  		// Store the layer. If layerData is not nil and this isn't a base image,
    78  		// unpack it into the new layer
    79  		if layerData != nil && img.Parent != "" {
    80  			var ids []string
    81  			if img.Parent != "" {
    82  				parentImg, err := graph.Get(img.Parent)
    83  				if err != nil {
    84  					return err
    85  				}
    86  
    87  				ids, err = graph.ParentLayerIds(parentImg)
    88  				if err != nil {
    89  					return err
    90  				}
    91  			}
    92  
    93  			if img.Size, err = wd.Import(img.ID, layerData, wd.LayerIdsToPaths(ids)); err != nil {
    94  				return err
    95  			}
    96  		}
    97  
    98  		if err := graph.saveSize(root, int(img.Size)); err != nil {
    99  			return err
   100  		}
   101  
   102  		f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
   103  		if err != nil {
   104  			return err
   105  		}
   106  
   107  		defer f.Close()
   108  
   109  		return json.NewEncoder(f).Encode(img)
   110  	} else {
   111  		// We keep this functionality here so that we can still work with the
   112  		// VFS driver during development. This will not be used for actual running
   113  		// of Windows containers. Without this code, it would not be possible to
   114  		// docker pull using the VFS driver.
   115  
   116  		// Store the layer. If layerData is not nil, unpack it into the new layer
   117  		if layerData != nil {
   118  			if err := graph.disassembleAndApplyTarLayer(img, layerData, root); err != nil {
   119  				return err
   120  			}
   121  		}
   122  
   123  		if err := graph.saveSize(root, int(img.Size)); err != nil {
   124  			return err
   125  		}
   126  
   127  		f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
   128  		if err != nil {
   129  			return err
   130  		}
   131  
   132  		defer f.Close()
   133  
   134  		return json.NewEncoder(f).Encode(img)
   135  	}
   136  }
   137  
   138  // TarLayer returns a tar archive of the image's filesystem layer.
   139  func (graph *Graph) TarLayer(img *image.Image) (arch archive.Archive, err error) {
   140  	if wd, ok := graph.driver.(*windows.WindowsGraphDriver); ok {
   141  		var ids []string
   142  		if img.Parent != "" {
   143  			parentImg, err := graph.Get(img.Parent)
   144  			if err != nil {
   145  				return nil, err
   146  			}
   147  
   148  			ids, err = graph.ParentLayerIds(parentImg)
   149  			if err != nil {
   150  				return nil, err
   151  			}
   152  		}
   153  
   154  		return wd.Export(img.ID, wd.LayerIdsToPaths(ids))
   155  	} else {
   156  		// We keep this functionality here so that we can still work with the VFS
   157  		// driver during development. VFS is not supported (and just will not work)
   158  		// for Windows containers.
   159  		rdr, err := graph.assembleTarLayer(img)
   160  		if err != nil {
   161  			logrus.Debugf("[graph] TarLayer with traditional differ: %s", img.ID)
   162  			return graph.driver.Diff(img.ID, img.Parent)
   163  		}
   164  		return rdr, nil
   165  	}
   166  }