github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/daemon/initlayer/setup_unix.go (about)

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