diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-01-15 10:57:10 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-01-15 13:07:06 +0900 |
| commit | 3e11ce6868182f1a3f74d5bf6c1db761097666fa (patch) | |
| tree | 85c611acc2aadb5b5b7818ad5a6a0769a6d71fa4 /helper/bwrap/builder.go | |
| parent | 562f5ed7971603a4e4e3315a7fe4188153bfc205 (diff) | |
helper/bwrap: separate sequential/static args
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'helper/bwrap/builder.go')
| -rw-r--r-- | helper/bwrap/builder.go | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/helper/bwrap/builder.go b/helper/bwrap/builder.go new file mode 100644 index 00000000..bd67da1c --- /dev/null +++ b/helper/bwrap/builder.go @@ -0,0 +1,170 @@ +package bwrap + +import "os" + +/* +Bind binds mount src on host to dest in sandbox. + +Bind(src, dest) bind mount host path readonly on sandbox +(--ro-bind SRC DEST). +Bind(src, dest, true) equal to ROBind but ignores non-existent host path +(--ro-bind-try SRC DEST). + +Bind(src, dest, false, true) bind mount host path on sandbox. +(--bind SRC DEST). +Bind(src, dest, true, true) equal to Bind but ignores non-existent host path +(--bind-try SRC DEST). + +Bind(src, dest, false, true, true) bind mount host path on sandbox, allowing device access +(--dev-bind SRC DEST). +Bind(src, dest, true, true, true) equal to DevBind but ignores non-existent host path +(--dev-bind-try SRC DEST). +*/ +func (c *Config) Bind(src, dest string, opts ...bool) *Config { + var ( + try bool + write bool + dev bool + ) + + if len(opts) > 0 { + try = opts[0] + } + if len(opts) > 1 { + write = opts[1] + } + if len(opts) > 2 { + dev = opts[2] + } + + if dev { + if try { + c.Filesystem = append(c.Filesystem, &pairF{DevBindTry.Unwrap(), src, dest}) + } else { + c.Filesystem = append(c.Filesystem, &pairF{DevBind.Unwrap(), src, dest}) + } + return c + } else if write { + if try { + c.Filesystem = append(c.Filesystem, &pairF{BindTry.Unwrap(), src, dest}) + } else { + c.Filesystem = append(c.Filesystem, &pairF{Bind.Unwrap(), src, dest}) + } + return c + } else { + if try { + c.Filesystem = append(c.Filesystem, &pairF{ROBindTry.Unwrap(), src, dest}) + } else { + c.Filesystem = append(c.Filesystem, &pairF{ROBind.Unwrap(), src, dest}) + } + return c + } +} + +// Dir create dir in sandbox +// (--dir DEST) +func (c *Config) Dir(dest string) *Config { + c.Filesystem = append(c.Filesystem, &stringF{Dir.Unwrap(), dest}) + return c +} + +// RemountRO remount path as readonly; does not recursively remount +// (--remount-ro DEST) +func (c *Config) RemountRO(dest string) *Config { + c.Filesystem = append(c.Filesystem, &stringF{RemountRO.Unwrap(), dest}) + return c +} + +// Procfs mount new procfs in sandbox +// (--proc DEST) +func (c *Config) Procfs(dest string) *Config { + c.Filesystem = append(c.Filesystem, &stringF{Procfs.Unwrap(), dest}) + return c +} + +// DevTmpfs mount new dev in sandbox +// (--dev DEST) +func (c *Config) DevTmpfs(dest string) *Config { + c.Filesystem = append(c.Filesystem, &stringF{DevTmpfs.Unwrap(), dest}) + return c +} + +// Mqueue mount new mqueue in sandbox +// (--mqueue DEST) +func (c *Config) Mqueue(dest string) *Config { + c.Filesystem = append(c.Filesystem, &stringF{Mqueue.Unwrap(), dest}) + return c +} + +// Tmpfs mount new tmpfs in sandbox +// (--tmpfs DEST) +func (c *Config) Tmpfs(dest string, size int, perm ...os.FileMode) *Config { + tmpfs := &PermConfig[*TmpfsConfig]{Inner: &TmpfsConfig{Dir: dest}} + if size >= 0 { + tmpfs.Inner.Size = size + } + if len(perm) == 1 { + tmpfs.Mode = &perm[0] + } + c.Filesystem = append(c.Filesystem, tmpfs) + return c +} + +// Overlay mount overlayfs on DEST, with writes going to an invisible tmpfs +// (--tmp-overlay DEST) +func (c *Config) Overlay(dest string, src ...string) *Config { + c.Filesystem = append(c.Filesystem, &OverlayConfig{Src: src, Dest: dest}) + return c +} + +// Join mount overlayfs read-only on DEST +// (--ro-overlay DEST) +func (c *Config) Join(dest string, src ...string) *Config { + c.Filesystem = append(c.Filesystem, &OverlayConfig{Src: src, Dest: dest, Persist: new([2]string)}) + return c +} + +// Persist mount overlayfs on DEST, with RWSRC as the host path for writes and +// WORKDIR an empty directory on the same filesystem as RWSRC +// (--overlay RWSRC WORKDIR DEST) +func (c *Config) Persist(dest, rwsrc, workdir string, src ...string) *Config { + if rwsrc == "" || workdir == "" { + panic("persist called without required paths") + } + c.Filesystem = append(c.Filesystem, &OverlayConfig{Src: src, Dest: dest, Persist: &[2]string{rwsrc, workdir}}) + return c +} + +// Symlink create symlink within sandbox +// (--symlink SRC DEST) +func (c *Config) Symlink(src, dest string, perm ...os.FileMode) *Config { + symlink := &PermConfig[SymlinkConfig]{Inner: SymlinkConfig{src, dest}} + if len(perm) == 1 { + symlink.Mode = &perm[0] + } + c.Filesystem = append(c.Filesystem, symlink) + return c +} + +// SetUID sets custom uid in the sandbox, requires new user namespace (--uid UID). +func (c *Config) SetUID(uid int) *Config { + if uid >= 0 { + c.UID = &uid + } + return c +} + +// SetGID sets custom gid in the sandbox, requires new user namespace (--gid GID). +func (c *Config) SetGID(gid int) *Config { + if gid >= 0 { + c.GID = &gid + } + return c +} + +// SetSync sets the sync pipe kept open while sandbox is running +// (--sync-fd FD) +func (c *Config) SetSync(s *os.File) *Config { + c.sync = s + return c +} |
