mirror of
https://github.com/YunoHost/doc.git
synced 2024-09-03 20:06:26 +02:00
add documentation on how to write config panel and actions
This commit is contained in:
parent
3117a2aa83
commit
08414c24aa
6 changed files with 482 additions and 0 deletions
BIN
images/actions_example.png
Normal file
BIN
images/actions_example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
BIN
images/config_panel_example.png
Normal file
BIN
images/config_panel_example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
BIN
images/config_panel_toml_example.png
Normal file
BIN
images/config_panel_toml_example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 125 KiB |
144
packaging_apps_actions.md
Normal file
144
packaging_apps_actions.md
Normal file
|
@ -0,0 +1,144 @@
|
|||
# Applications Actions
|
||||
|
||||
<div class="alert alert-warning">For now, all those features are <b>EXPERIMENTAL</b>
|
||||
and aren't ready for production and are probably going to change again, if you
|
||||
still decide to use them don't expect them to be stable and follow to core
|
||||
development of YunoHost otherwise <b>they might randomly breaks on your apps</b>
|
||||
</div>
|
||||
|
||||
Applications "actions" is a packaging feature that allow you to ship with your
|
||||
application a list of "actions" executable from both the cli and the admin
|
||||
interfaces.
|
||||
|
||||
"actions" are a list of custom commands that, optionally, has arguments (like
|
||||
the installation script of an application has arguments) and once called will
|
||||
called a specific selected command with those arguments. Like an "actions"
|
||||
restart service with a argument "service name" could called the command
|
||||
`systemctl restart $some_service` (but don't that specific action in your app,
|
||||
it's just for example purpose).
|
||||
|
||||
Like the installation page generated from the manifest those actions can accept
|
||||
a list of arguments.
|
||||
|
||||
Their main purpose is to expose procedures that a sysadmin would normally do on
|
||||
CLI but that your application user would want to do but don't have the
|
||||
knowledge to do by themselves via ssh (or are just too lazy for that).
|
||||
|
||||
For example those could be:
|
||||
|
||||
* importing data in a application
|
||||
* generate a custom backup
|
||||
* start a procedure like synchronising file with the file system (nextcloud for example)
|
||||
* purge a local cache
|
||||
* restart some services
|
||||
* modify a theme
|
||||
|
||||
Actions looks like this in the admin interface:
|
||||
|
||||
![actions admin screenshot](images/actions_example.png)
|
||||
|
||||
## How to add actions to your application
|
||||
|
||||
Adding actions to your application is pretty simple as it is very similar to
|
||||
writing your manifest for the application installation.
|
||||
|
||||
You need to write an `actions.toml` file in your application at the root level
|
||||
like the `manifest.toml`/`manifest.json`.
|
||||
|
||||
The general pattern looks like this:
|
||||
|
||||
```toml
|
||||
[first_action]
|
||||
name = "some name"
|
||||
description = "some description that will be displayed"
|
||||
|
||||
# can be a bash command like so:
|
||||
command = "echo pouet $YNH_ACTION_FIRST_ARGUMENT"
|
||||
# or a path to a script like
|
||||
command = "/path/to/some/stuff --some-flag $YNH_ACTION_FIRST_ARGUMENT"
|
||||
|
||||
user = "root" # optional
|
||||
cwd = "/" # optional, "current working directory", by default it's "/etc/yunohost/apps/the_app_id"
|
||||
# also the variable "$app" is available in this variable and will be replace with the app id
|
||||
# for example you can write "/var/www/$app"
|
||||
accepted_return_codes = [0, 1, 2, 3] # optional otherwise only "0" will be a non enorous return code
|
||||
|
||||
[first_action.arguments]
|
||||
# here, you put a list of arguments exactly like in manifest.toml/json
|
||||
[first_action.arguments.first_argument]
|
||||
type = "string"
|
||||
ask = "service to restart"
|
||||
example = "nginx"
|
||||
|
||||
... # add more arguments here if needed
|
||||
# you can also have actions without arguments
|
||||
|
||||
[another_action]
|
||||
name = "another name"
|
||||
command = "systemctl restart some_service"
|
||||
|
||||
[another_action.arguments]
|
||||
[another_action.arguments.argument_one]
|
||||
type = "string"
|
||||
ask = "some stuff"
|
||||
example = "stuff"
|
||||
|
||||
... # add more arguments here if needed
|
||||
# you can also have actions without arguments
|
||||
```
|
||||
|
||||
You can have as much actions as you want and from zero to as many arguments you want.
|
||||
|
||||
If you prefer, you can also write your actions in json like manifest.json:
|
||||
|
||||
```json
|
||||
[{
|
||||
"id": "restart_service",
|
||||
"name": "Restart service",
|
||||
"command": "echo pouet $YNH_ACTION_SERVICE",
|
||||
"user": "root", # optional
|
||||
"cwd": "/", # optional
|
||||
"accepted_return_codes": [0, 1, 2, 3], # optional
|
||||
"description": {
|
||||
"en": "a dummy stupid exemple or restarting a service"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"name": "service",
|
||||
"type": "string",
|
||||
"ask": {
|
||||
"en": "service to restart"
|
||||
},
|
||||
"example": "nginx"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
... # other action
|
||||
}]
|
||||
```
|
||||
|
||||
## How to use actions
|
||||
|
||||
### In the admin
|
||||
|
||||
<div class="alert alert-warning">For now since those features are still
|
||||
experimental you won't find any direct links to the app actions on the app
|
||||
page</div>
|
||||
|
||||
The actions are located on https://some_domain.tld/yunohost/admin/#/apps/$app_id/actions
|
||||
|
||||
## With the CLI
|
||||
|
||||
The CLI API is very similar to application installation. You have 2 commands:
|
||||
|
||||
* `yunohost app list $app`
|
||||
* `yunohost app run $app $action_id` ("$action_id" is the this between "[]"
|
||||
like "[another_action]" in the example)
|
||||
|
||||
`list` will obviously give you all actions for an application.
|
||||
|
||||
`run` will run an existing action for an application and will ask, if needed,
|
||||
values for arguments. Like with `yunohost app install` you can use the `-a` and
|
||||
pass arguments in the HTTP POST arguments format (like
|
||||
`&path=/app&domain=domain.tld&other_value=stuff`)
|
40
packaging_apps_advanced.md
Normal file
40
packaging_apps_advanced.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Advanced features of apps packaging
|
||||
|
||||
<div class="alert alert-warning">For now, all those features are <b>EXPERIMENTALS</b>
|
||||
and aren't ready for production and are probably going to change again, if you
|
||||
still decide to use them don't expect them to be stable and follow to core
|
||||
development of YunoHost otherwise <b>they might randomly breaks on your apps</b>
|
||||
</div>
|
||||
|
||||
## Actions
|
||||
|
||||
Actions allow you to ship a list of executables "actions" related to your
|
||||
application, for example that could be:
|
||||
|
||||
* import data
|
||||
* generate a custom backup
|
||||
* start a procedure
|
||||
* regenerate a local cache
|
||||
|
||||
[Full documentation](#/packaging_apps_actions)
|
||||
|
||||
Example in the admin:
|
||||
|
||||
![actions admin screenshot](images/actions_example.png)
|
||||
|
||||
## Configuration Panel
|
||||
|
||||
Configuration or "config_panel" allow you to offer a custom configuration panel
|
||||
for your application integrated into YunoHost administration panel. This allow
|
||||
you to expose whatever configuration you want for your application and this is
|
||||
generally used to handle an application configuration file when this is not
|
||||
possible inside the application itself.
|
||||
|
||||
This is generally also the place where you want to add the option to make an
|
||||
application public or not.
|
||||
|
||||
[Full documentation](#/packaging_apps_config_panel)
|
||||
|
||||
Example in the admin:
|
||||
|
||||
![actions admin screenshot](images/config_panel_example.png)
|
298
packaging_apps_config_panel.md
Normal file
298
packaging_apps_config_panel.md
Normal file
|
@ -0,0 +1,298 @@
|
|||
# Applications Configuration Panel
|
||||
|
||||
<div class="alert alert-warning">For now, all those features are <b>EXPERIMENTAL</b>
|
||||
and aren't ready for production and are probably going to change again, if you
|
||||
still decide to use them don't expect them to be stable and follow to core
|
||||
development of YunoHost otherwise <b>they might randomly breaks on your apps</b>
|
||||
</div>
|
||||
|
||||
Configuration panel, or "config_panel", is a way for an application to ship a
|
||||
custom configuration panel available in the YunoHost's admin interface for the
|
||||
application. This is generally used to replace the "you need to manually edit
|
||||
this configuration file (or files) in whatever format/language for this
|
||||
application in cli and do all those complex commands" to "just use to
|
||||
configuration panel to change the options of the application".
|
||||
|
||||
Yes, this is one place to add this so asked "how can I make my application from
|
||||
public to private and vice versa" user request.
|
||||
|
||||
config_panel is probably the most complex YunoHost apps feature as you'll need
|
||||
to write both a description of the panel in toml and a script that will need to
|
||||
both work in a "display mode" and "handle inputs" mode. But this is still very
|
||||
doable and very worth it if you need it.
|
||||
|
||||
Here how it looks like in the admin interface:
|
||||
|
||||
![actions admin screenshot](images/config_panel_example.png)
|
||||
|
||||
## Usage
|
||||
|
||||
### Admin interface
|
||||
|
||||
The configuration panel for an application can be accessed with this url:
|
||||
|
||||
https://my_domain.tld/yunohost/admin/#/apps/$app_id/config-panel
|
||||
|
||||
<div class="alert alert-warning">For now since those features are still
|
||||
experimental you won't find any direct links to the app actions on the app
|
||||
page</div>
|
||||
|
||||
### CLI
|
||||
|
||||
For now the CLI API for the config panel is not very good at all, you can still
|
||||
use it but it's really impracticable.
|
||||
|
||||
* `yunohost app config show-panel $app_id` will show the panel. **But for now
|
||||
it's very broken and will asked question for unfilled value of the panel**.
|
||||
|
||||
* `yunohost app config apply` will call the script with apply and... no values
|
||||
since you aren't passing them, except if you are ready to play with the `-a`
|
||||
flag and pass every global value in the HTTP POST format (protip: you don't)
|
||||
|
||||
In conclusion: don't use the CLI for now, we need to design something better.
|
||||
|
||||
## How to add a config_ panel to your application
|
||||
|
||||
### config_panel.toml
|
||||
|
||||
Firs, you need to write a `config_panel.toml` (or `config_panel.json` if you
|
||||
REALLY wants it but we really don't recommend it has it is very error prone and
|
||||
frustrating to write by hand) that will be located at the root of you
|
||||
application, next to the manifest.json/toml. It looks like this:
|
||||
|
||||
```toml
|
||||
version = "0.1" # version number, not used yet but important
|
||||
name = "name that will be displayed on the admin"
|
||||
|
||||
[section_id]
|
||||
name = "name of the section that will be displayed"
|
||||
|
||||
[section_id.sub_section_id]
|
||||
name = "sub section"
|
||||
|
||||
# those arguments are in yunohost argument format like manifest.json
|
||||
[section_id.sub_section_id.option_id]
|
||||
ask = "the text displayed for the option"
|
||||
type = "argument_option"
|
||||
default = true
|
||||
help = "A public Leed will be accessible for third party apps.<br>By turning on 'anonymous readers' in Leed configuration, you can made your feeds public."
|
||||
|
||||
[section_id.sub_section_id.another_option_id]
|
||||
...
|
||||
|
||||
[section_id.another_sub_section_id]
|
||||
name = "stuff"
|
||||
|
||||
[another_section_id]
|
||||
name = "stuff"
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
And a real world example with the rendered admin:
|
||||
|
||||
![config_panel_toml_example](images/config_panel_toml_example.png)
|
||||
|
||||
As a text format:
|
||||
|
||||
```toml
|
||||
version = "0.1"
|
||||
name = "Leed configuration panel"
|
||||
|
||||
[main]
|
||||
name = "Leed configuration"
|
||||
|
||||
[main.is_public]
|
||||
name = "Public access"
|
||||
|
||||
# those arguments are in yunohost argument format
|
||||
[main.is_public.is_public]
|
||||
ask = "Is it a public website ?"
|
||||
type = "boolean"
|
||||
default = true
|
||||
help = "A public Leed will be accessible for third party apps.<br>By turning on 'anonymous readers' in Leed configuration, you can made your feeds public."
|
||||
|
||||
|
||||
[main.overwrite_files]
|
||||
name = "Overwriting config files"
|
||||
|
||||
[main.overwrite_files.overwrite_nginx]
|
||||
ask = "Overwrite the nginx config file ?"
|
||||
type = "boolean"
|
||||
default = true
|
||||
help = "If the file is overwritten, a backup will be created."
|
||||
|
||||
[main.overwrite_files.overwrite_phpfpm]
|
||||
ask = "Overwrite the php-fpm config file ?"
|
||||
type = "boolean"
|
||||
default = true
|
||||
help = "If the file is overwritten, a backup will be created."
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### the scripts/config script
|
||||
|
||||
To make your configuration panel functional you need write a "config" script
|
||||
that will be location in the "script" folder like the "install" script. This
|
||||
script will be called at 2 different occasions:
|
||||
|
||||
* when the configuration panel is displayed and yunohost needs to fill the values
|
||||
* when the configuration is modified by the user
|
||||
|
||||
Every option of the configuration panel will be send to the script
|
||||
following this naming convention:
|
||||
|
||||
```bash
|
||||
YNH_{section_id}_{sub_section_id}_{option_id} (everything in upper case)
|
||||
```
|
||||
|
||||
For example, this option value:
|
||||
|
||||
```toml
|
||||
[main]
|
||||
name = "Leed configuration"
|
||||
|
||||
[main.is_public]
|
||||
name = "Public access"
|
||||
|
||||
# those arguments are in yunohost argument format
|
||||
[main.is_public.is_public]
|
||||
...
|
||||
```
|
||||
|
||||
Will be available under this name in the config script:
|
||||
|
||||
```
|
||||
YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC
|
||||
```
|
||||
|
||||
Also, the same "scripts/config" script is called in both situation. To differentiate
|
||||
those situation the first argument passed to the config script is either "show"
|
||||
or "apply".
|
||||
|
||||
A common pattern to handle that is to write your script following this pattern:
|
||||
|
||||
```bash
|
||||
show_config() {
|
||||
# do stuff
|
||||
}
|
||||
|
||||
apply_config() {
|
||||
# do stuff
|
||||
}
|
||||
|
||||
case $1 in
|
||||
show) show_config;;
|
||||
apply) apply_config;;
|
||||
esac
|
||||
```
|
||||
|
||||
#### The "show" part
|
||||
|
||||
The show part is when the user ask to see the current state of the
|
||||
configuration panel (like opening to configuration panel page on the admin
|
||||
interface). The role of the scripts/config script here is to gather all the
|
||||
relevant information, by for example parsing a configuration file or querying a
|
||||
database, and communicate it to YunoHost. To do so, you need to use the helper
|
||||
`ynh_return` like so:
|
||||
|
||||
```bash
|
||||
ynh_return "YNH_CONFIG_SOME_VARIABLE_NAME=some_value"
|
||||
```
|
||||
|
||||
For example, for this config_panel:
|
||||
|
||||
```toml
|
||||
[main]
|
||||
name = "Leed configuration"
|
||||
|
||||
[main.is_public]
|
||||
name = "Public access"
|
||||
|
||||
# those arguments are in yunohost argument format
|
||||
[main.is_public.is_public]
|
||||
...
|
||||
```
|
||||
|
||||
You would do:
|
||||
|
||||
```bash
|
||||
ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=1"
|
||||
```
|
||||
|
||||
If you don't provide any value for a configuration **the default value will be used**.
|
||||
|
||||
Expanding our previous example you would have this scripts/config script:
|
||||
|
||||
```bash
|
||||
show_config() {
|
||||
ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=1"
|
||||
}
|
||||
|
||||
apply_config() {
|
||||
# do stuff
|
||||
}
|
||||
|
||||
case $1 in
|
||||
show) show_config;;
|
||||
apply) apply_config;;
|
||||
esac
|
||||
```
|
||||
|
||||
#### The "apply" part
|
||||
|
||||
The "apply" part is called when the user click on "submit" on the configuration
|
||||
page on the admin interface. This part is simpler to write:
|
||||
|
||||
- the scripts/config will be called with "apply"
|
||||
- all the value in the config panel (modified or not) are available as global
|
||||
variable in the script following the format `YNH_{section_id}_{sub_section_id}_{option_id}`
|
||||
(exactly the same than for show)
|
||||
- the script is responsible for doing whatever it wants with those information
|
||||
- once the script as succeeded, the admin interface display the config panel
|
||||
again so the script is called again in "show" mode
|
||||
|
||||
Expanding the previous script that could look like that:
|
||||
|
||||
```bash
|
||||
show_config() {
|
||||
ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=1"
|
||||
}
|
||||
|
||||
apply_config() {
|
||||
value=$YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC
|
||||
# do some stuff with value
|
||||
}
|
||||
|
||||
case $1 in
|
||||
show) show_config;;
|
||||
apply) apply_config;;
|
||||
esac
|
||||
```
|
||||
|
||||
Or if you want a full useless simple script that store the value in a file,
|
||||
this can looks like this:
|
||||
|
||||
```bash
|
||||
dummy_config_file="dummy_config_file.ini"
|
||||
|
||||
show_config() {
|
||||
if [ -e $dummy_config_file ]
|
||||
then
|
||||
ynh_return "YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC=$(cat $dummy_config_file)"
|
||||
fi
|
||||
|
||||
# the default value will be used
|
||||
}
|
||||
|
||||
apply_config() {
|
||||
echo $YNH_CONFIG_MAIN_IS_PUBLIC_IS_PUBLIC > $dummy_config_file
|
||||
}
|
||||
|
||||
case $1 in
|
||||
show) show_config;;
|
||||
apply) apply_config;;
|
||||
esac
|
||||
```
|
Loading…
Reference in a new issue