Sandbox.jl Documentation
Sandbox.jl provides basic containerization tools for running Linux guests on a variety of platforms.
Index
Sandbox.BinFmtRegistrationSandbox.BinFmtRegistrationSandbox.SandboxConfigSandbox.SandboxExecutorSandbox.build_docker_imageSandbox.check_binfmt_misc_loadedSandbox.default_persist_root_dirsSandbox.export_docker_imageSandbox.get_kernel_versionSandbox.get_loaded_modulesSandbox.getgidSandbox.getuidSandbox.is_ecryptfsSandbox.load_env_prefSandbox.max_directory_ctimeSandbox.pull_docker_imageSandbox.read_binfmt_misc_registrationsSandbox.realpath_stemSandbox.register_requested_formats!Sandbox.register_stringSandbox.unameSandbox.with_executorSandbox.write_binfmt_misc_registration!
Types
Sandbox.BinFmtRegistration — TypeBinFmtRegistrationProvides a structured view of a binfmt_misc interpreter registration. Note that only "magic" matching rules are allowed, we do not support "extension" matching rules.
Sandbox.BinFmtRegistration — MethodBinFmtRegistration(file::String)Reads a binfmt_misc registration in from disk, if it cannot be parsed (because it is malformed, or uses unsupported features) it an ArgumentError will be thrown.
Sandbox.SandboxConfig — TypeSandboxConfig(read_only_maps, read_write_maps, env)Sandbox executors require a configuration to set up the environment properly.
read_only_maps: Directories that are mapped into the sandbox as read-only mappings.- Specified as pairs, e.g.
sandbox_path => host_path. All paths must be absolute. - Must always include a mapping for root, e.g.
"/" => rootfs_path.
- Specified as pairs, e.g.
read_write_maps: Directories that are mapped into the sandbox as read-write mappings.- Specified as pairs, e.g.
sandbox_path => host_path. All paths must be absolute. - Note that some executors may not show perfect live updates; consistency is guaranteed only after execution is finished.
- Specified as pairs, e.g.
env: Dictionary mapping of environment variables that should be set within the sandbox.entrypoint: Executable that gets passed the actual command being run.- This is a path within the sandbox, and must be absolute.
- Defaults to
nothing, which causes the command to be executed directly.
pwd: Set the working directory of the command that will be run.- This is a path within the sandbox, and must be absolute.
persist: Tell the executor object to persist changes made to the rootfs.- This is a boolean value, it is up to interpretation by the executor.
- Persistence is a property of an individual executor and changes live only as long as the executor object itself.
- You cannot transfer persistent changes from one executor to another.
multiarch: Request multiarch executable support- This is an array of
Platformobjects - Sandbox will ensure that interpreters (such as
qemu-*-staticbinaries) are available for each platform. - Requesting multiarch support for a platform that we don't support results in an
ArgumentError.
- This is an array of
uidandgid: Numeric user and group identifiers to spawn the sandboxed process as.- By default, these are both
0, signifyingrootinside the sandbox.
- By default, these are both
stdin,stdout,stderr: input/output streams for the sandboxed process.- Can be any kind of
IO,TTY,devnull, etc...
- Can be any kind of
hostname: Set the hostname within the sandbox, defaults to the current hostnameverbose: Set whether the sandbox construction process should be more or less verbose.
Sandbox.SandboxExecutor — TypeSandboxExecutorThis represents the base type for all execution backends within this package. Valid concrete subtypes must implement at least the following methods:
T(): no-argument constructor to ready an execution engine with all defaults.executor_available(::DataType{T}): Checks whether executor typeTis available on this system. For example,UserNamespacesExecutors are only available on Linux, and even then only on certain kernels. Availablility checks may run a program to determine whether that executor is actually available.build_executor_command(exe::T, config::SandboxConfig, cmd::Cmd): Builds theCmdobject that, when run, executes the user's desired command within the given sandbox. Theconfigobject contains all necessary metadata such as shard mappings, environment variables,stdin/stdout/stderrredirection, etc...cleanup(exe::T): Cleans up any persistent data storage that this executor may have built up over the course of its execution.
Note that while you can manually construct and cleanup an executor, it is recommended that users instead make use of the with_executor() convenience function:
with_executor(UnprivilegedUserNamespacesExecutor) do exe
run(exe, config, ...)
endFunctions
Sandbox.build_docker_image — Methodbuild_docker_image(root_path::String)Docker doesn't like volume mounts within volume mounts, like we do with sandbox. So we do things "the docker way", where we construct a rootfs docker image, then mount things on top of that, with no recursive mounting. We cut down on unnecessary work somewhat by quick-scanning the directory for changes and only rebuilding if changes are detected.
Sandbox.check_binfmt_misc_loaded — Methodcheck_binfmt_misc_loaded()Check that the binfmt_misc kernel module is loaded and enabled.
Sandbox.default_persist_root_dirs — Methoddefault_persist_root_dirs()Returns the default list of directories that should be attempted to be used as persistence storage. Influenced by the SANDBOX_PERSISTENCE_DIR environment variable, as well as the persist_dir preference. The last place searched by default is the persist_dirs scratch space.
Sandbox.export_docker_image — Functionexport_docker_image(image::String,
output_dir::String = <default scratch location>;
verbose::Bool = false,
force::Bool = false)Exports the given docker image name to the requested output directory. Useful for pulling down a known good rootfs image from Docker Hub, for future use by Sandbox executors. If force is set to true, will overwrite a pre-existing directory, otherwise will silently return.
Sandbox.get_kernel_version — Methodget_kernel_version(;verbose::Bool = false)Use uname() to get the kernel version and parse it out as a VersionNumber, returning nothing if parsing fails or this is not Linux.
Sandbox.get_loaded_modules — Methodget_loaded_modules()Returns a list of modules currently loaded by the system. On non-Linux platforms, returns an empty list.
Sandbox.getgid — Methodgetgid()Wrapper around libc's getgid() function
Sandbox.getuid — Methodgetuid()Wrapper around libc's getuid() function
Sandbox.is_ecryptfs — Methodis_ecryptfs(path::AbstractString; verbose::Bool=false)Checks to see if the given path (or any parent directory) is placed upon an ecryptfs mount. This is known not to work on current kernels, see this bug for more details: https://bugzilla.kernel.org/show_bug.cgi?id=197603
This method returns whether it is encrypted or not, and what mountpoint it used to make that decision.
Sandbox.load_env_pref — Methodload_env_pref(env_var, prefs_name, default)Many pieces of Sandbox.jl functionality can be controlled either through environment variables or preferences. This utility function makes it easy to check first the environment, then preferences, finally falling back to the default. Additionally, it memoizes the result in a caching dictionary.
Sandbox.max_directory_ctime — Methodmax_directory_ctime(prefix::String)Takes the stat() of all files in a directory root, keeping the maximum ctime, recursively. Comparing just this value allows for quick directory change detection.
Sandbox.pull_docker_image — Functionpull_docker_image(image::String,
output_dir::String = <default scratch location>;
platform::String = "",
verbose::Bool = false,
force::Bool = false)Pulls and saves the given docker image name to the requested output directory. Useful for pulling down a known good rootfs image from Docker Hub, for future use by Sandbox executors. If force is set to true, will overwrite a pre-existing directory, otherwise will silently return. Optionally specify the platform of the image with platform.
Sandbox.read_binfmt_misc_registrations — Methodread_binfmt_misc_registrations()Return a list of BinFmtRegistration objects, one per readable registration, as found sitting in /proc/sys/fs/binfmt_misc/*. Registrations that cannot be parsed are silently ignored.
Sandbox.realpath_stem — Methodrealpath_stem(path::AbstractString)Given a path, return the realpath of it. If it does not exist, try to resolve the realpath of its containing directory, then append the tail portion onto the end of that resolved stem. This iterates until we find a stem that can be resolved.
This allows for resolving directory symlinks halfway through a path, while not requiring that the final path leaf exist at the time of calling realpath_stem(). Of course, if the final path leaf is itself a symlink, this will not work correctly, so this should be considered a "best effort" function.
Internally, we use this to attempt to discover the actual mountpoint a mapping is or will be stored on.
Sandbox.register_requested_formats! — Methodregister_requested_formats(formats::Vector{BinFmtRegistration})Given the list of binfmt_misc formats, check the currently-registered formats through read_binfmt_misc_registrations(), check to see if any in formats are not yet registered, and if they are not, call write_binfmt_misc_registration!() to register it with an artifact-sourced qemu-*-static binary.
Sandbox.register_string — Methodregister_string(reg::BinFmtRegistration)Constructs the string used to register a binfmt_misc registration with the register file endpoint within /proc/sys/fs/binfmt_misc/register. To actually register the interpreter, use write_binfmt_misc_registration().
Sandbox.uname — Methoduname()On Linux systems, return the strings returned by the uname() function in libc.
Sandbox.with_executor — Methodwith_executor(f::Function, ::Type{<:SandboxExecutor} = preferred_executor(); kwargs...)Sandbox.write_binfmt_misc_registration! — Methodwrite_binfmt_misc_registration(reg::BinFmtRegistration)Write a binfmt_misc registration out to the kernel's register file endpoint. Requires sudo privileges.