-
-
Notifications
You must be signed in to change notification settings - Fork 188
Packaging
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.
-
dependencies
file containing a list of other required packages Required -
.dna
file containing meta data relationships to Ports System Required -
build/conf
for ThinStation build configuration examples, -
build/finalize
to perform package specific shell commands that will be applied towards the end of build, -
build/pip3.freeze
to download and install python packages, -
bin
for all standard executables and symlinks, -
sbin
for secure executables and symlinks, -
etc
for your application’s global configuration, -
etc/cmd
for session or menu startup scripts, -
etc/init.d
for initialization scripts, -
etc/systemd/system
for a service file that starts the later, -
etc/systemd/system/multi-user.target.wants
for a symlink to the service file, -
lib
for library files, -
lib/menu
for menu entries, -
lib/icons/hicolor/scalable/apps
for 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 0
Your 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.global
This 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.