# Contribute to AutoPilot script
In this page I will walk you trough how to contribute to AutoPilot script.
# Prerequisites
- AutoPilot forked (opens new window) on your GitHub account.
- Text editor.
- Some sort of VM setup (optional).
# Make changes
There are several functions you need to know before making any changes:
- xecho:
Every time you want toecho
something you need to use the following format:Here are all the prefixes variables available:xecho "$[Choosen prefix] <biw>[Text data]<biw>"
$info_prefix
- Anything that doesnt indicate something.$good_prefix
- Something good happend.$notgood_prefix
- Something not good happend but nothing crucial happend.$bad_prefix
- Something bad happend. (e.g. an error) For example:
If I wanted to notify the user that what ever I wanted to happend succeeded, I would use something like this:
xecho "$good_prefix <biw>What ever I wanted to happen happend.</biw>"
TIP
For extended explenation on the
xecho
function, refer here (opens new window)You still have to format all text to be bold intense white.
- fail:
When you want to exit the script, you would have to cal thefail
function. Here's the syntax:For example:fail [EXIT CODE] "[TEXT DATA]"
fail 1 "File not found."
- check_dependencies:
When you want to install a new dependencie for what ever reason, you would usecheck_dependencies
:For example:check_dependencies "[Dependency name]" "$notgood_prefix <biw>[TEXT DATA]</biw>" "[CMD TO INSTALL]" "[TEST AFTER INSTALL]"
check_dependencies "network-manager" "$notgood_prefix <biw>Dependency missing, trying to install network-manager.</biw>" "apt install -yq network-manager &> /dev/null" "which nmcli"
WARNING
I do not recommend adding dependencies to AutoPilot.
- parse_yaml:
Like you probably know, AutoPilot uses YAML for its configuration files, this fuction is meant for you to parse new YAML easly.Extract Keys from a List or Dictionary:
parse_yaml keys "yaml_path" "sub_key"
yaml_path
: Path to the YAML list or dictionary.sub_key
: Sub-key within the items to extract (optional).
Example:
parse_yaml keys "items" "name"
This command will list all names in the
items
list to STDOUT.Extract a Single Value:
parse_yaml 0 "yaml_path"
yaml_path
: Path to the YAML value.
Example:
parse_yaml 0 "SELinux"
This command retrieves the value at
SELinux
and assigns it to a variable named like theyaml_path
.Extract a List of Values to an Array:
parse_yaml 1 "yaml_path"
yaml_path
: Path to the YAML list.
Example:
parse_yaml 1 "names"
This command extracts all items from
names
and stores them in an array named like theyaml_path
.Extract Key-Value Pairs to an Associative Array:
parse_yaml 2 "yaml_path" "key_path" "value_path"
yaml_path
: Path to the YAML list.key_path
: Path to the key within the items.value_path
: Path to the value associated with each key.
Example:
parse_yaml 2 "items" "name" "value"
This command extracts key-value pairs where the keys are from
name
and the values are fromvalue
, storing them in an associative array named like theyaml_path
.Extract Key-Value Pairs with Two Values per Key:
parse_yaml 3 "yaml_path" "key_path" "value1_path" "value2_path"
yaml_path
: Path to the YAML list.key_path
: Path to the key within the items.value1_path
: Path to the first value associated with each key.value2_path
: Path to the second value associated with each key.
Example:
parse_yaml 3 "config.items" "name" "value1" "value2"
This command extracts key-value pairs where each key from
name
has two associated values fromvalue1
andvalue2
.
To access the data use something like this:parse_yaml 3 Installed_packages name type source if [ "${#Installed_packages[@]}" -ne 0 ]; then IP_keys=($(tr ' ' '\n' <<< "${!Installed_packages[@]}" | grep -Ev '\[(0|1)\]' | sort -u)) for pkg in "${IP_keys[@]}" do pkg_type="${Installed_packages["$pkg [0]"]}" pkg_source="${Installed_packages["$pkg [1]"]}" fi
This was the YAML:
Installed_packages: Installed_packages: - name: AnyName type: Deb/Pkg/Sh source: Deb name/Package url/Script url
Extract Key-Value Pairs with Three Values per Key:
parse_yaml 4 "yaml_path" "key_path" "value1_path" "value2_path" "value3_path"
yaml_path
: Path to the YAML list.key_path
: Path to the key within the items.value1_path
: Path to the first value associated with each key.value2_path
: Path to the second value associated with each key.value3_path
: Path to the third value associated with each key.
Example:
parse_yaml 4 "config.items" "name" "value1" "value2" "value3"
This command extracts key-value pairs where each key from
name
has three associated values fromvalue1
,value2
, andvalue3
.
To access the data use something like this:parse_yaml 4 Users name pass group shell if [ "${#Users[@]}" -ne 0 ]; then U_keys=($(tr ' ' '\n' <<< "${!Users[@]}" | grep -Ev '\[(0|1|2)\]' | sort -u)) for user in "${U_keys[@]}"; do userpass="${Users["$user [0]"]}" usergrp="${Users["$user [1]"]}" usershell="${Users["$user [2]"]}" fi
This was the YAML:
Users: - name: USERNAME pass: PASSWORD/%Gen% group: GROUP1,GROUP2,GROUP3 shell: /path/to/shell
TIP
In general AutoPilot uses utils.sh (opens new window) heavily, it is recommend that you learn how to use its functions before adding something to AutoPilot. (Link to docs (opens new window))
Now that you know the basic functions needed to add/change something in AutoPilot, you need to understand the stracture of AutoPilot.
Since AutoPilot revolves around directives each directive has its own function with the same name, but with a prefix of rn_
(rn_el
for RHEL version of a function), for example:
SomeDirective: Yes
## SomeDirective
function rn_SomeDirective {
parse_yaml 0 SomeDirective
xecho "$info_prefix <biw>Called SomeDirective, $SomeDirective. {{ E-smile }}</biw>"
}
function rn_el_SomeDirective {
parse_yaml 0 SomeDirective
xecho "$info_prefix <biw>Called SomeDirective, $SomeDirective. {{ E-smile }}</biw>"
}
That is so it can be called when it is mentioned in the configuration file via this part of the script:
## Execute functions
for key in "${keys[@]}"
do
if [[ ! "$key" =~ ^("Running_OS")$ ]]; then
if [ "$Running_OS" == "Debian" ]; then
rn_$key
else
rn_el_$key
fi
fi
done
TIP
Naming a function like a directive in the configuration file (With the rn_
prefix) only calls the function, to also retrieve any data from the directive use the parse_yaml
function.
# Test changes
Test the newly added changes by running the script either on your personal computer (if applicable) or a virtual machine.
It's highly recommended to use some form of VM setup, to not harm your personal environment.
TIP
I would suggest using Vagrant (opens new window), as it enables the creation of lightweight, reproducible, and portable development environments.
Using a VM also enables me as the developer a way to recreate the exact circomstances you had while encountering an issue/bug, so you could ask for a helping hand 😁.
# Send a PR
After making changes to the AutoPilot script, push to your AutoPilot fork then send a PR with detailed explenation of the changes you've made or any other valuable information, for example:
# Added Users directive
I've added the Users directive, It's responsable for adding users.
Here's the syntax for the configuration file:
Users:
- name: USERNAME
pass: PASSWORD/%Gen%
group: GROUP1,GROUP2,GROUP3
shell: /path/to/shell
For example:
Users:
- name: Noam
pass: 1234
group: Noam,sudo,admins
shell: /bin/bash
### Notes
- one
- two
- three
Huge thank you to anyone willing to contribute! 🙏