github.com/rentongzhang/docker@v1.8.2-rc1/graph/graph_unix.go (about)

     1  // +build !windows
     2  
     3  package graph
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"syscall"
    12  
    13  	"github.com/Sirupsen/logrus"
    14  	"github.com/docker/docker/image"
    15  	"github.com/docker/docker/pkg/archive"
    16  	"github.com/docker/docker/pkg/system"
    17  )
    18  
    19  // setupInitLayer populates a directory with mountpoints suitable
    20  // for bind-mounting dockerinit into the container. The mountpoint is simply an
    21  // empty file at /.dockerinit
    22  //
    23  // This extra layer is used by all containers as the top-most ro layer. It protects
    24  // the container from unwanted side-effects on the rw layer.
    25  func SetupInitLayer(initLayer string) error {
    26  	for pth, typ := range map[string]string{
    27  		"/dev/pts":         "dir",
    28  		"/dev/shm":         "dir",
    29  		"/proc":            "dir",
    30  		"/sys":             "dir",
    31  		"/.dockerinit":     "file",
    32  		"/.dockerenv":      "file",
    33  		"/etc/resolv.conf": "file",
    34  		"/etc/hosts":       "file",
    35  		"/etc/hostname":    "file",
    36  		"/dev/console":     "file",
    37  		"/etc/mtab":        "/proc/mounts",
    38  	} {
    39  		parts := strings.Split(pth, "/")
    40  		prev := "/"
    41  		for _, p := range parts[1:] {
    42  			prev = filepath.Join(prev, p)
    43  			syscall.Unlink(filepath.Join(initLayer, prev))
    44  		}
    45  
    46  		if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
    47  			if os.IsNotExist(err) {
    48  				if err := system.MkdirAll(filepath.Join(initLayer, filepath.Dir(pth)), 0755); err != nil {
    49  					return err
    50  				}
    51  				switch typ {
    52  				case "dir":
    53  					if err := system.MkdirAll(filepath.Join(initLayer, pth), 0755); err != nil {
    54  						return err
    55  					}
    56  				case "file":
    57  					f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
    58  					if err != nil {
    59  						return err
    60  					}
    61  					f.Close()
    62  				default:
    63  					if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
    64  						return err
    65  					}
    66  				}
    67  			} else {
    68  				return err
    69  			}
    70  		}
    71  	}
    72  
    73  	// Layer is ready to use, if it wasn't before.
    74  	return nil
    75  }
    76  
    77  func createRootFilesystemInDriver(graph *Graph, img *image.Image, layerData archive.ArchiveReader) error {
    78  	if err := graph.driver.Create(img.ID, img.Parent); err != nil {
    79  		return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err)
    80  	}
    81  	return nil
    82  }
    83  
    84  func (graph *Graph) restoreBaseImages() ([]string, error) {
    85  	return nil, nil
    86  }
    87  
    88  // storeImage stores file system layer data for the given image to the
    89  // graph's storage driver. Image metadata is stored in a file
    90  // at the specified root directory.
    91  func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) {
    92  	// Store the layer. If layerData is not nil, unpack it into the new layer
    93  	if layerData != nil {
    94  		if err := graph.disassembleAndApplyTarLayer(img, layerData, root); err != nil {
    95  			return err
    96  		}
    97  	}
    98  
    99  	if err := graph.saveSize(root, int(img.Size)); err != nil {
   100  		return err
   101  	}
   102  
   103  	f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	defer f.Close()
   109  
   110  	return json.NewEncoder(f).Encode(img)
   111  }
   112  
   113  // TarLayer returns a tar archive of the image's filesystem layer.
   114  func (graph *Graph) TarLayer(img *image.Image) (arch archive.Archive, err error) {
   115  	rdr, err := graph.assembleTarLayer(img)
   116  	if err != nil {
   117  		logrus.Debugf("[graph] TarLayer with traditional differ: %s", img.ID)
   118  		return graph.driver.Diff(img.ID, img.Parent)
   119  	}
   120  	return rdr, nil
   121  }