Support read-only root filesystems
The only place I could find where libcontainer tries to write to the container's root FS is when setting up the pivot dir, to be used on pivot_root(2). This makes the pivot base dir configurable, so a read-only FS can be used as root FS of containers. Users can then specify a writeable subpath to be used as pivot inside the container. Signed-off-by: Fabio Kung <fabio@heroku.com> (github: fabiokung)
This commit is contained in:
parent
1d3b2589d7
commit
2a452c17aa
|
@ -79,7 +79,7 @@ func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountCon
|
|||
if mountConfig.NoPivotRoot {
|
||||
err = MsMoveRoot(rootfs)
|
||||
} else {
|
||||
err = PivotRoot(rootfs)
|
||||
err = PivotRoot(rootfs, mountConfig.PivotDir)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -13,6 +13,11 @@ type MountConfig struct {
|
|||
// This is a common option when the container is running in ramdisk
|
||||
NoPivotRoot bool `json:"no_pivot_root,omitempty"`
|
||||
|
||||
// PivotDir allows a custom directory inside the container's root filesystem to be used as pivot, when NoPivotRoot is not set.
|
||||
// When a custom PivotDir not set, a temporary dir inside the root filesystem will be used. The pivot dir needs to be writeable.
|
||||
// This is required when using read only root filesystems. In these cases, a read/writeable path can be (bind) mounted somewhere inside the root filesystem to act as pivot.
|
||||
PivotDir string `json:"pivot_dir,omitempty"`
|
||||
|
||||
// ReadonlyFs will remount the container's rootfs as readonly where only externally mounted
|
||||
// bind mounts are writtable
|
||||
ReadonlyFs bool `json:"readonly_fs,omitempty"`
|
||||
|
|
|
@ -10,8 +10,15 @@ import (
|
|||
"syscall"
|
||||
)
|
||||
|
||||
func PivotRoot(rootfs string) error {
|
||||
pivotDir, err := ioutil.TempDir(rootfs, ".pivot_root")
|
||||
func PivotRoot(rootfs, pivotBaseDir string) error {
|
||||
if pivotBaseDir == "" {
|
||||
pivotBaseDir = "/"
|
||||
}
|
||||
tmpDir := filepath.Join(rootfs, pivotBaseDir)
|
||||
if err := os.MkdirAll(tmpDir, 0755); err != nil {
|
||||
return fmt.Errorf("can't create tmp dir %s, error %v", tmpDir, err)
|
||||
}
|
||||
pivotDir, err := ioutil.TempDir(tmpDir, ".pivot_root")
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err)
|
||||
}
|
||||
|
@ -25,7 +32,7 @@ func PivotRoot(rootfs string) error {
|
|||
}
|
||||
|
||||
// path to pivot dir now changed, update
|
||||
pivotDir = filepath.Join("/", filepath.Base(pivotDir))
|
||||
pivotDir = filepath.Join(pivotBaseDir, filepath.Base(pivotDir))
|
||||
if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
|
||||
return fmt.Errorf("unmount pivot_root dir %s", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue