// overlayRender renders the image that corresponds to the given hash using the // overlay filesystem. // It mounts an overlay filesystem from the cached tree of the image as rootfs. func overlayRender(cfg RunConfig, treeStoreID string, cdir string, dest string, appName string) error { destRootfs := path.Join(dest, "rootfs") if err := os.MkdirAll(destRootfs, defaultRegularDirPerm); err != nil { return err } cachedTreePath := cfg.Store.GetTreeStoreRootFS(treeStoreID) overlayDir := path.Join(cdir, "overlay") if err := os.MkdirAll(overlayDir, defaultRegularDirPerm); err != nil { return err } // Since the parent directory (rkt/pods/$STATE/$POD_UUID) has the 'S_ISGID' bit, here // we need to explicitly turn the bit off when creating this overlay // directory so that it won't inherit the bit. Otherwise the files // created by users within the pod will inherit the 'S_ISGID' bit // as well. if err := os.Chmod(overlayDir, defaultRegularDirPerm); err != nil { return err } imgDir := path.Join(overlayDir, treeStoreID) if err := os.MkdirAll(imgDir, defaultRegularDirPerm); err != nil { return err } // Also make 'rkt/pods/$STATE/$POD_UUID/overlay/$IMAGE_ID' to be readable by 'rkt' group // As 'rkt' status will read the 'rkt/pods/$STATE/$POD_UUID/overlay/$IMAGE_ID/upper/rkt/status/$APP' // to get exit status. if err := os.Chown(imgDir, -1, cfg.RktGid); err != nil { return err } upperDir := path.Join(imgDir, "upper", appName) if err := os.MkdirAll(upperDir, defaultRegularDirPerm); err != nil { return err } if err := label.SetFileLabel(upperDir, cfg.MountLabel); err != nil { return err } workDir := path.Join(imgDir, "work", appName) if err := os.MkdirAll(workDir, defaultRegularDirPerm); err != nil { return err } if err := label.SetFileLabel(workDir, cfg.MountLabel); err != nil { return err } opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", cachedTreePath, upperDir, workDir) opts = label.FormatMountLabel(opts, cfg.MountLabel) if err := syscall.Mount("overlay", destRootfs, "overlay", 0, opts); err != nil { return fmt.Errorf("error mounting: %v", err) } return nil }
// prepateOverlay sets up the needed directories, files and permissions for the // overlay-rendered pods func prepareOverlay(lower, treeStoreID, cdir, dest, appName, lbl string, gid int, fm os.FileMode) (*overlay.MountCfg, error) { fi, err := os.Stat(lower) if err != nil { return nil, err } imgMode := fi.Mode() dst := path.Join(dest, "rootfs") if err := os.MkdirAll(dst, imgMode); err != nil { return nil, err } overlayDir := path.Join(cdir, "overlay") if err := os.MkdirAll(overlayDir, fm); err != nil { return nil, err } // Since the parent directory (rkt/pods/$STATE/$POD_UUID) has the 'S_ISGID' bit, here // we need to explicitly turn the bit off when creating this overlay // directory so that it won't inherit the bit. Otherwise the files // created by users within the pod will inherit the 'S_ISGID' bit // as well. if err := os.Chmod(overlayDir, fm); err != nil { return nil, err } imgDir := path.Join(overlayDir, treeStoreID) if err := os.MkdirAll(imgDir, fm); err != nil { return nil, err } // Also make 'rkt/pods/$STATE/$POD_UUID/overlay/$IMAGE_ID' to be readable by 'rkt' group // As 'rkt' status will read the 'rkt/pods/$STATE/$POD_UUID/overlay/$IMAGE_ID/upper/rkt/status/$APP' // to get exgid if err := os.Chown(imgDir, -1, gid); err != nil { return nil, err } upper := path.Join(imgDir, "upper", appName) if err := os.MkdirAll(upper, imgMode); err != nil { return nil, err } if err := label.SetFileLabel(upper, lbl); err != nil { return nil, err } work := path.Join(imgDir, "work", appName) if err := os.MkdirAll(work, fm); err != nil { return nil, err } if err := label.SetFileLabel(work, lbl); err != nil { return nil, err } return &overlay.MountCfg{lower, upper, work, dst, lbl}, nil }
// overlayRender renders the image that corresponds to the given hash using the // overlay filesystem. // It writes the manifest in the specified directory and mounts an overlay // filesystem from the cached tree of the image as rootfs. func overlayRender(cfg RunConfig, img types.Hash, cdir string, dest string, appName string) error { if err := writeManifest(cfg.CommonConfig, img, dest); err != nil { return err } destRootfs := path.Join(dest, "rootfs") if err := os.MkdirAll(destRootfs, 0755); err != nil { return err } cachedTreePath := cfg.Store.GetTreeStoreRootFS(img.String()) overlayDir := path.Join(cdir, "overlay", img.String()) if err := os.MkdirAll(overlayDir, 0755); err != nil { return err } upperDir := path.Join(overlayDir, "upper", appName) if err := os.MkdirAll(upperDir, 0755); err != nil { return err } if err := label.SetFileLabel(upperDir, cfg.MountLabel); err != nil { return err } workDir := path.Join(overlayDir, "work", appName) if err := os.MkdirAll(workDir, 0755); err != nil { return err } if err := label.SetFileLabel(workDir, cfg.MountLabel); err != nil { return err } opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", cachedTreePath, upperDir, workDir) opts = label.FormatMountLabel(opts, cfg.MountLabel) if err := syscall.Mount("overlay", destRootfs, "overlay", 0, opts); err != nil { return fmt.Errorf("error mounting: %v", err) } return nil }