2025-09-25 21:55:06 +02:00
2022-06-24 17:52:17 +02:00
2025-09-25 22:13:30 +02:00
2025-09-25 22:02:48 +02:00
2021-09-29 10:56:23 +02:00
2022-06-24 17:52:17 +02:00
2025-09-24 17:24:55 +02:00
2021-09-15 12:18:27 +02:00
2025-09-24 15:41:04 +02:00

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

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.

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 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:

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.

# ------------------------------------------------------------------------------
# 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 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
20 Ambigous realm with autodetection
21 Unconsistant directory structure with configured realm
22 Required secret management software missing
23 Secret key not found in secret database
24 File is not readable
25 Needed variable not set or not declared
26 Secret reference missing or malformed
27 Unknown secret reference
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 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, 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. 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-2025 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

Description
init.sh is a small scalable system configurator
Readme BSD-3-Clause 894 KiB
Languages
Shell 100%