dynpk is a tool for bundling programs together from a local Linux system into an arrangement that allows them to be run on any other Linux system, regardless of distribution. For example, it can be used to run Fedora’s ipython on a RHEL 5 machine without having to perform any compilation from source. As well as being an alternative to static linking, it does more than static linking — bundling all the other files that libraries require to run as well (e.g. files in /etc).
Get the source like so:
git clone git://srobo.org/~rspanton/dynpk.git
Build the wrapper and audit library that dynpk needs to function:
% make gcc -fPIC -g -c -Wall audit.c -o audit.o gcc -shared -Wl,-soname,audit -o libaudit.so audit.o cc -g -o wrap -static -Wall -Wl,--gc-sections wrap.c
Use the example config file “conf.ini” as base for a new configuration file. This config file tells dynpk what packages and files to include in your bundle, as well as a few runtime-related things. Here’s a config file that’ll wrap bash and coreutils:
[dynpk] # RPMs to include in the bundle rpms: bash coreutils # Executables to include in the bundle files: # Holes to make in the filesystem to the host exclude_paths: /home /tmp /dev # Where the dynamic linker needs to look in the fake system library_dirs: /lib /usr/lib /usr/lib/mysql # Things that need to be in PATH in the fakechroot path: /usr/local/bin /usr/bin /bin /usr/local/sbin /usr/sbin /sbin # Whether to use libaudit use_audit: False
Invoke dynpk with it, like so:
./dynpk conf.ini bundle
dynpk will create a directory called “bundle”. Running the bash binary in this bundle will result in a shell that is inside the fakechroot:
[rob@zarniwoop dynpk(master)]$ ./bundle/bin/bash [FAKECHROOT@zarniwoop dynpk]$cd / [FAKECHROOT@zarniwoop /]$ls bin dynpk.config etc lib sbin usr wrap [FAKECHROOT@zarniwoop /]$
Here’s a summary of all of the current config file options:
- rpms A list of RPM package names from the current system to include in the bundle. dynpk doesn’t currently support working through the RPM dependency tree, so you have to list all the ones you want here.
- files A list of ELF files to include in the target bundle. These will be put in /bin within the bundle.
- exclude_paths Directories in the fakechroot that should punch through to the host system’s filesystem.
- library_dirs A list of directories to search for libraries in within the bundle.
- use_audit Whether to enable an auditing library that ensures that the dynamic linker only loads libraries from within the bundle, and not the host system. You should probably set this to False at the moment because there is some sort of issue with thread-local storage, glibc, and this.
How it works
dynpk encases programs in a fakechroot environment that contains everything they need to run, including the dynamic linker and all of their auxiliary files such as shared libraries and configuration files.
To make sure that programs don’t escape the fakechroot, it wraps them with a statically linked executable that invokes them with the right dynamic linker.
dynpk is not intended to be a tool to ensure that a program cannot escape its fakechroot. It is intended for situations in which one wants to run a program on a system on which you do not have control over what packages are installed.
Things that would be good for dynpk to support:
- deb support: I’m a Fedora user. Fedora uses RPMs. Some other people use deb-based systems, like Ubuntu. With not too much work, dynpk could support debs too.
- Dependency trees: I couldn’t find an easy way to get a list of all of the packages from the dependency tree of a given RPM. If someone knows of a good way to do this, please let me know (or write a patch…).
- /etc/ld.so.conf.d/* support At the moment dynpk hardcodes the dynamic linker’s search path. It should really look in /etc/ld.so.conf.d/* within the fakechroot for what it should run.
Site by Robert Spanton. © 2008 - 2011