Files
init.sh/doc/dev.md
2022-06-24 17:52:17 +02:00

837 lines
41 KiB
Markdown

# init.sh developer's reference
## Table of content
- [1. Getting started](#1-getting-started)
- [2. The aaa_error.sh file](#2-the-aaa_errorsh-file)
- [2.1. Functions](#21-functions)
- [2.1.1. ```check_root```](#211-check_root)
- [2.1.2. ```die <exitcode> [--force]```](#212-die-exitcode---force)
- [2.1.3. ```noerror [--noout] <command>```](#213-noerror---noout-command)
- [2.2. Other functionalities](#22-other-functionalities)
- [3. The chroot.sh file](#3-the-chrootsh-file)
- [3.1. Functions](#31-functions)
- [3.1.1. ```chroot_bootstrap```](#311-chroot_bootstrap)
- [3.2. Other functionnalities](#32-other-functionnalities)
- [4. The diskman.sh file](#4-the-diskmansh-file)
- [4.1. Global warning](#41-global-warning)
- [4.2. Function](#42-function)
- [4.2.1. ```blank_disk <bloc_device> [--full]```](#421-blank_disk-bloc_device---full)
- [4.2.2. ```is_blank <bloc_device>```](#422-is_blank--bloc_device)
- [4.2.3. ```mkparts <disk> [dos|gpt] [size_part1 [... size_partN]]```](#423-mkparts--disk-dosgpt-size_part1--size_partn)
- [4.3. Other functionnalities](#43-other-functionnalities)
- [5. The command_line.sh file](#5-the-command_linesh-file)
- [5.1. Functions](#51-functions)
- [5.1.1. ```read_commandline```](#511-read_commandline)
- [5.1.5. ```process_commandline_and_vars```](#515-process_commandline_and_vars)
- [5.2. Other functionnalities](#52-other-functionnalities)
- [6. The display.sh file](#6-the-displaysh-file)
- [6.1. Functions](#61-functions)
- [6.1.1. ```prnt [-n] [I|W|E|m] <message>```](#611-prnt--n-iwem-message)
- [6.1.2. ```separator```](#612-separator)
- [6.1.3. ```dsleep <miliseconds> [char]```](#613-dsleep-miliseconds-char)
- [6.1.4. ```dump_key_buffer```](#614-dump_key_buffer)
- [6.2. Other functionalities](#62-other-functionalities)
- [7. The filefct.sh file](#7-the-filefctsh-file)
- [7.1. Common behavior](#71-common-behavior)
- [7.2. Functions](#72-functions)
- [7.2.1. ```backup_dist <file_or_dir1> [file_or_dir2 [... file_or_dirN]] ```](#721-backup_dist-file_or_dir1-file_or_dir2--file_or_dirn-)
- [7.2.2. ```select_file <filename>```](#722-select_file-filename)
- [7.2.2. ```install_file <source1> [source2 [... sourceN]] <destination>```](#722-install_file-source1-source2--sourcen-destination)
- [7.2.3. ```append_file <source> <destination>```](#723-append_file-source-destination)
- [7.2.4. ```is_dir_empty <directory>```](#724-is_dir_empty-directory)
- [7.2.5. ```patch_file <source> <destination> [VAR1 [VAR2 [... VARN]]]```](#725-patch_file-source-destination-var1-var2--varn)
- [7.2.6. ```tag_file <file1> [file2 [... fileN]]```](#726-tag_file-file1-file2--filen)
- [7.2.7. ```file_exists <file1> [file2 [... fileN]]```](#727-file_exists-file1-file2--filen)
- [7.2.8. ```file_must_exists <file1> [file2 [... fileN]]```](#728-file_must_exists-file1-file2--filen)
- [7.2.9. ```directory_exists <directory1> [directory2 [... directoryN]]```](#729-directory_exists-directory1-directory2--directoryn)
- [7.2.10. ```directory_must_exists <directory1> [directory2 [... directoryN]]```](#7210-directory_must_exists-directory1-directory2--directoryn)
- [7.3. Other functionnalities](#73-other-functionnalities)
- [8. The loaders.sh file](#8-the-loaderssh-file)
- [8.1. Functions](#81-functions)
- [8.1.3. ```load_autoconf```](#813-load_autoconf)
- [8.1.4. ```load_configuration```](#814-load_configuration)
- [8.2. Other functionnalities](#82-other-functionnalities)
- [9. The pkgman.sh file](#9-the-pkgmansh-file)
- [9.1. Global dependencies](#91-global-dependencies)
- [9.2. Functions](#92-functions)
- [9.2.1. ```pkgupdt```](#921-pkgupdt)
- [9.2.2. ```pkginst <package1> [package2 [... packageN]]```](#922-pkginst-package1-package2--packagen)
- [9.2.3. ```pkgupgd```](#923-pkgupgd)
- [9.2.4. ```pkgrm <package1> [package2 [... packageN]]```](#924-pkgrm-package1-package2--packagen)
- [9.2.5. ```pkgautorm```](#925-pkgautorm)
- [9.3. Other functionnalities](#93-other-functionnalities)
- [10. The services.sh file](#9-the-servicessh-file)
- [10.1. Global dependencies](#101-global-dependencies)
- [10.2. Functions](#102-functions)
- [10.2.1. ```exec_serv <service> <command>```](#1021-exec_serv-service-command)
- [10.2.2. ```svc_start <service1> [service2 [... serviceN]]```](#1022-svc_start-service1-service2--servicen)
- [10.2.3. ```svc_reload <service1> [service2 [... serviceN]]```](#1023-svc_reload-service1-service2--servicen)
- [10.2.2. ```svc_restart <service1> [service2 [... serviceN]]```](#1022-svc_restart-service1-service2--servicen)
- [10.2.3. ```svc_stop <service1> [service2 [... serviceN]]```](#1023-svc_stop-service1-service2--servicen)
- [10.3. Other functionnalities](#103-other-functionnalities)
- [11. The support.sh file](#11-the-supportsh-file)
- [11.1. Global behaviour](#111-global-behaviour)
- [11.2. Functions](#112-functions)
- [11.2.1. ```disp_help```](#1121-disp_help)
- [11.2.2. ```show_version```](#1122-show_version)
- [11.3. Other functionnalities](#113-other-functionnalities)
- [12. The utils.sh file](#12-the-utilssh-file)
- [12.1. Functions](#121-functions)
- [12.1.1. ```stdtime```](#1211-stdtime)
- [12.1.2. ```function_exists <function_name>```](#1212-function_exists-function_name)
- [12.1.3. ```get_mod_name <module_file>```](#1213-get_mod_name-module_file)
- [12.1.4. ```set_system_proxy```](#1214-set_system_proxy)
- [12.2. Other functionnalities](#122-other-functionnalities)
- [13. The version.sh file](#13-the-versionsh-file)
- [13.1. Functions](#131-functions)
- [13.1.1. ```get_os_version```](#1311-get_os_version)
- [13.1.2. ```set_sys_var <arch> <dist> <version> <codename>```](#1312-set_sys_var-arch-dist-version-codename)
- [13.2. Other functionnalities](#132-other-functionnalities)
- [14. Global variables](#14-global-variables)
- [15. Writing conventions](#15-writing-conventions)
## 1. Getting started
This is a developer's reference. It's not intended to be a manual, but a
reference for all internal functions, so you can easily build your own modules.
This supposes you already read the [README file](../README.md). Creating modules
will also require some good knowledge of Bash programming.
Writing conventions are the classical ones:
* ```<param>```: written like this, the parameter is mandatory
* ```[param]```: that parameter is optional
* ```[ab|cd]```: optional parameter have to be "ab" or "cd"
* ```[0..15,20]```: acceptable values start at 0 and goes up to 15 or be 20.
Boolean values have to be set as ```true``` or ```false``` for test to succeed.
Any unset boolean is always interpreted as ```false```.
## 2. The aaa_error.sh file
### 2.1. Functions
#### 2.1.1. ```check_root```
Check if user is root. If the user is not root, script execution interrupts and
exit with error.
This function has no parameter.
If the variable ```NO_ROOT_CHECK``` is set to true, the function always exit
without error and no check is done.
#### 2.1.2. ```die <exitcode> [--force]```
Trigger an error, print a back trace and exit the script, unless ```KEEPGOING```
variable is set to true. In that situation, we just display a warning.
If the parameter ```--force``` is given, we exit even if the ```KEEPGOING```
variable is set to true.
#### 2.1.3. ```noerror [--noout] <command>```
Allow the execution of a command bypassing the error management system. The
purpose is to allow execution of tests returning normally a non-zero value
without triggering an error and the exit coming with.
If the first parameter is ```--noout``` any outputs on standard and error
console are disabled. The other parameters are the raw command line to execute.
In any case, the function echoes the error code returned by the executed
command.
### 2.2. Other functionalities
The simple integration of aaa_error.sh file into a script, will change the
entire script behavior regarding errors. The following Bash signals will be
trapped:
- **```ERR```**: The ```ERR``` signal is triggered every time Bash encounters
an error or if a command return a non-zero value. The function called on that
signal will stop execution of the script, displaying an error message with error
code and a back trace to help identify the error origin. Because of this
behavior, the function supersedes the internal ```errexit``` Bash configuration
switch, unless the *noerror* function is used.
- **```SIGINT```**: That signal is triggered when ```Ctrl + C``` is pressed by
the user. That signal will be interpreted only if the command being executed
when the event occurs is a Bash internal. If an executable program receive the
signal it will be interpreted with its own mechanisms, generally resulting in an
execution error that will trigger an **```ERR```** signal as described above.
The script will exit after cleanup when that signal is trapped.
- **```SIGTERM```**: That signal is typically the result of an external kill of
the bash process running the script. The kill signal can come from the kernel or
through the use of a *kill* command. The script will exit after cleanup.
## 3. The chroot.sh file
### 3.1. Functions
#### 3.1.1. ```chroot_bootstrap```
That function is called if a chroot option have been given. It's in charge of
performing the chroot, copying a full working directory structure of init.sh
tree. After that copy, a chroot command is run, launching that new copy of
init.sh.
If the child init.sh end with error, the stage file is gathered in parent
directory tree to allow launching again the chrooted init.sh with the resume
option.
At the end, the function will clean up, removing the second copy of init.sh.
### 3.2. Other functionnalities
So far, only one function is provided in this file.
## 4. The diskman.sh file
### 4.1. Warning about that unit
The goal of that unit is to provide disks manipulation function, like
partitioning, blanking or format. All those functions are potentially very
destructive. Please use with extra care and do not hesitate to highly protect
your code when using those. By defaults, the functions try to be as conservative
as they can, triggering errors on the smallest doubt.
### 4.2. Function
#### 4.2.1. ```blank_disk <bloc_device> [--full]```
Blank a block device using two different method to be sure it's all clear. First
we use the *wipefs* method, specialized in resetting all possible flags on the
drive and it's partitions. It will also blank the partition table. A second pass
will fill the first 512 MB with zeroes to also blank MBR and other parts of the
drive wipefs would have ignored.
If the parameter ```--full``` is provided as second parameter, the entire disk
will be filled with zeroes. Please consider that such operation might take a
very long time (can be several hours).
That function only take parameter which must be a block device.
#### 4.2.2. ```is_blank <bloc_device>```
That function will try to detect if a drive is blank or not. It will return 0 if
the drive is blank, and return 1 otherwise. If the function return 2, either the
provided parameter is not a block device or that block device do not exist.
Please consider that special drive configuration could be detected as blank
while it's not. Only one parameter will be accepted, a block device.
The function will give different information depending on the block device you
test:
- On a whole disk drive, it while return 0 if the drive is blank, meaning no
MBR and no partition table (either GTP or DOS);
- On a partition, it will tell if that partition is formatted or not. Beware
that an erased then recreated partition will continue to have old data
available and will be shown as non-blank.
#### 4.2.3. ```mkparts <disk> [dos|gpt] [size_part1 [... size_partN]]```
This function create partitions on the disk given as the first parameter. The
second parameter can be gpt or dos, respectively, to instruct the creation of a
GPT partition table (which is default when not mentioned) or a DOS partition
table, deprecated but supported for compatibility purposes. Then a list of size
can be given to generate more than one partition. In the case of a DOS partition
table, only primary partition are possible, four of, maximum.
Partition size can be :
- Simple number: will be interpreted as a precise number of cylinders, this is
the only method that will be precise;
- 100M: will create a 100 MiB partition, more or less to the nearest cylinder;
- 100G: will create a 100 GiB partition, more or less to the nearest cylinder;
- 100T: same again 100 TiB, and you really have a lot of space...
- 0: will be interpreted as all remaining space in the final partition scheme.
It must come only once.
Be warned that a size (whatever the unit is) can result in slightly different
space depending on the drive model and cylinder size.
### 4.3. Other functionalities
That file don't provide any other things that the previously listed functions.
## 5. The command_line.sh file
### 5.1. Functions
#### 5.1.1. ```read_commandline```
That function consist in a loop that analyze command line one parameter after
the other. Most of command line parameters will result in the positioning of
some global variables. The following table details the variable with their type
associated to the corresponding parameter:
| Parameter | Variable | Type | Description |
|:--------------|:-------------------|:--------|:------------------------------|
| --help | *none* | *n/a* | Trigger help display directly and exit |
| --version | *none* | *n/a* | Trigger version display directly and exit |
| --module | MANUAL_MODULE_LIST | string | The following parameter will set a list of module to use |
| --check-only | CHECK_ONLY | boolean | Activate check only mode |
| --jump | JUMP | boolean | Activate no check mode |
| --keep-going | KEEPGOING | boolean | Activate keep going option |
| --resume | RESUME | boolean | Activate resume mode if stage file exists |
| --no-root-check | NO_ROOT_CHECK | boolean | Activate option to not check if user is root |
| --no-deps | NO_DEPS | boolean | Activate not checking module dependencies option |
| --logfile | NEW_LOGFILE | string | The following parameter will be the log filename |
| --file | CONFFILES | string | The following parameter will be a configuration filename |
| --shell | RUN_SHELL | boolean | Activate the shell mode |
| --chroot | CHROOT_PATH | string | The following parameter will be the path to chroot in |
| --cron | CRON_MODE | boolean | Activate cron mode |
The function will do some basic syntax checks. For example, if you put an option
just after one supposing a value declaration, an error will be triggered
directly.
#### 5.1.5. ```process_commandline_and_vars```
That function has the role to check the concistency of command line parameters.
It will trigger errors if incompatible parameters have been given or if those
parameters might lead to a non-predictable situation.
When those checks are done, the definitive module list to load is created. With
that list we then checks the modules are available and do not contain the dash
character.
That function will also trigger an error if the resulting module list appears to
be empty.
### 5.2. Other functionalities
That file don't provide any other things that the previously listed functions.
## 6. The display.sh file
### 6.1. Functions
#### 6.1.1. ```prnt [-n] [I|W|E|m] <message>```
Print a message with timestamp and header. The header depends on a single
character parameter, will be colored and have a fixed length, so the messages
will always be aligned.
If the first parameter is ```-n```, we won't go to a new line after displaying
the message.
The first parameter (if ```-n``` is not provided) is the header type, having
those possible values:
- **I**: Display an informative message in green
- **W**: Display a warning in yellow
- **E**: Display an error in red
- **m**: Display a message without header but aligned
- Anything else will be treated as the message and will lose alignment.
The second parameter is the message to display.
As this function is widely used almost everywhere in the code at runtime,
consider it as being a base dependency of all libraries and modules.
Consequently, that function can only contain code that cannot trigger errors or
fail, as it's also used to display errors. Thus, it only contains echoes and
some variables manipulation.
#### 6.1.2. ```separator```
That function display a separator made with dash, filling the screen length minus
one character if screen length is 80 character or less. If the screen length is
above 80 characters, the length of the separator will be 80 plus half of
additional length.
It takes no parameters and return no value.
#### 6.1.3. ```dsleep <miliseconds> [char]```
That function is an equivalent to *sleep* bash command but will display a
countdown every second until it reaches zero. Optionally, a character (or a
string) can be given as a second parameter to replace the countdown by that
character. For example, you can use a dot to display a dot every second until
the wait is over.
The function returns nothing useful.
#### 6.1.4. ```dump_key_buffer```
That function dumps the keyboard's buffer. It's used to clear eventual key press
before any critical keyboard action.
That function takes no parameter and returns no useful value.
### 6.2. Other functionalities
Using that script will declare some easy to remember variables containing Bash
color codes:
- Standard codes depending on your environment: DEFAULTFG,
DEFAULTBG, ```DEFAULTCOL=${DEFAULTBG}${DEFAULTFG}```
- Regular colors: Black, Red, Green, Yellow, Blue, Purple, Cyan, White
- Bold (only available in graphical console or some non standard console
fonts): BBlack, BRed, BGreen, BYellow, BBlue, BPurple, BCyan, BWhite
- Underline: UBlack, URed, UGreen, UYellow, UBlue, UPurple, UCyan, UWhite
- Background: On_Black, On_Red, On_Green, On_Yellow, On_Blue, On_Purple,
On_Cyan, On_White
- High intensity: IBlack, IRed, IGreen, IYellow, IBlue, IPurple, ICyan, IWhite
- Bold high intensity (only available in graphical console or some non standard
console fonts): BIBlack, BIRed, BIGreen, BIYellow, BIBlue, BIPurple,
BICyan, BIWhite
- High intensity backgrounds: On_IBlack, On_IRed, On_IGreen, On_IYellow,
On_IBlue, On_IPurple, On_ICyan, On_IWhite
For example, if you what to write "ATTENTION: this is a warning!" in red with
"ATTENTION:" on yellow background, you should write:
```shell
echo -e "${IRed}${On_IYellow}ATTENTION:${DEFAULTBG} this is a warning!${DEFAULTCOL}"
```
Remember to always terminate an *echo -e* using colors with the $DEFAULTCOL
variable. If not, any new line might be filled with the last used color and line
ending will be filled with background color.
## 7. The filefct.sh file
### 7.1. Common behavior
In our terminology, a source file can be of three different origins, selected
automatically from highest to lowest priority:
- **```repo/hosts/$HOSTNAME```**: this allows to provide system specific
files. Use only relative path to access it.
- **```repo/common```**: this one will provide files suitable for your entire
infrastructure. Yet again, provide a relative path to access it.
- **Any path**: You can give fully qualified path names to access resources
from other locations.
### 7.2. Functions
#### 7.2.1. ```backup_dist <file_or_dir1> [file_or_dir2 [... file_or_dirN]] ```
That function will provide a backup of any given files or directories given in
command line. The backup will be named name.dist-timestamp, where name is the
original file or directory name and timestamp the date and time of the backup
as retuned by the ```stdtime``` function. If a file given in parameter don't
exists, the function will issue a warning and continue to the next.
If the target file or directory is a symbolic link, the link will be resolved
recursively until we backup in the backup destination.
The function don't take any other parameters than file and/or directory names.
#### 7.2.2. ```select_file <filename>```
Returns the best match in our priority system, returning on ```stdout``` the
resulting fully qualified path name as a result. The priorities apply on file
existence.
Many functions manipulating files in ```init.sh``` depends on that function.
#### 7.2.2. ```install_file <source1> [source2 [... sourceN]] <destination>```
Install a list of source files to the given destination using our priority
system.
Wildcards are not allowed in file names, so an error will occur if you try to
use any. It's also not yet possible to give an entire directory as a source.
The last parameter is always the destination. If the destination path does not
exists, it will be created automatically. The destination must be a fully
qualified file name (and consequently, begin with "/").
#### 7.2.3. ```append_file <source> <destination>```
That function add the content of source file to destination file. The source
file can have different origins, following the same path priority as the
*install_file* function.
The destination file must exist and be on the root file system. Only two
parameters are accepted, the source and destination files.
#### 7.2.4. ```is_dir_empty <directory>```
That function take only one parameter, a path name and return 0 if the given
path doesn't exist or is empty. It will return one if there's at least one file
in the given directory.
If the given parameter is a file (or a symlink to a file), it will terminate
with an error.
#### 7.2.5. ```patch_file <source> <destination> [VAR1 [VAR2 [... VARN]]]```
That function will patch the given file using our priority system, patch it
then place the result in the given destination. The patching will be done when
any @VAR@ item in the source file will match an environment variable of the
exact same name without the trailing @. Variables will be either the
given list or, if nothing is given in parameter, in the global system
variables, in the context of the *init.sh* execution.
The source file must exist and not be empty. The function returns nothing
useful.
#### 7.2.6. ```tag_file <file1> [file2 [... fileN]]```
That function add a tag to the first line of the given files. If one file
already exists, the added line will be in the form:
``` # File automatically modified by init.sh on $(stdtime).```
If it doesn't exist, it is created with the line:
```# File automatically generated by init.sh on $(stdtime).```
```stdtime``` is the timestamps function in the ```utils.sh``` library file.
It's not using the file selection system, as our source file are not supposed to
be modified directly. In consequence, you should always provide fully qualified
path names to it.
#### 7.2.7. ```file_exists <file1> [file2 [... fileN]]```
That function check files existence within our file selection system. If one
source file is missing it will return 1 and echo the first file name that have
not been found in the list. If all the given files exists, it returns 0 and
echoes nothing.
#### 7.2.8. ```file_must_exists <file1> [file2 [... fileN]]```
That function check files existence within our file selection system. If one
source file is missing, it will return an error and stop execution. That function
is logically massively used during check phase to verify all source files are in
place.
#### 7.2.9. ```directory_exists <directory1> [directory2 [... directoryN]]```
That function check directories' existence within our file selection system. If
one source directory is missing, it will return 1 and echo the first directory
name that have not been found in the list. If all the given directories exists,
it returns 0.
#### 7.2.10. ```directory_must_exists <directory1> [directory2 [... directoryN]]```
That function check directories' existence within our file selection system. If
one source directory is missing, it will return an error and stop execution.
That function is useful during check phase to verify all source directories are
in place.
### 7.3. Other functionalities
That library initialize a couple of variables possibly useful in modules:
* ```HOST_REPO_PATH```: path where source files specific to the host will be
stored. Default is ```repo/hosts/$HOSTNAME``` under the ```init.sh``` script
directory;
* ```COMM_REPO_PATH```: path where common source files will be stored. Default
is ```repo/common``` under the ```init.sh``` script directory.
## 8. The loaders.sh file
### 8.1. Functions
#### 8.1.3. ```load_autoconf```
That function will automatically load system specific configuration if file
exist in the following order:
1) ```auto/arch.conf.sh```
2) ```auto/distro.conf.sh```
3) ```auto/distro-arch.conf.sh```
4) ```auto/distro-version.conf.sh```
5) ```auto/distro-codename.conf.sh``` (if ```SYS_CODE``` defined)
6) ```auto/distro-version-arch.conf.sh```
7) ```auto/distro-codename-arch.conf.sh``` (if ```SYS_CODE``` defined)
Please note that a situation where no such file exists would lead to error. Most
of the time, a basic package manager configuration will be required to make it
work.
#### 8.1.4. ```load_configuration```
That function loads configuration files. It will first check for configuration
given as command line parameter. If no such parameter exists, it will try to
load a file named ```conf/${HOSTNAME}.conf.sh```. If that file don't exist, the
generic configuration will be loaded in the file ```conf/init.conf.sh```.
If no configuration file can be found, the function will trigger an error and
exit the script.
### 8.2. Other functionalities
That file don't provide any other things that the previously listed functions.
## 9. The pkgman.sh file
### 9.1. Global dependencies
Because it gives system independent function to the system dependent package
manager, the entire file depends on ```PKG_MAN``` variable, defining the package
manager executable to use. Other variables giving command line parameters to
use for the different function will also be needed and detailed for every
function. All those variable have to be defined in a system dependent
configuration file automatically called on script startup.
### 9.2. Functions
#### 9.2.1. ```pkgupdt```
That function calls the package manager to update the package database.
It depends on the ```COM_UPDATE``` variable which define the parameters to use
to accomplish that function.
That function takes no parameters and any given parameters will be ignored.
#### 9.2.2. ```pkginst <package1> [package2 [... packageN]]```
That function installs using the package manager the packages given in
parameters. The list of parameters will be entirely considered as package names.
Before installation, the list of package to be installed by the package
manager will be extracted to allow execution of pre-installation scripts
and post-installation scripts, even for dependencies (i.e.: packages not parts
of the given parameters).
Pre-installation scripts have to be named ```preinst_<package_name>```.
Post-installation script will be in the form ```postinst_<package_name>```.
If the ```INSTALL_MODE``` variable is set to ```dev``` the package manager will
be called surrounded by eventual pre and post install scripts, one package
after the other. Elsewhere, all pre-installation scripts are executed, followed
by the package manager with the entire package list as parameter and finally
all the post-installation scripts.
The function depends on the ```COM_INSTALL``` variable which define the
parameter to use to accomplish that package manager function.
#### 9.2.3. ```pkgupgd```
That function calls the package manager to upgrade the system. If pre-upgrade
scripts exist, they will be executed if the corresponding package are being
upgraded. After the upgrade, the same behavior will trigger post-upgrade
scripts.
Pre-upgrade scripts have to be named ```preupgd_<package_name>```. Post-upgrade
scripts will be in the form ```postupgd_<package_name>```.
It depends on the ```COM_UPGRADE``` variable which define the parameters to use
to accomplish that function.
That function takes no parameters and any given parameters will be ignored.
#### 9.2.4. ```pkgrm <package1> [package2 [... packageN]]```
That function uninstalls using the package manager the packages given in
parameters. The list of parameters will be entirely considered as package names.
Before removal, the list of package to be uninstalled by the package
manager will be extracted to allow execution of pre-removal scripts
and post-removal scripts, even for dependencies (i.e.: packages not parts of
the given parameters).
If the ```INSTALL_MODE``` variable is set to ```dev``` the package manager will
be called one package after the other (along with pre and post-remove scripts).
Elsewhere, all pre-removal scripts are executed, followed by the package manager
with the entire package list as parameter and finally all the post-removal
scripts.
Pre-remove scripts have to be named ```prerm_<package_name>```. Post-remove
script will be in the form ```postrm_<package_name>```.
The function depends on the ```COM_REMOVE``` variable which define the parameter
to use to accomplish that function.
#### 9.2.5. ```pkgautorm```
That function calls the package manager to remove no longer needed dependencies
still installed. Any package not manually installed is considered as a
dependency.
Pre-removal and post-removal scripts will be executed accordingly if any
matching package is to be removed. It will be the same as the ones executed by
```pkgrm``` function.
It depends on the ```COM_AUTOREM``` variable which define the parameters to use
to accomplish that function.
That function takes no parameters and any given parameters will be ignored.
### 9.3. Other functionalities
Other functions are declared to call pre- and post-actions for the corresponding
package manager events. It doesn't make sense those functions to be called
outside the integrated package manager mechanisms as their functionalities
depends on variables managed by their respective package manager functions.
The following table resume those function sorted with their respective caller:
| Pre/post-functions | Caller | Required var | Package trigger | Description |
|:-------------------|:--------|:-------------|:---------------|:--------------|
| ```exec_preinst``` | ```pkginst``` | ```GET_INTALLLIST``` | ```preinst_@pkgname@``` | ```GET_INTALLLIST``` variable defines the command that allows us to obtain the list of package that will be installed with ```@pkg@``` as a substitute to the list given as ```pkginst``` parameters. |
| ```exec_postinst``` | ```pkginst``` | ```POSTINSTLIST``` | ```postinst_@pkgname@``` | ```POSTINSTLIST``` is generated by ```exec_preinst``` and destroyed after ```exec_postinst``` execution. |
| ```exec_preupgd``` | ```pkgupgd``` | ```GET_UPGRADELIST``` | ```preupgd_@pkgname@``` | ```GET_UPGRADELIST``` variable defines the command that allows us to obtain the list of package that will be installed. |
| ```exec_postupgd``` | ```pkgupgd``` | ```POSTUPGRADELIST``` | ```postupgd_@pkgname@``` | ```POSTUPGDLIST``` is generated by ```exec_preupgd``` and destroyed after ```exec_postupgd``` execution. |
| ```exec_prerm``` | ```pkgrm``` | ```GET_REMOVELIST``` | ```prerm_@pkgname@``` | ```GET_REMOVELIST``` variable defines the command that allows us to obtain the list of package that will be removed. ```@pkg@``` will be substituted by the list given as ```pkgrm``` parameters. |
| ```exec_postrm``` | ```pkgrm``` | ```POSTRMLIST``` | ```postrm_@pkgname@``` | ```POSTRMLIST``` is generated by ```exec_prerm``` and destroyed after ```exec_postrm``` execution. |
| ```exec_preautorm``` | ```pkgautorm``` | ```GET_AUTORMLIST``` | ```prerm_@pkgname@``` | ```GET_AUTORMLIST``` variable defines the command that allows us to obtain the list of package that will be automatically removed. |
| ```exec_postautorm``` | ```pkgautorm``` | ```POSTRMLIST``` | ```postrm_@pkgname@``` | ```POSTRMLIST``` is generated by ```exec_preautorm``` and destroyed after ```exec_postautorm``` execution. |
## 10. The services.sh file
### 10.1. Global dependencies
That script relies on the ```INIT_COM``` variable, defining the program to use
to manipulate services. It is defined in configuration file automatically called
depending on your distribution. Nevertheless, even if it's system dependent,
some distributions offer you to choose between different services call (and
init system). If you're not using the standard init system of your distribution,
you'll need to overload the ```INIT_COM``` variable in your configuration files.
It have been tested with SystemV, SystemD and UpStart init systems. Thus,
the originally UpStart "service" program tend to be available on many systems
and is privileged.
With the tested init systems, and considering ```%srv%``` the service name and
```%com%``` the command to execute, the ```INIT_COM``` variable can be:
* **```$RC_SCRIPTS_PATH/%srv% %com%```** with ```$RC_SCRIPTS_PATH``` being ```/etc/init.d``` on Debian like systems when using SystemV init. The variable can be overloaded to change the access path.
* **```systemctl %com% %srv%```** for systems using SystemD
* **```service %srv% %com%```** for upstart like scripts (but widely available)
### 10.2. Functions
#### 10.2.1. ```exec_serv <service> <command>```
That function execute the given action to the given service. The service have
to be the first parameter and the action, the second parameter. No more
parameter will be accepted and an error will be triggered if there's any more
than two.
The function returns the exit code of the service command.
#### 10.2.2. ```svc_start <service1> [service2 [... serviceN]]```
Start the services given in parameters. You can give as many services you want.
That function relies on the previously documented exec_serv function.
#### 10.2.3. ```svc_reload <service1> [service2 [... serviceN]]```
Reload the configuration of the services given in parameters. You can give as
many services you want. Be careful using this as some services don't have that
capability.
That function relies on the previously documented exec_serv function.
#### 10.2.2. ```svc_restart <service1> [service2 [... serviceN]]```
Restart the services given in parameters. It consists generally in a stop
immediately followed by a start. You can give as many services you want.
That function relies on the previously documented exec_serv function.
#### 10.2.3. ```svc_stop <service1> [service2 [... serviceN]]```
Stop the services given in parameters. You can give as many services you want.
That function relies on the previously documented exec_serv function.
### 10.3. Other functionnalities
That file don't provide any other thing that the previously listed functions.
## 11. The support.sh file
### 11.1. Global behavior
That file is designed to just display information. It only contains code that
doesn't require any special rights, and do nothing to the system. The idea is to
have the minimal sets of dependencies. As it's sometimes using colors to display
results, it depends only on color code declaration in the ```display.sh``` file.
### 11.2. Functions
#### 11.2.1. ```disp_help```
That function display the help screen, usually called using the *--help* switch.
It's not taking any parameter and return nothing but help text.
#### 11.2.2. ```show_version```
That function display the version of init.sh. It will also parse all the
available modules to display a table with their respective versions.
If the user is not root, an additional warning will be displayed to warn the
fact the script requires root privileges to work properly.
### 11.3. Other functionalities
That file don't provide any other thing that the previously listed functions.
## 12. The utils.sh file
### 12.1. Functions
#### 12.1.1. ```stdtime```
Display date and time based on RFC 3339 standard but slightly modified, so it
can be used in filename. Thus, spaces are replaced by dash, and comas between
hours, minutes and seconds are just removed.
That function takes no parameters and return its result on standard output.
#### 12.1.2. ```function_exists <function_name>```
That function checks if the given name is a defined function in the execution
environment. It returns 0 if yes and 1 value if not. The function name is
mandatory and an error will be triggered if no function name is given.
That functions prints nothing.
#### 12.1.3. ```get_mod_name <module_file>```
That function return the name of the module file given in parameter. It takes
only one parameter: a module file name.
Result will be sent to ```stdout```.
#### 12.1.4. ```set_system_proxy```
That function applies proxy settings in the configuration files to the system
proxy configuration, unless the ```--no-proxy``` parameters have been given
command line or if proxy settings are already set.
That function takes no parameters and only change ```http_proxy``` and
```https_proxy``` standard POSIX variables in the script environment. No useful
result will be returned.
### 12.2. Other functionalities
That file don't provide any other thing that the previously listed functions.
## 13. The version.sh file
### 13.1. Functions
#### 13.1.1. ```get_os_version```
That function takes no parameters and will return three values in order:
1. Distribution ID, in low case, usually equivalent to the distribution name.
2. Distribution version, if available, elsewhere kernel version (only major and
minor, release will be ignored).
3. Distribution code-name (e.g., buster for Debian 10) in lowercase if
available. If not, the generic "null" value is returned instead.
The function mainly relies on the "*/etc/os-release*" new standard file. If your
distribution do not provide that file, it is required you generate it yourself
before using init.sh. If you need help with the *os-release* file you can check
the [official documentation](https://www.freedesktop.org/software/systemd/man/os-release.html).
In "*/etc/os-release*" the variables *ID*, *VERSION_ID* and *VERSION_CODENAME*
will be the ones being analyzed. Only the *ID* variable is mandatory.
#### 13.1.2. ```set_sys_var <arch> <dist> <version> <codename>```
That function sets some important variables that will store the system
architecture. It allows the automatic loading of mandatory system dependent code
and variables. For debugging purpose it's be possible to call it manually.
Inside the init.sh initialization, it's called that way:
```shell
set_sys_vars $(uname -m) $(get_os_version)
```
All the four parameters have to be given in that order:
1. System architecture (e.g., x86_64, i386, arm64...)
2. Distribution name (e.g., debian, centos, ubuntu...)
3. Distribution version (or kernel version for rolling releases)
4. Distribution code-name if available (e.g., jessie, buster, bulleyes...)
If your distribution do not provide any code-name, you have to give "null" as a
replacement parameter.
The following global variables will be set at the end of the execution:
- **```SYS_ARCH```** for the system architecture
- **```SYS_DIST```** for the distribution name
- **```SYS_VER```** for the distribution version
- **```SYS_CODE```** for the distribution code-name
The ```SYS_CODE``` variable won't be set if your distribution provides no
code-name.
### 13.2. Other functionnalities
That file don't provide any other thing that the previously listed functions.
## 14. Global variables
Here is the table of the global variable, that could be usefull either to change
script behavior, or because those variables could be useful in many modules.
| Varaible | Type | Use |
|:-------------|:-------|:-----------------------------------------------|
| HOSTNAME | string, automatic | Define the name of the host |
| MODULE_LIST | comma separated string list, configuration file | The module list to execute |
## 15. Writing conventions
For readability and compatibility purpose, I adopted some writing conventions.
First, indentation is made with space only, as different editors can have a very
different approach on tabs management. I honestly really love the "Emacs" tab
management style, but I must recognize most editor are not behaving correctly
with tabs. Consequently, please configure your editor to replace tabs with four
spaces, if you want to share your work.
If, for and while statement are all written in that way:
```shell
# if exemple
if [[ condition ]]; then
something
elif [[ condition ]]; then
something
else
something
fi
# for exemple
for var in range; do
something
done
# while exemple
while condition; do
something
done
```
Case statement will look like this:
```shell
case var in
state1)
something
;;
state2)
something
;;
*)
something
;;
esac
```
Tests have to be done using if. Writing ```[[ test ]] && action``` is not
encouraged, even if I personally think it's a very elegant writing. It makes
reading and comprehension harder for beginners.
A much more accepted behavior is the following two rules with tests:
* Don't write ```[[ $VAR ]]``` to test variable existance, write
```[[ -n $VAR ]]``` instead.
* Don't write ```[[ ! $VAR ]]``` to test if a variable is undeclared, write
```[[ -z $VAR ]]``` instead.
-----------------------------------------------------------------------------
Documentation (c) 2019-2022 Geoffray Levasseur.
This file is distributed under3-clause BSD license. The complete license
agreement can be obtained at: https://opensource.org/licenses/BSD-3-Clause