399 lines
19 KiB
Markdown
399 lines
19 KiB
Markdown
# init.sh
|
|
**init.sh** is an automated configuratinon software for system administrators.
|
|
It's fully written using Bash scripting and aims to be platform independent.
|
|
Nevertheless, its requirements turn it naturally to Linux systems. It has long
|
|
been tested using Debian GNU/Linux, Devuan and different flavors of Ubuntu.
|
|
|
|
## Table of content
|
|
- [init.sh](#initsh)
|
|
- [1. Getting started](#1-getting-started)
|
|
- [2. Why init.sh?](#2-why-initsh)
|
|
- [3. Design](#3-design)
|
|
- [3.1. Command line](#31-command-line)
|
|
- [3.2. Loading order and process](#32-loading-order-and-process)
|
|
- [3.4. Naming conventions](#34-naming-conventions)
|
|
- [3.5. Basic module structure](#35-basic-module-structure)
|
|
- [4. Error code table](#4-error-code-table)
|
|
- [5. Contact and more information](#5-contact-and-more-information)
|
|
- [5.1. New users](#51-new-users)
|
|
- [5.2. Bugs](#52-bugs)
|
|
- [5.3. How to contribute?](#53-how-to-contribute)
|
|
- [5.4. Website and maintainor](#54-website-and-maintainor)
|
|
|
|
## 1. Getting started
|
|
You should consider reading that document entirely before use. If you need
|
|
to create additional modules to meet your needs, consider reading the
|
|
[Developer's guide](./doc/dev.md).
|
|
|
|
Please also consider that your needs might meet the needs of someone else, thus
|
|
it would be a good idea to submit your module to init.sh source base.
|
|
|
|
## 2. Why init.sh?
|
|
Short answer: why not?
|
|
|
|
Long answer: Even if I value tools like Puppet or Ansible, I always thought that
|
|
such great and complex systems are very nice for big infrastructures. But, on a
|
|
much smaller scale like small business, or if you require something fast to
|
|
deploy and easy to adapt to your needs, such great tools are somehow
|
|
overkilling.
|
|
|
|
I wanted something simple and as universal as possible to manage many unique
|
|
servers in my small local foundations. I started with a lot of long hard-coded
|
|
monolithic scripts where I had to rewrite many things on every new
|
|
infrastructures I wanted to manage. As it was a fastidious job, I started to
|
|
rewritte and redesign everything with a common architecture and code, modular
|
|
and easily adaptive. As I don't know any tools in that market scale, I decided
|
|
to publish and share that work, in the hope it can be useful.
|
|
|
|
## 3. Design
|
|
**init.sh** relies on three different elements to work:
|
|
|
|
- The ```init.sh``` script and libraries, which provide a simple framework to do
|
|
simple tasks and embed system dependent tools to provide system independent
|
|
function calls.
|
|
- Modules that actually do the job, as possible on a system independent way
|
|
through the use of the framework, and consisting of very small and simple tasks.
|
|
- Multilevel configuration files, being simply Bash variables declaration.
|
|
|
|
Additionally, some module might be run regularly, so it could be integrated in a
|
|
cron-like service using the provided cron mode with the benefits of ```init.sh```
|
|
structure and libraries.
|
|
|
|
### 3.1. Command line
|
|
|
|
The **init.sh** script allows some command line parameters and some environment
|
|
variables to change its behavior.
|
|
|
|
The parameters are:
|
|
|
|
- **-f \<file\>, --file \<file\>**: Allows specifying which configuration file
|
|
to load manually. That option can be repeated to allow the loading of multiple
|
|
configuration file, the last overloading the previously defined ones in case of
|
|
identical variable name.
|
|
- **-m \<list\>, --module \<list\>**: Allows to manually give a module list and
|
|
override the ```MODULE_LIST``` variable declaration. The list is a comma
|
|
separated module name. If that option is provided, the module list is mandatory.
|
|
- **-c, --check-only**: Do not launch any actions, only the checks are launched.
|
|
In that situation, no change should be done to the system.
|
|
- **-j, --jump**: Jump the checks and goes directly to system transformation.
|
|
That option should only be run after successful checks (e.g., after using the
|
|
\--check-only option).
|
|
- **-k, --keep-going**: The scripts will try to continue even if errors occurs.
|
|
Thus, some unrecoverable errors might stop the script anyway if it's not
|
|
allowing it to work. Please use with care as it might lead to unexpected
|
|
results.
|
|
- **-r, --resume**: Restart an interrupted process with the last executed module
|
|
that failed.
|
|
- **-R, --no-root-check**: Disable checks on root rights (or the 0 UID).
|
|
- **-D, --no-deps**: Disable module dependencies checks.
|
|
- **-P, --no-proxy**: Do not hot apply proxy setting to the running system, even
|
|
if system proxy is set in configuration files.
|
|
- **-h, --help**: Display information on command line usage.
|
|
- **-s, --shell**: Launch a shell with entire script's environment for
|
|
debugging purpose. No action or modification is made to the system unless you
|
|
launch commands manually doing some.
|
|
- **--chroot \<path\>**: Allows you to apply init.sh test or modification on a
|
|
non-running system, mounted in the given path.
|
|
- **--cron**: execute init.sh in cron mode. Check [cron subsystem
|
|
documentation](./doc/cron.md)
|
|
for more details.
|
|
- **-l, --logfile**: Specify a custom name for the log file. Standard log file
|
|
is named init-hostname-date-time.log in the log subdirectory. That file can also
|
|
be customized using the ```LOGFILE``` environment variable.
|
|
- **-v, --version**: Display version information, including available module
|
|
list and their version.
|
|
|
|
The options cannot be concatenated like most of Unix binaries allows. For
|
|
example, you cannot write ```-rR```, you have to write ```-r -R```.
|
|
|
|
### 3.2. Loading order and process
|
|
|
|
The first thing the script do is loading its libraries contained in the "*lib*"
|
|
directory. Any file situated in that directory ending with the .sh extension
|
|
will be loaded in alphabetical order. For that reason, error management
|
|
functions are placed in a file called aaa_error.sh, so it can be loaded first
|
|
and catch errors that could occur while loading other library files.
|
|
|
|
After that, a basic command line parameter treatment will be done. That allows
|
|
the use of ```--version``` and ```--help``` options in user space. Those options
|
|
display information and don't require any superuser rights, and exit at that
|
|
point of execution. Everything after that will require administrator rights and
|
|
the script will exit with error at that point if not superuser, unless the
|
|
```--no-root-check``` option was given.
|
|
|
|
Next will be the log file creation and the loading of configuration files.
|
|
Configuration files exist in two distinct categories. First system dependent
|
|
configuration will be loaded automatically depending on your platform, then
|
|
your own configuration. At this point, a deeper analysis of command line option
|
|
will be done, triggering errors in case of inconsistency or incompatible
|
|
options.
|
|
|
|
After that, all the configured modules with the ```$MODULE_LIST``` variable are
|
|
loaded to be available for execution. Note that even function that might not be
|
|
used will be loaded. At this point, everything that will be necessary for checks
|
|
and modification will be available in the scripts' execution environment. If the
|
|
```--shell``` command line option was given, the sub-shell is loaded just after
|
|
this point.
|
|
|
|
Finally, checking processes are launched in their declaration order (cf.
|
|
configuration file). A module dependency check is made prior to the module specific
|
|
checks unless the ```--no-deps``` option was given or if a manual module list
|
|
was transmitted. If no error occurs and after a confirmation prompt, final
|
|
treatment processes, those that actually makes changes, are launched.
|
|
|
|
Without the ```--keep-going``` option, any error will immediately stop execution.
|
|
Some errors that could make the script impossible to execute will stop
|
|
execution, even if the ```--keep-going``` option was provided.
|
|
|
|
### 3.3. Configuration files
|
|
#### 3.3.1. Main configuration file
|
|
|
|
The main configuration file can be two different files. Either it's completely
|
|
generic and will be named **init.conf.sh** in the ```conf``` directory, either
|
|
it will be named after the current hostname of the computer in that same
|
|
```conf``` directory. Please remember that the actual name will be used until
|
|
the end of the execution of init.sh. If one of your module change the hostname,
|
|
the new name can only be taken into account after a new execution of **init.sh**.
|
|
|
|
Most of the variable you can declare to configure your host depends on the
|
|
module you will use. Please refer to module header to see what's available for
|
|
your use case.
|
|
|
|
After a module version upgrade, you should check again headers as variable name
|
|
or structure might change. A variable can also be deleted, new variables could
|
|
appear, and so on.
|
|
|
|
It is heavily recommended to use includes technique to shorten your
|
|
configuration file and make a file for your organization and another one
|
|
for the Linux distribution you use. Remember that the declaration order matters,
|
|
so you can declare something in your organization configuration file and
|
|
supersede it in your host configuration file. The only limit will be Bash
|
|
capabilities in terms of variable manipulation.
|
|
|
|
#### 3.3.2. Automatically loaded configuration files
|
|
Those files are basically the system dependent part that assure compatibility
|
|
with different Linux distributions. Some of those files are shipped with
|
|
init.sh, but you can add what you want to improve possibilities or to add
|
|
support for a new distribution. init.sh understand the following possibilities
|
|
in terms of OS detection:
|
|
|
|
| Name | Variable | Description |
|
|
|:------------|:---------------|:----------------------------------------------|
|
|
| **arch** | ```SYS_ARCH``` | This is the system architecture, like x86_64, i386, arm64, etc. |
|
|
| **dist** | ```SYS_DIST``` | The name of the Linux distribution as reported by */etc/os-release*. |
|
|
| **version** | ```SYS_VER``` | Version of the distribution. If you run a rolling release and no version is provided by your */etc/os-release* file, the main version of the Linux kernel will be used (e.g. 5.4 for any version of 5.4.x kernel branch). |
|
|
| **codename**| ```SYS_CODE``` | If your distribution provide a version codename, it will be set with it, elsewhere it will remain unset. |
|
|
|
|
The configuration files loads if exists in the following order:
|
|
1. arch.conf.sh
|
|
2. distro.conf.sh
|
|
3. distro-arch.conf.sh
|
|
4. distro-version.conf.sh
|
|
5. distro-codename.conf.sh (only if ```$SYS_CODE``` defined)
|
|
6. distro-version-arch.conf.sh
|
|
7. distro-codename-arch.conf.sh (only if ```$SYS_CODE``` defined)
|
|
|
|
The loading of those files, if one exists, cannot be avoided. They all must be
|
|
located in the ```conf/auto``` directory of the init.sh tree.
|
|
|
|
### 3.4. Naming conventions
|
|
|
|
Because of internal mechanics, the dash character is forbidden in module names.
|
|
Thus, Bash language also forbid that character in variable name.
|
|
|
|
Another limit is, even if digits are allowed in module names and variable, they
|
|
can't be used as a leading character or worse the full name only made of digits.
|
|
You can use as many digits you want in names, but with at least a leading
|
|
alphabetical (or underscore) character, whatever the case of that character will
|
|
be.
|
|
|
|
You can use upper case and lower case as you wish, with underscore character,
|
|
even as leading character. Any other special character than alphanumerical or
|
|
underscore is completely forbidden.
|
|
|
|
Any submitted module to the central repository will have module name in lower
|
|
case with underscore to separate words and ease reading, and variable name upper
|
|
case (except local variables) with the same underscore as word separator.
|
|
|
|
### 3.5. Basic module structure
|
|
|
|
Please note that modules are not supposed to contain any specific code for a
|
|
platform or a distribution, even if nothing block you doing so. It is highly
|
|
recommended to use automatic configurations files to introduce any platform
|
|
dependent code and variables. Additionally, it will be possible to create system
|
|
dependent modules using naming convention in the style
|
|
```module_name.debian.x86_64.sh``` (awaited for version 2 of init.sh).
|
|
|
|
In the following example, ```@template@``` have to be replaced with the name of
|
|
your module with the filename ```@template@.sh```. You can automatically create
|
|
your new module with the following command:
|
|
|
|
```shell
|
|
sed -e "s/@template@/module_name/g" -e "/^# .*/d" -e "s/^##/# /" template > \
|
|
module_name.sh
|
|
```
|
|
|
|
Versioning modules is up to you, but the recommended behavior follows some
|
|
standard rules, not artificially increasing version numbers in a stupid fight of
|
|
who will have the biggest, like Google or Firefox. Considering a numbering as
|
|
x.y.z:
|
|
|
|
- x might increment in case of major change, rewriting or different approach on
|
|
the way to have the job done, the used variable could massively change and
|
|
jeopardy compatibility;
|
|
- y might increment in case of simple functionality addition or basic
|
|
improvements, existing variable might not change, but new ones could appear;
|
|
- z might increment only when correcting problems and/or bugs (+n fix ⇒ +n to
|
|
increment), variable should not change unless this is the only way to fix a
|
|
problem.
|
|
|
|
Unless only configuration files has changed, any change in the code implies an
|
|
increment of a version number in the code **and** a "git" commit.
|
|
|
|
```shell
|
|
# ------------------------------------------------------------------------------
|
|
# Description @template@ module
|
|
# Copyright (c) Year Your Name <your.mail@host.tld>
|
|
# ------------------------------------------------------------------------------
|
|
# <License header compatible with BSD-3 license, you want to use>
|
|
# ------------------------------------------------------------------------------
|
|
# Variable list:
|
|
# * <VARNAME>: role explanation
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Module version
|
|
export VER_@template@="0.0.1"
|
|
|
|
# Module dependencies (contains other module names if dependencies exists)
|
|
export DEPS_@template@=""
|
|
|
|
# Module main code
|
|
@template@()
|
|
{
|
|
: # Code
|
|
}
|
|
|
|
# Pre-run checks code
|
|
precheck_@template@()
|
|
{
|
|
: # Code
|
|
}
|
|
|
|
# Optionnally, cron mode code
|
|
cron_@template@()
|
|
{
|
|
: # Code
|
|
}
|
|
|
|
# Any public function have to be exported
|
|
export -f @template@
|
|
export -f precheck_@template@
|
|
|
|
# If cron_@template@ exists:
|
|
export -f cron_@template@
|
|
```
|
|
|
|
Unexported template function will not work as any module execute in a sub-shell
|
|
in order to protect ```init.sh``` script environment.
|
|
|
|
The optional ```cron_@template@``` function allows you to define code that will
|
|
be executed in cron mode. Check [cron documentation](./doc/cron.md) for more
|
|
details.
|
|
|
|
|
|
## 4. Error code table
|
|
|
|
The following table is giving a list of error codes with explanation:
|
|
|
|
| Code | Meaning |
|
|
|:----------|:------------------------------------------------------------|
|
|
| 0 | No error |
|
|
| 1 | Command line syntax error or incompatible options |
|
|
| 2 | Misuse of Bash built-in |
|
|
| 3 | Missing library file or function |
|
|
| 4 | No root rights |
|
|
| 5 | Malformed module list |
|
|
| 6 | Unable to find configuration |
|
|
| 7 | Misuse of script internal function |
|
|
| 8 | Can't determine OS type or version |
|
|
| 9 | Unsatisfied dependency |
|
|
| 10 | File missing or empty |
|
|
| 11 | Bad function call |
|
|
| 12 | Error copying files |
|
|
| 13 | Bad target file system |
|
|
| 14 | Impossible to chroot |
|
|
| 15 | Bad chrooted installation, destination OS needs to be fixed |
|
|
| 16 | Invalid options provided with cron mode activated |
|
|
| 17 | Missing or invalid status file, can't resume |
|
|
| 18 | Module file don't exists or is empty |
|
|
| 50..100 | Error in module execution |
|
|
| 126 | Command exists but is not executable |
|
|
| 127 | Command not found |
|
|
| 128 | Abortion due to external cause |
|
|
| 150..200 | Error in module checks |
|
|
| 255 | Exit status out of range |
|
|
|
|
Additionally to exit codes, the script will try to produce a call stack to help
|
|
you in the debugging process. If you find a bug outside modules or in the basic
|
|
provided module, please contact the author. Of course, if you also have a patch,
|
|
your mail will be even more welcomed!
|
|
|
|
You can check [error fixing documentation](./doc/errors.md) to obtain help on
|
|
how to solve problems.
|
|
|
|
## 5. Contact and more information
|
|
### 5.1. New users
|
|
This project is very new in terms of publication, and I have no idea of who will
|
|
use it, if any does. If you use (or plan to use) ```init.sh```, I'll be very
|
|
happy if you simply mail me to let me know, especially if you don't plan to
|
|
contribute. If you plan to contribute, I'll be twice happier for sure!
|
|
|
|
### 5.2. Bugs
|
|
**init.sh** have no bug tracker yet. For now, if you find a bug, please submit a
|
|
bug report to the maintainer mentioned at the end of that document. A bug report
|
|
may contain the command line parameters where the bug happens, OS details,
|
|
the module that trigger it, if any, and the log file containing the error.
|
|
|
|
Please check the to-do list before sending any report, as the problem might
|
|
already be known.
|
|
|
|
### 5.3. How to contribute?
|
|
You are free to improve and contribute as you wish. If you have no idea what to
|
|
do or want some direction, you can check the [to-do list](./doc/todo.md),
|
|
containing desired future improvements. Make sure you always have the latest
|
|
development version before starting your work.
|
|
|
|
It's heavily recommended to use git to obtain the latest copy of init.sh tree.
|
|
Make sure your git configuration is correct in order to contribute. Please
|
|
contact me to obtain push authorizations, or, if you want to submit a patch, you
|
|
can send it by mail to the maintainer of init.sh.
|
|
|
|
You can improve anything you want, but keep in mind init.sh have to stay small
|
|
and simple. If your idea cannot be written using Bash scripting, maybe that
|
|
means you're going too far in the improvement.
|
|
|
|
Code written in Python or Perl might be accepted as long as it's not mobilizing
|
|
a lot of dependencies (forget big framework). Anything that need the
|
|
installation of packages not provided in minimal Debian installation will be
|
|
rejected in the libraries. For module, the KISS philosophy is the one promoted.
|
|
Anyway, core scripts will remain in Bash whatever the evolutions of
|
|
```init.sh``` will be.
|
|
|
|
If you want to make a financial contribution, please contact me by mail.
|
|
|
|
### 5.4. License, website, and maintainer
|
|
Everything except configuration files is licensed under BSD-3 license. Please
|
|
check license file allong this one.
|
|
|
|
Please check [https://www.geoffray-levasseur.org/init](https://www.geoffray-levasseur.org/init).
|
|
Note that this website is still under construction and needs some more care.
|
|
|
|
You can mail author to fatalerrors \<at\> geoffray-levasseur \<dot\> org.
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
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
|