I have opted to combine most/all of the CORE install scripts created by community members into one collection, and have modified them with the following additions/subtractions.
NOTE All previous “Scripted Install” resources have now been merged into this repo.
They are now to be installed inside a jail, as opposed to running the script on the host system.
They can be installed in any jail using any jail manager, which removes the necessity to be running iocage.
Mount points and jail properties now have to be manually set (command examples included) by the jail manager before entering the jail and running the script. Mount points are now optional, but still recommended. Jail properties (if applicable) are mandatory.
This was done to bypass the need to learn any one jail managers template/plugin system. It allows users to use the jail manager of their choice, expanding the scope of this project to beyond TrueNAS CORE and iocage.
To help with this effort. Please see the attached script-writer helper script I created.
EXAMPLE
$ ./src/script-writer.sh install ACME start ACME
Will produce the output:
#!/bin/sh
# ------------------------------------------------
# Bail out if we don't have root privileges.
if [ $(id -u) -ne 0 ]; then
echo "This script must be run as root."
exit 1
fi
echo "Installing package: ACME"
pkg install -y ACME
echo "Starting service: ACME"
sysrc ACME_enable="YES"
service ACME onestart
Your scripts–the ones with user variables–could benefit from the
addition of a switch/case statement parser. In this form, defaults are
established but the user can override the variables on execution if
they need (without having to edit the actual script; thus, not needing
an editor).
My point can be demonstrated with the following example.
Call example script with the following: ./oldMcDonald.sh
which will just output the defaults. but ./oldMcDonald.sh dog quack
will output a silly doggy.
A dog says: quack
A cow says: Moo
A cat says: Meow
HOWEVER, this does not cover the situation where incorrect input is
given. -i.e. there is ZERO error checking in this example.
-e.g. ./oldMcDonald.sh dog cat would output:
A dog says: cat
A cow says: moo
A cat says: meow
In this case you could develop a quick configure script to modify
the script with sed, but this requires a two (2) step process to run
a script. -e.g. ./configure ; ./oldMdDondald.sh which will eliminate
the need for the end user to use an editor but the syntax is slightly
more cumbersome. I can help you with the configure script if you want.
warning: typed blindly and not tested (typed on a windows machine).
#!/bin/sh
#: OldMcDonald.sh
# Establish default actions for Old McDondald's farm animals.
dog="Bark"
cow="Moo"
cat="Meow"
# Allow script arguments and account for upper and lower case
# arguments.
for item in "$@"
do
case "$item" in
dog | DOG) {
dog="$2";
shift; } ;;
cow | COW) {
cow="$2";
shift; } ;;
cat | CAT) {
cat="$2";
shift; } ;;
*) shift ;;
esac
done
# Report the results.
printf "A dog says: %s\nA cow says: %s\nA cat says: %s\n" ${dog} ${cow} ${cat}
It would not be necessary to use sed. You could also just have a config file in the same directory as the script that would be sourced for variables after the script variables are loaded.
Some of the scripts require ~ 5 ~ variables.
It would be a good idea to implement something like that so users don’t have to modify the actual script.
Sure, but that situation gets a bit complicated: You could just source the config file in the script but I also went down the path of actually parsing the config file (for error checking). You could tar.gz the script and config file and fetch that instead of just the script.
How I did the parsing config files in my jcreate concept script. Take a look at the src directory and the two files: jcreate.conf and jcreate.sh.
But to save you a bit of time here is essentially how I implemented a more robust config file parser into my script.
config file looks like:
variable.name="value"
In your script you have to perform a few checks (it gets a bit long-winded checking and whatnot, but the system works well):
# config_read_file ---
# Read a file and look for a value.
# XXX:
# 1. Return 0 instead of string.
config_read_file() {
(grep -E "${2}=" -m 1 "${1}" 2>/dev/null || echo "VAR=__UNDEFINED__") | head -n 1 | cut -d '=' -f 2-;
}
# cofig_get ---
# A wrapper. Call `config_read_file` and set the variable value.
config_get() {
val="$(config_read_file "${2}" "${1}")";
printf -- "%s" "${val}";
}
# Locate our configuration file.
# NOTE:
# 1. location to find (example: .)
# 2. The name of the file to find (example: "create.conf").
_conf="$(find . -type f -name 'create.conf')"
# Get variable "variable.name" from the "create.conf" file.
variable_name="$(config_get variable.name $_conf)"
# Check to see if we have that variable value.
if [ "${variable_name}" = __UNDEFINED__ ]; then
# if we've not found a value, then exit.
echo "**ERROR** \"variable.name\" value not found in create.conf"
exit 1
fi