Writing a module (configuration)¶
Writing module is actually quite easy. Unlike YaST or Anaconda or similar projects, Teabox does not limits you in anything. A module is just a standalone executable in any kind of form, as long as it meets the following (POSIX standard) requirements:
Can at least output to the STDOUT
Returns a standard POSIX exit code
Optionally:
Output to STDERR
Receive STDIN
Module concept¶
A module in Teabox is essentially a wrapper around a command (or even a direct call of a program, if that is completely sufficient), but typically a wrapper. Choose wisely which language you want to use, but typically just a Shell script is almost always enough.
Each module has its own configuration file, called init.conf and its own directory,
which is inside of the module suite (see below).
Call cycle¶
During a call, a module has three phases, such as:
Gathering existing data, if any, and pre-loading the UI form with the corresponding values.
Displaying the UI form with the values.
The data from the UI form is then formed as a parameters to your command or a wrapper script, and the launch happens. Durinth this launch a “landing window” is displayed to either show just standard output, or progress bar, or any other form of progress.
Modules suite¶
Modules suite is just a directory with the initial configuration init.conf and Teabox
is pointed to it in its general configuration. All modules are simply directories inside.
It does not matter how the directories are organised, as long as there is a directory with
the init.conf file in it.
Modules can be optionally grouped by their topic, using their configuration. However, it does not matter in which directory a module is physically located, as long as it is within the entire suite directory.
It is still a very good idea to organise modules using directores, so they are not randomly placed, causing trouble finding them.
Module init.conf¶
Before anything, init.conf must define the UI, which will generate an input form with corresponding
widgets, those are used to construct a command line for the target call.
All the configuration of Teabox is using YAML syntax and is self-descriptive (most of the time) to understand. To begin with, define module common attributes, such as its name/title, an optional group name if a module should be grouped into a specific topic etc.
General settings¶
To define a title, just do it straight-forward:
# Title/name of the module
title: STOUT Log Landing Page
A group is optional. However, in a current implementation group has no ID, just a string directly.
This group should be the same across all the modules. If a string is different (other Unicode character etc),
then you will get two groups. In a future, group might have also group-id option:
# An optional group definition
group: Common Examples
Setup phase¶
Before module form is shown in the UI, setup command is called. Setup command is used to pre-load the UI
with the data, which is gathered at this phase. Form filling and any other communication with your module
and the Teabox is done throgh the API via Unix socket on the localhost. This socket is opened only during
the runtime and is closed and removed when the module call is over. The socket path is configured in the
main configuration, and how to communicate with it — is up to you. In a Shell script, for example, you can
use just socat or netcat programs, using Teabox API.
NOTE: Setup command is a full “as is” command, so any complete arguments are also allowed. Typically, setup is just another runtime mode of your module, so typically just
--setupparameter should be fully sufficient.
setup: example-module.sh --setup
Landing screen¶
Landing screen or report form is the screen that is shown right after user clicks “Start” button, and your module starts running. This landing screen can show a progress bar, display some progress messages or just show the STDOUT etc. There are currently two landing screens:
logger(default)progress
The logger screen only shows the STDOUT and has a status bar to inform user what is generally happening. The progress screen is a bit more advanced and has additional features, such as progress bar, current event message, a “todo list” of items that gets checked once they are completed and a general information text area that supports dynamic colors.
The logger is default and does not have to be explicitly defined in the configuration:
landing: logger
Conditions¶
There are conditions, under which your module runs or doesn’t. For example, sometimes you want to setup something, but you want to do it only once. The second call of the same setup would not be necessary, so you want to block it, informing user about it. Or you want to make sure that the requirements for your module are met.
This is done with the conditions directive, which is an infinite list of conditions. It is set the
following way:
conditions:
- clause
- target
- target
message: ....
- ...
- ...
Each condition has a preposition and an action what to do otherwise. For example:
conditions:
- absent:
- /var/run/apt.lock
message: "Package manager is currently running!"
- present:
- /etc/hosts
message: "Unable to find /etc/hosts"
File Checks
all-present, all-absent, present, absent.
All keys are self-explanatory: “all-*” means all files speficied needs to be either present or absent, otherwise, any of those. Example:
conditions:
- all-present:
- /etc/passwd
- /etc/shadow
- all-absent:
- /var/run/.lock
- /var/run/.stop
Permissions Checks
uid, gid
Check UID and/or GID if any of these matches current user. NOTE: on some OS they are strings.
So you can specify, e.g “root”, as integer - 0 but also as as string - "0":
conditions:
- uid:
- 0
message: You are not Groot! You should be much cooler than now. :-P
The UI and the arguments¶
Now to the cool stuff: the UI definition and arguments construction.
Apart from single forms that showes “Start” or “Cancel” buttons, Teabox also allows to use batches
in classic Windows “next/next/next/finish” style. This is done by the commands directive, which is
a list of commands. Think of an each command as a separate UI form. Currently teabox supports only
one form per a command (this might change in a future).
Each command is basically a set of directives:
commands:
- path: ...
title: ...
flags: ...
args: ...
- path: ...
title: ...
...
path¶
The path directive can be either absolute or none path to the command. For example, sometimes it is
maybe a good idea to call some specific command (very rare cases, usually unused):
path: /usr/bin/something
Or just call a wrapper from the current module (and this is the usual, typical use case):
path: my-wrapper.sh
title¶
This directive is a label of the menu item and then a title on the UI form. Type string.
flags¶
The directive flags is a list of strings. These are just flags to the executable in the command-line.
For example, if a command in path can accept a flag -q which makes it “quiet” to the STDOUT and you
want it so, then describe it this way:
- path: my-example.sh
flags:
- -q
Then the called command will be:
my-example.sh -q
Since this is a list, you may add more flags. Order of this directive will also affect how the command line is constructed. Some programs oddly is paying attention to the flags order, so you can directly control that behaviour as well.
Note: this is a list of static flags that always will be passed in. If you want control them in a form as toggle checkboxes, you have to use them as arguments (see below).
args¶
This is the arguments directive. Arguments usually have key/value form. If an argument has no value and it affects the program by mere presence (or absence) of the argument, then it is a “toggle” argument.
The directive args is just a list of arguments, while an argument is a structure, which describes
many aspects of an argument, such as:
type: widget type on the formname: The argument key, e.g.--archor--log-leveletc.label: The abel for the UI (stringtype)options: Possible options to choose (or values). This is a compex option, described below.attributes: a list of attributes of the field (explained below).
Example:
args:
- type: dropdown
name: --arch
label: Architecture
attributes:
- skip-empty
options:
- ["Intel 64bit", string, "x86_64"]
- ["ARM 64bit", string, "aarch_64"]
While type, name and label are just strings, the directive options has its own structure and rules.
This directive is a two-dimensional array, where each element has a strict structure, depending on the widget.
attributes
Attributes are just flags to the given argument and written just as a list of attributes key. Currently
implemented attributes:
Common attributes:
skip-emptyOmit empty named argument. Since teabox always adds a given option to a target script by default, this attribute allows to omit a named argument in the command line, if no value given.view-onlyTeabox will never send this field as an option or a named argument. It turns any field only for information purposes. For example, to show a table with existing repositories or users or user groups etc.
Attributes for tabular widget only:
selectorIf specified, tabular will show “selected row” column in front of others, displaying a bullet point for visual recognition of selected items.hidden = <INT>Indicates if a specified column is hidden. Example:hidden = 3.value = <INT>Indicates if a column is a value, so its content is used when the row is selected. Usually this is a composite column and it is usually hidden. Example:value = 3heightSets height of the entire field.multiselectTurns off toggle mode and allows to select multiple fields.search = [INT,]Adds a search mode, where appears extra widgets, allowing filter the content in all columns. However it is possible to limit search to a specified columns. Example:search = 1,2,5expand = <INT>Sets the specified column to be stretched, minimising all other columns to their minimum width.
Widgets¶
There are couple of widgets for the form that are implemented and will be displayed accordingly.
Dropdown¶
Same as list, but has a height of one character field on the form. Each option of the dropdown
widget has the following syntax:
[<LABEL>, <TYPE>, [VALUE]]
For example:
options:
- ["Global Optional", string, "/opt"]
- ["Local Optional", string, "/usr/local/opt"]
The form element is then accessed by the label, e.g. "Global Optional".
List¶
Same as dropdown, but has a height more than one character field on the form. Currently is
substituted as a dropdown.
Text¶
The widget text is just a text field entry, which may have a default value or preloaded one.
The options can contain only one element which has format of one mandatory element: content of the text.
For example, to display an entry text with the value “Borat Sagdiev”, one need to describe it this way:
options:
- ["Borat Sagdiev"]
Password, Masked¶
Password or masked text widget is completely identical to text widget,
except it is called as password or masked. Same as text, it would require options, which can be also completely empty:
options:
- []
Toggle (checkbox)¶
This widget is rendered as a checkbox and is called toggle. If it is checked, then the static flag
will appear in the final command line call. For example, to add a --debug flag to a general command,
one needs to construct the following way:
- type: toggle
name: --debug
Label: Debug mode
options:
- ["debug", bool, yes]
In this case, UI will contain a checkbox with the label “Debug mode”, checked by default. If module will
be launched together with this checkbox state, a command line will contain --debug flag in it.
Complete Example¶
This is a complete example of a “Hello world” module UI definition, which will ask for one parameter:
title: Hello World
# Delete "group" option to get this module standalone on top-level menu
group: Common Examples
setup: hello.sh --setup
landing: logger
commands:
- path: hello.sh
title: Print "Hello"
args:
- type: text
name: --name
label: "The name of the world"
options:
- ["Mordor"]
Here is your first module. It is in the goup of “Common Examples” alongside of all others.

However, if you will try to launch it, it will do exactly as “Loading Failure” example next to it:
Error: Failure while loading form from setup command.
Command: /opt/projects/teabox/example/modules/examples/helloworld/hello.sh
args: [--setup]
System exit: fork/exec /opt/projects/teabox/example/modules/examples/helloworld/hello.sh: no such file or directory
Of course. Because we also need to make our hello.sh executable. Go on, create for now an empty file
hello.sh in the same directory and make it executable:
#!/usr/bin/bash
Now we are getting our module working:

Right… “One does not simply walk into Mordor”, so we probably want to change that in the next chapter, looking at loading module concept.