56 lines
1.5 KiB
Nim
56 lines
1.5 KiB
Nim
|
import os
|
||
|
import json
|
||
|
import bwrap
|
||
|
import config
|
||
|
import options
|
||
|
|
||
|
const CONFIG_LOCATION = "config.json"
|
||
|
|
||
|
proc homePath(p: string): string =
|
||
|
joinPath(getHomeDir(), p)
|
||
|
|
||
|
proc checkRelativePath(p: string): string =
|
||
|
if p[0] == '/':
|
||
|
return p
|
||
|
homePath(p)
|
||
|
|
||
|
proc applyConfig(call: var BwrapCall, config: Config) =
|
||
|
for mount in config.mount.get(@[]):
|
||
|
call.addMount("--bind", checkRelativePath(mount))
|
||
|
|
||
|
for mount in config.romount.get(@[]):
|
||
|
call.addMount("--ro-bind", checkRelativePath(mount))
|
||
|
|
||
|
for symlink in config.symlinks.get(@[]):
|
||
|
call.addArg("--symlink", symlink.src, symlink.dst)
|
||
|
|
||
|
proc loadConfig(path: string): Config =
|
||
|
return readFile(path).parseJson().to(Config)
|
||
|
|
||
|
proc sandboxExec*(name: string, command: string) =
|
||
|
let sandboxPath = homePath(joinPath(".sandboxes", name))
|
||
|
let sandboxFiles = joinPath(sandboxPath, "files")
|
||
|
let sandboxInfo = joinPath(sandboxPath, "info")
|
||
|
|
||
|
createDir(sandboxFiles)
|
||
|
var call = BwrapCall()
|
||
|
|
||
|
call
|
||
|
.addArg("--bind", sandboxFiles, getHomeDir())
|
||
|
.addMount("--dev-bind", "/dev")
|
||
|
.addArg("--dir", "/tmp")
|
||
|
.addArg("--proc", "/proc")
|
||
|
.addArg("--unshare-all")
|
||
|
.addArg("--share-net")
|
||
|
.addArg("--die-with-parent")
|
||
|
.addArg("--hostname", name)
|
||
|
.addArg("--chdir", getHomeDir())
|
||
|
.applyConfig(loadConfig(CONFIG_LOCATION))
|
||
|
|
||
|
let configPath = sandboxPath.joinPath("config.json")
|
||
|
echo configPath
|
||
|
if fileExists(configPath):
|
||
|
call.applyConfig(loadConfig(configPath))
|
||
|
|
||
|
call.addArg(command).exec()
|