Packaging - Thinstation/thinstation GitHub Wiki
Let’s assume you want to include a new application or a set of special configuration files into ThinStation. For this purpose it is better to create a new package than patching an existing one (already included in ThinStation).
Your newly created package – let’s call it mypackage – can be used like an existing one: Simply insert
package mypackage
into build.conf.
For the impatient: There is a package called template serving as a template for creating your own packages.
Technically speaking, a package is a subdirectory of /build/packages containing a set of files and directories.
-
dependenciesfile containing a list of other required packages Required -
.dnafile containing meta data relationships to Ports System Required -
build/conffor ThinStation build configuration examples, -
build/finalizeto perform package specific shell commands that will be applied towards the end of build, -
build/pip3.freezeto download and install python packages, -
binfor all standard executables and symlinks, -
sbinfor secure executables and symlinks, -
etcfor your application’s global configuration, -
etc/cmdfor session or menu startup scripts, -
etc/init.dfor initialization scripts, -
etc/systemd/systemfor a service file that starts the later, -
etc/systemd/system/multi-user.target.wantsfor a symlink to the service file, -
libfor library files, -
lib/menufor menu entries, -
lib/icons/hicolor/scalable/appsfor scalable svg icons.
To see where to put your new files read on.
In the root of your package directory /build/packages/<mypackage>, should be a file called dependencies. This file should always exist even if empty, but I'm sure you will at least depend on base. You should also define any other packages you depend on, one per line.
If you need to compile your application please refer to README.md and Ports and Packages.
If you need to add new configuration variables for your package, please add a file build/conf/99mypackage. Define the variables in it and comment them verbosely.
This file will be part of the thinstation.conf.sample file. Replace 99 with a lower number if you want your variables to appear earlier in thinstation.conf.sample.
If you need specific shell commands to run during the build process as opposed to during boot, you can add a finalize file build/finalize with a header like ##mypackage 78 and then add shell commands to make specific changes to the filesystem during build. The number at the end is a metric that tries to order the finalize scripts.
We don't include any package managers in the final build image, that includes pip. However, during build we can call pip within build and feed it a freeze file build/pip3.freeze and it will install those packages into the image. The format is the same as the output of pip freeze would produce. You can remove the version numbers if you want pip to always grab the latest version, or leave them in to make sure a specific version is installed.
This can generate configuration files for a service or application based on variables in the conf files. To initialize your package (e.g. a service) at boot time you have to put a shell script in etc/init.d that is named exactly as your package plus a .init suffix, for our example we use mypackage.init. You can use any variables defined in thinstation.conf.* files in this script.
Example:
#! /bin/sh
. `dirname $0`/common
case "$1" in
init)
# run during boot (if started by systemd)
if ! pkg_initialized $PACKAGE; then
# Your startup instructions go here
pkg_set_init_flag $PACKAGE
fi
;;
console)
;;
window)
;;
fullscreen)
;;
help)
echo "Usage: $0 init"
;;
*)
exit 1
;;
esac
exit 0Your script needs to be started with a systemd unit file placed in etc/systemd/system
Example: mypackage.service
[Unit]
Description=ThinStation mypackage
After=profile-setup.service pkg.service
Before=display-manager.service
ConditionPathIsReadWrite=/etc
[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/thinstation.env
ExecStart=/etc/init.d/mypackage.init init
SyslogIdentifier=mypackage
[Install]
WantedBy=multi-user.target
Finally, create a symlink to the service file in etc/systemd/system/multi-user.target.wants/ like
ln -sf ../mypackage.service etc/systemd/system/multi-user.target.wants/mypackage.service
If you don’t need to do any special initialization for your application, and you plan to launch your application as a session or a menu entry, just create a symlink to /etc/thinstation.packages (for GUI applications) or /etc/thinstation.console (for textmode applications) like this:
cd mypackage/etc/init.d
ln -s /etc/thinstation.packages mypackage # or alternatively
ln -s /etc/thinstation.console mypackage
If you use a symlink for initialization (see previous section) then it is necessary to define the exact command for starting your application. This is done in form of shell variable definitions. There can be several files in etc/cmd:
-
mypackage.globalThis is the default file if no others are supplied and is always required.CMD_GLOBAL="application" -
mypackage.console(Optional) Define how to start your application from the console. -
mypackage.fullscreen(Optional) Define how to start your application fullscreen.CMD_FULLSCREEN="application --FULLSCREEN" -
mypackage.window(Optional) Define how to start your application in an ordinary window.CMD_WINDOW="application"
If your application runs in text mode, then you should create an empty file in etc/console:
touch etc/console/mypackage
go into lib.
for Openbox, IceWM and XFWM menu entries can be defined in the file lib/menu/mypackage like this:
package="mypackage"; needs="x11"; title="Example application"; command="pkg window mypackage"
package="mypackage"; needs="x11"; title="Example application (fullscreen)"; command="pkg fullscreen mypackage"
That will go through the various thinstation functions and run commands that you have defined in /etc/cmd/mypackage.* files.
For simple menu entries, you can just call the command directly without pkg window or pkg fullscreen but they must be valid executables in the path.
If you have an icon that you want displayed in menus, it should be an svg file, and placed at mypackage/lib/icons/hicolor/scalable/apps/mypackage.svg.
You can then run icon-gen mypackage, and any pixmaps should get placed as well.