This tool is used to place a package into a system image without the need to use sudo
.
It is used to create a disk image with a package installed.
This way the target system can be used with new packages without the need to generate a whole image and know yocto.
It takes a package (archive) and a system image (disk image) as input and creates a new disk image with the package. If the package contains any service files, they can be activated.
For working with the image, the tool uses libguestfs
to mount the image's filesystems. This way, the tool can work with the image without root permissions.
The tool supports interactive mode, which allows the user to select the package, target partition, and the service files to activate. Then it can generate a config file for the tool to use in non-interactive mode.
- golang >= 1.23
- libguestfs
- See [libguest installation] section for install instructions.
- ssty
go get package-to-image-placer
go build
For interactive mode, run:
./package-to-image-placer -source <source_image_path> -target <target_image_path> [ -package-dir <package_dir> ... ]
For non-interactive mode, run:
./package-to-image-placer -config <config_file_path> [ <overrides> ]
-source
- Path to the source image.-target
- Path to the target image. The path will be created.- If used with no-clone option this file must exist and will be changed.
-config
- Path to the config file. Sets Non-interactive mode.-no-clone
- Do not clone the source image. The target image must exist.-overwrite
- Overwrite the target image if it exists.-package-dir
- Initial directory for the package selection. Interactive mode only.-target-dir
- Override target directory on the image from config. Non-interactive mode only.-h
- Show usage.
Command line arguments are overriding the config file values.
To run all tests, run:
go test ./...
The config can be generated in interactive run. The config file is used to set the package, target partition, and service files to activate.
Default config file is in default-config.json.
Config structure is as follows:
{
"source": "<source-image-path>",
"target": "<target-image-path>",
"packages": [
"<package-path.zip>"
],
"partition-numbers": [
<partition-number>
],
"service_files": [
"<service-file-name-with-suffix>"
],
"target-directory": "<target-directory-on-image>",
"no-clone": <bool>,
"overwrite": <bool>
}
The tool can activate service files in the image.
The service files are activated by copying them to /etc/system/systemd/
and creating symlink to the file in /etc/systemd/system/multi-user.target.wants/
.
The paths in the image are updated based on WorkingDirectory
field, where the original WorkingDirectory is replaced with the new path in the target image.
The service file must:
- be in the package.
- contain the following fields:
ExecStart
User
RestartSec
WorkingDirectory
Type=simple
WantedBy=multi-user.target
Libquestfs is a library for modifying disk images. It is used to mount the disk image without root permissions.
sudo apt-get install libguestfs-tools
# Add user kernel, which can be accessed without sudo. Other option is to give permissions to the existing kernel.
apt-get download linux-image-$(uname -r)
dpkg-deb -x linux-image-$(uname -r)*.deb ./
export SUPERMIN_KERNEL=./boot/vmlinuz-image-$(uname -r)
install libguestfs-tools
will install the tools, but it needs read access to the kernel (e.g. /boot/vmlinuz-*
) image.
You can either create a new kernel image, that supermin
will use (as shown above), or give read access to the existing one.
To test functionality or to find the used kernel image, run:
libguestfs-test-tool
sudo dnf install libguestfs-tools
If you have error that look like this:
libguestfs: error: could not create appliance through libvirt.
Original error from libvirt: internal error:
process exited while connecting to monitor: 2025-03-03T14:51:53.981133Z qemu-kvm: -device {"driver":"scsi-hd","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":0,"device_id":"drive-scsi0-0-0-0","drive":"libvirt-2-storage","id":"scsi0-0-0-0","bootindex":1,"write-cache":"on"}: Failed to get "write" lock
Is another process using the image?
Make sure you have kvm
enabled.