github.com/olljanat/moby@v1.13.1/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  	"syscall"
    10  
    11  	"github.com/docker/docker/pkg/idtools"
    12  )
    13  
    14  // Setup populates a directory with mountpoints suitable
    15  // for bind-mounting things into the container.
    16  //
    17  // This extra layer is used by all containers as the top-most ro layer. It protects
    18  // the container from unwanted side-effects on the rw layer.
    19  func Setup(initLayer string, rootUID, rootGID int) error {
    20  	for pth, typ := range map[string]string{
    21  		"/dev/pts":         "dir",
    22  		"/dev/shm":         "dir",
    23  		"/proc":            "dir",
    24  		"/sys":             "dir",
    25  		"/.dockerenv":      "file",
    26  		"/etc/resolv.conf": "file",
    27  		"/etc/hosts":       "file",
    28  		"/etc/hostname":    "file",
    29  		"/dev/console":     "file",
    30  		"/etc/mtab":        "/proc/mounts",
    31  	} {
    32  		parts := strings.Split(pth, "/")
    33  		prev := "/"
    34  		for _, p := range parts[1:] {
    35  			prev = filepath.Join(prev, p)
    36  			syscall.Unlink(filepath.Join(initLayer, prev))
    37  		}
    38  
    39  		if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
    40  			if os.IsNotExist(err) {
    41  				if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, filepath.Dir(pth)), 0755, rootUID, rootGID); err != nil {
    42  					return err
    43  				}
    44  				switch typ {
    45  				case "dir":
    46  					if err := idtools.MkdirAllNewAs(filepath.Join(initLayer, pth), 0755, rootUID, rootGID); err != nil {
    47  						return err
    48  					}
    49  				case "file":
    50  					f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
    51  					if err != nil {
    52  						return err
    53  					}
    54  					f.Chown(rootUID, rootGID)
    55  					f.Close()
    56  				default:
    57  					if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
    58  						return err
    59  					}
    60  				}
    61  			} else {
    62  				return err
    63  			}
    64  		}
    65  	}
    66  
    67  	// Layer is ready to use, if it wasn't before.
    68  	return nil
    69  }