Skip to content
ThinStation edited this page Oct 21, 2024 · 31 revisions

Motivation

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.

What is a package?

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.

Dependencies

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.

Compiling

If you need to compile your application please refer to README.md and Ports and Packages.

Configuration - Optional

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.

Finalize - Optional

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.

Python - Optional

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.

Initialization - Optional

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

Startup

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"
    

Console (text mode) applications

If your application runs in text mode, then you should create an empty file in etc/console:

touch etc/console/mypackage

Libraries

go into lib.

Menu entries

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.

Icons

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.

Clone this wiki locally