Files
init.sh/doc/dev.md
2021-10-21 17:19:58 +02:00

428 lines
20 KiB
Markdown

# init.sh developer's reference
## Table of content
- [init.sh developer's reference](#initsh-developers-reference)
- [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 [--force] \<exitcode\>](#212-die---force-exitcode)
- [2.1.3. noerror [--noout] \<command\>](#213-noerror---noout-command)
- [2.2. Other functionalities](#22-other-functionalities)
- [3. The display.sh file](#3-the-displaysh-file)
- [3.1. Functions](#31-functions)
- [3.1.1. prnt [-n] [I|W|E|m] \<message\>](#311-prnt--n-iwem-message)
- [3.1.2. dsleep \<miliseconds\> [char]](#312-dsleep-miliseconds-char)
- [3.1.3. dump_key_buffer](#313-dump_key_buffer)
- [3.2. Other functionalities](#32-other-functionalities)
- [4. The filefct.sh file](#4-the-filefctsh-file)
- [4.1. Functions](#41-functions)
- [4.1.1. stdtime](#411-stdtime)
- [4.1.2. backupdist \<list_of_files_or_dirs\>](#412-backupdist-list_of_files_or_dirs)
- [4.1.3. installfile \<sources\> \<destination\>](#413-installfile-sources-destination)
- [4.1.4. appendfile \<source\> \<destination\>](#414-appendfile-source-destination)
- [4.1.5. isdirempty \<directory\>](#415-isdirempty-directory)
- [4.2. Other functionnalities](#42-other-functionnalities)
- [5. The pkgman.sh file](#5-the-pkgmansh-file)
- [5.1. Global dependencies](#51-global-dependencies)
- [5.2. Functions](#52-functions)
- [5.2.1. pkgupdt](#521-pkgupdt)
- [5.2.2. pkginst \<package_list\>](#522-pkginst-package_list)
- [5.2.3. pkgupgd](#523-pkgupgd)
- [5.2.4. pkgrem \<package_list\>](#524-pkgrem-package_list)
- [5.2.3. pkgupgd](#523-pkgupgd)
- [5.3. Other functionnalities](#53-other-functionnalities)
- [6. The services.sh files](#6-the-servicessh-files)
- [6.1. Global dependencies](#61-global-dependencies)
- [6.2. Functions](#62-functions)
- [6.2.1. exec_serv \<service\> \<command\>](#621-exec_serv-service-command)
- [6.2.2. svc_start \<service1\> [service2 ... serviceN]](#622-svc_start-service1-service2--servicen)
- [6.2.3. svc_reload \<service1\> [service2 ... serviceN]](#623-svc_reload-service1-service2--servicen)
- [6.2.2. svc_restart \<service1\> [service2 ... serviceN]](#622-svc_restart-service1-service2--servicen)
- [6.2.3. svc_stop \<service1\> [service2 ... serviceN]](#623-svc_stop-service1-service2--servicen)
- [6.3. Other functionnalities](#63-other-functionnalities)
- [7. The support.sh file](#7-the-supportsh-file)
- [7.1. Functions](#71-functions)
- [7.1.1. disp_help](#711-disp_help)
- [7.1.2. show_version](#712-show_version)
- [7.1.3. get_mod_name \<module_file\>](#713-get_mod_name-module_file)
- [7.1.4. set_system_proxy](#714-set_system_proxy)
- [8. The version.sh file](#8-the-versionsh-file)
- [8.1. Functions](#81-functions)
- [8.1.1. get_os_version](#811-get_os_version)
- [8.1.2. set_sys_var \<arch\> \<dist\> \<version\> \<codename\>](#812-set_sys_var-arch-dist-version-codename)
## 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\>: writen like this, the parameter is mandatory
* [param]: that parameter is optionnal
* [ab|cd]: optionnal parmeter have to be "ab" or "cd"
* [0..15,20]: acceptable values start at 0 and goes up to 15 or be 20.
## 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 is interrupted
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 display.sh file
### 3.1. Functions
#### 3.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.
#### 3.1.2. dsleep \<miliseconds\> [char]
That function is an equivalent to *sleep* bash command but will display a
countdown every second until it reaches zero. Optionnally a character (or a
string) can be given as a second parameter to replace the countdown by that
character. For exemple, you can use a dot to display a dot every second until
the wait is over.
The function returns nothing useful.
#### 3.1.3. dump_key_buffer
That function dumps 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.
### 3.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 filled with background color.
## 4. The filefct.sh file
### 4.1. Functions
#### 4.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 removed.
That function takes no parameters and return its result on standard output.
#### 4.1.2. backupdist \<list_of_files_or_dirs\>
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.
The function don't take any other parameters than file and/or directory names.
#### 4.1.3. installfile \<sources\> \<destination\>
Install a list of file to the given destination. The source of the file can be
of three different orrigins, from highest to lowest priority:
- **repo/hosts/$HOSTNAME**: this allows to provide system specific configuration
files. Use only relative path to access the file.
- **repo/common**: this one will provide configuration 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.
The priorities applies on file existance. Wildcards are not allowed in file
names, so an error will occurs 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 path do not exists, it
will be created automatically.
#### 4.1.4. appendfile \<source\> \<destination\>
That function add the content of source file to destination file. The source
file can have defferent origins, following the same path priority as the
*installfile* function.
The destination file must exist and be on the root filesystem. Only two
parameters are accepted, the source and destination files.
#### 4.1.5. isdirempty \<directory\>
That function take only one parameter, a path name and return 0 if the given
path don't exists or is empty. It will return one if there's at least one file
in the given directory.
If the given parametter is a file (or a symlink to a file), it will terminate
with an error.
### 4.2. Other functionnalities
That file don't profide any other things that the previously listed functions.
## 5. The pkgman.sh file
### 5.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 nedeed and detailed for every
function. All those variable are defined in a system dependant configuration
file automatically called on script startup.
### 5.2. Functions
#### 5.2.1. pkgupdt
That function calls the package manager to update package database.
It depends on the *COM_UPDATE* variable wich define the parameters to use to
accomplish that function.
That function takes no parameters and any given parameters will be ignored.
#### 5.2.2. pkginst \<package_list\>
That function installs using the package manager the packages given in
parameters. The list of parameters are all considered as package names.
If the *INSTALL_MODE* variable is set to "dev" the package manger will be
called one package after the other. Elsewhere, it will be called once with
the entire package list as parameter.
The function depends on the *COM_INSTALL* variable wich define the parameter
to use to accomplish that function.
#### 5.2.3. pkgupgd
That function calls the package manager to upgrade system.
It depends on the *COM_UPGRADE* variable wich define the parameters to use to
accomplish that function.
That function takes no parameters and any given parameters will be ignored.
#### 5.2.4. pkgrem \<package_list\>
That function uninstalls using the package manager the packages given in
parameters. The list of parameters are all considered as package names.
If the *INSTALL_MODE* variable is set to "dev" the package manger will be
called one package after the other. Elsewhere, it will be called once with
the entire package list as parameter.
The function depends on the *COM_REMOVE* variable wich define the parameter
to use to accomplish that function.
#### 5.2.3. pkgupgd
That function calls the package manager to remove no longer needed installed
dependencies. Any package not manually installed is considered as a depndency.
It depends on the *COM_AUTOREM* variable wich define the parameters to use to
accomplish that functionenfin.
That function takes no parameters and any given parameters will be ignored.
### 5.3. Other functionnalities
That file don't profide any other things that the previously listed functions.
## 6. The services.sh file
### 6.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 offers 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
* **"systemctl %com% %srv%"** for systems using SystemD
* **"service %srv% %com%"** for upstart like scripts (but widely available)
### 6.2. Functions
#### 6.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 acceted and an error will be triggered if there's any more
than two.
The function returns the exit code of the service command.
#### 6.2.2. svc_start \<service1\> [service2 ... serviceN]
Start the services given in parmeters. You can give as many services you want.
That function relies on the previously documented exec_serv function.
#### 6.2.3. svc_reload \<service1\> [service2 ... serviceN]
Reload the configuration of the services given in parmeters. 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.
#### 6.2.2. svc_restart \<service1\> [service2 ... serviceN]
Restart the services given in parmeters. It consist 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.
#### 6.2.3. svc_stop \<service1\> [service2 ... serviceN]
Stop the services given in parmeters. You can give as many services you want.
That function relies on the previously documented exec_serv function.
### 6.3. Other functionnalities
That file don't profide any other thing that the previously listed functions.
## 7. The support.sh file
### 7.1. Functions
#### 7.1.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.
#### 7.1.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 respecting versions.
If user is not root an additionnal warning will be displayed to warn the fact
the script requires root privileges to work properly.
As it's using colors to display results, it depends on color code declaration in
the *display.sh* file.
#### 7.1.3. get_mod_name \<module_file\>
That function return the name of the module file given in parameter. It takes
only one parameter: the module file name.
Result is sent to *stdout*.
#### 7.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.
That function takes no parameters and only change *http_proxy* and *https_proxy*
standard POSIX variables. No usefull result will be returned.
## 8. The version.sh file
### 8.1. Functions
#### 8.1.1. get_os_version
That function takes no parameters and will return three values in order:
1. Distribution ID, in lowcase, usually equivalent to the distribution name.
2. Distribution version, if available, elsewhere kernel version with it's major.
3. Distribution codename (eg. 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 analysed. Only the *ID* variable is mandatory.
#### 8.1.2. set_sys_var \<arch\> \<dist\> \<version\> \<codename\>
That function sets important variable that will store the system architecture.
It will allow the automatic loading of mandatory system dependent code and
variables. For debugging purpose it will be possible to call it manually.
Inside the init.sh initiallisation, 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 (eg. x86_64, i386, arm64...)
2. Distribution name (eg. debian, centos, ubuntu...)
3. Distribution version (or kernel version for rolling releases)
4. Distribution codename if available (eg. jessie, buster, bulleyes...)
If your distribution do not provide any codename, 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 codename
The *SYS_CODE* variable won't be set if your distribution provides no codename.