github.com/sams1990/dockerrepo@v17.12.1-ce-rc2+incompatible/daemon/initlayer/setup_unix.go (about)

     1  // +build linux freebsd
     2  
     3  package initlayer
     4  
     5  import (
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/docker/docker/pkg/containerfs"
    11  	"github.com/docker/docker/pkg/idtools"
    12  	"golang.org/x/sys/unix"
    13  )
    14  
    15  // Setup populates a directory with mountpoints suitable
    16  // for bind-mounting things into the container.
    17  //
    18  // This extra layer is used by all containers as the top-most ro layer. It protects
    19  // the container from unwanted side-effects on the rw layer.
    20  func Setup(initLayerFs containerfs.ContainerFS, rootIDs idtools.IDPair) error {
    21  	// Since all paths are local to the container, we can just extract initLayerFs.Path()
    22  	initLayer := initLayerFs.Path()
    23  
    24  	for pth, typ := range map[string]string{
    25  		"/dev/pts":         "dir",
    26  		"/dev/shm":         "dir",
    27  		"/proc":            "dir",
    28  		"/sys":             "dir",
    29  		"/.dockerenv":      "file",
    30  		"/etc/resolv.conf": "file",
    31  		"/etc/hosts":       "file",
    32  		"/etc/hostname":    "file",
    33  		"/dev/console":     "file",
    34  		"/etc/mtab":        "/proc/mounts",
    35  	} {
    36  		parts := strings.Split(pth, "/")
    37  		prev := "/"
    38  		for _, p := range parts[1:] {
    39  			prev = filepath.Join(prev, p)
    40  			unix.Unlink(filepath.Join(initLayer, prev))
    41  		}
    42  
    43  		if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
    44  			if os.IsNotExist(err) {
    45  				if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootIDs); err != nil {
    46  					return err
    47  				}
    48  				switch typ {
    49  				case "dir":
    50  					if err := idtools.MkdirAllAndChownNew(filepath.Join(initLayer, pth), 0755, rootIDs); err != nil {
    51  						return err
    52  					}
    53  				case "file":
    54  					f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
    55  					if err != nil {
    56  						return err
    57  					}
    58  					f.Chown(rootIDs.UID, rootIDs.GID)
    59  					f.Close()
    60  				default:
    61  					if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
    62  						return err
    63  					}
    64  				}
    65  			} else {
    66  				return err
    67  			}
    68  		}
    69  	}
    70  
    71  	// Layer is ready to use, if it wasn't before.
    72  	return nil
    73  }