From Univention Wiki
Apps may be configured from within the App Center. A file describing App Settings may ship with the App, rendering a form for the user.
There are a variety of possible Settings that can be defined. The file is in the ini file format. Easy example:
[myapp/mysetting] Type = String Description = A string type Description[de] = Eine Zeichenkette InitialValue = The "default" value of this setting; optional
This will render a form:
After applying this form, the variable "myapp/mysetting" will be saved inside the container of the Docker App. The App can then react on this change.
Where are the Settings stored?
For Docker Apps, they are stored inside the container in the Univention Config Registry (UCR). If you use a Docker App based on UCS with debian packages, you can easily access this variable using UCR as a CLI tool or by importing the python library. As UCS is the basis, you also get UCR templates, etc., for free.
For Docker Apps that are based on their own image, a "UCR like interface" is used, meaning that the settings are stored in a file:
univention-app shell myapp cat /etc/univention/base.conf | grep mysetting myapp/mysetting: The "default" value of this setting; optional
So you can still use the variable, just not as comfortable.
- Even Non-Docker Apps are supported. The variables are stored in UCR as well, but on the server itself.
- This does not hold for Settings of type File or PasswordFile. These are stored according to their Filename attribute.
How do I react on Setting changes?
After the Settings are applied, two scripts are called. First, the outer script .configure_host is called. It runs on the Docker Host and therefore also has access to the container (using "univention-app shell"). After that the inner script .configure is called. It may be sufficient for many applications to just have this easier script that runs directly inside the container. How you actually make the variables known to your application is up to you.
What kind of form widgets are supported?
As said, the Settings are defined in an ini file. You can specify some options for each and every Setting. Let's go through them:
The name of the Setting is the name of the section in the ini file:
It is up to you how you want to name them. We prefer variable names with slashes in them and meaningful prefixes like the App ID. This prevents name collisions with the original UCR.
The most important attribute is Type. Currently, these are supported:
- String: A standard input field with no restrictions. Also the default if omitted.
- Int: A number field and validated accordingly.
- Bool: A Checkbox. Saved in UCR as either "true" or "false".
- List: A widget that lets the user choose from a predefined set of values.
- Password: A password input. Note: The content will be stored in a world readable UCR file (world <=> container)!
- File: An upload widget. The content is actually not stored in UCR. Instead it is stored directly in a file according to the definition of the Setting.
- PasswordFile: As a File, but shown as a password input.
- Status: A read-only Settings that is actually meant as a "feedback channel" for the user. This does not render a widget, but instead just writes a text with whatever was written into this variable. Writing to it is up to the App Provider (e.g., by using the configure script).
Another important (because it is required) attribute is Description. It can be localised by also defining Description[de] and so on. It is rendered next to the widget so that the user knows what to do with the form. The variable name itself is not shown.
You can group settings together by using the attribute Group. All settings sharing one group will be put under that label. The default is "Settings". Group[de] is also possible. Ordering of the widgets is done by the ordering in the file.
Show is a powerful attribute that lets you show the Settings on different occasions, namely on the settings page while the App is up and running. But also before installation, upgrade and removal of the App. Possible values are: 'Install', 'Upgrade', 'Remove', 'Settings'.
- It is possible to specify more than one value in Show. For example, you can do Install, Settings, resulting in a form being rendered with this widget before the installation and afterwards on the Settings page.
ShowReadOnly is just like Show, but none of the widgets may be changed. The use case here may be that a Settings has Show set to Install, but although the Setting can never be changed (because it is glued into the setup process and cannot be undone), you want to show the user what was entered during the installation process. Thus, you set ShowReadOnly to Settings.
InitialValue: The value that is set when no prior value was found. This only works well Settings with Show set to Install. One may emtpy a value afterwards in the Settings page and not automatically get the InitialValue back. Therefore it is not named Default.
With Required, you can specify whether or not this Setting has to be set. If not, the installation cannot continue. Or the form cannot be applied.
Another advanded attribute is Scope. You can specify inside, outside, or even inside, outside. It tells the App Center where to apply the Setting, where inside means inside the container (default), outside means on the Docker Host and inside, outside in both worlds. Note that you cannot access variables that are stored outside from within the Container.
- If you are using a Non-Docker App, inside is not possible and outside is the default.
There are more attributes specific to certain Types of Settings:
The attributes Labels and Values are used in the List type. The attributes describe the possible values of the widget, where Labels are what is actually shown to the user and Values what is actually stored in the system. The lists are comma separated and should have the same size. If a comma is necessary inside a label or value, you can escape it: Label 1, Label 2, Label 3\, but with a comma (these are only three labels)
File types (and its derivative, PasswordFile) need to Filename attribute. It should contain the absolute path to the file where the value of the Setting will be stored. Directories are created where necessary.
In summary, this is a minimal Setting:
[myapp/mysetting] Type = String Description = This is the description of the setting Description[de] = Das ist die Beschreibung der Einstellung
and these are two more advanced Settings:
[myapp/myfile] Type = File Filename = /opt/myapp/license Description = License for the App Description[de] = Lizenz der App Show = Install, Settings Group = License and List Group[de] = Lizenz und Liste [myapp/list] Type = List Description = List of values Show = Install ShowReadOnly = Settings Values = value1, value2, value3 Labels = Label 1, Label 2, Label 3 InitialValue = value2 Scope = inside, outside Group = License and List Group[de] = Lizenz und Liste
The first of these two Settings will upload a file to /opt/myapp/license inside the container, the second one will save "myapp/list: value2" (or another value) inside the UCR database in the container AND on the host. Both Settings will be shown before the installation. On the App Settings page, though, the list Setting will be read-only.
This is what the form will look like (combined):
This is one script that App Providers may ship along with their App. See Docker_Apps/Container_Scripts; it counts as an "inner script". The file name extension is .configure.
It can be activated by hand:
univention-app configure myapp
But it is also called when the Settings are used, i.e., applied.
The Settings have been stored prior to calling the script! The script is not called with the values. Instead, it is assumed that the script handles reading the values where needed.
The script will instead be called with this signature:
/path/to/configure <action> --app myapp --app-version 1.0 --error-file /tmp/XXX
where <action> is one of ('settings', 'install', 'upgrade', 'remove'), depending on when the App is configured. See also ???
Configure host script
This is one script that App Providers may ship along with their App. See Docker_Apps/Container_Scripts; it counts as an "outer script". The file name extension is .configure_host.
Everything said in #Configure script also holds. But this script is actually called before the inner configure script.
Thus you can do things on the Docker Host before you configure the Docker Container. If you instead would need to configure the Container before the Host, you have access to it by just using
univention-app shell myapp ...