Built and documented more logic functions, started an exit codes help section adding exit codes as I go. Ceated a tester script for testing logic functions from functions.lib.sh without the need to run the entire code base.

This commit is contained in:
2026-04-02 10:21:29 +02:00
parent 1c648f2739
commit 38562c1d55
7 changed files with 758 additions and 36 deletions

View File

@@ -1,7 +1,122 @@
## DebMirror Manager Actions Library ## DebMirror Manager Actions Library
# doAddRepo (Busy)
# doEditRepo
# doHelper
# doHelperAdd
# doHelperEditRepo
# doHelperExitCodes
# doHelperListRepos
# doHelperQuietSyncRepos
# doHelperRemoveRepo
# doHelperRepoUsage
# doHelperShowRepo
# doHelperSyncRepos
# doHelperTestRepo
# doHelperUpdater
# doLicense
# doQuietSyncRepos
# doRepoUsage
# doShowRepo
# doSyncRepos
# doTestRepo
# doUpdater
function doAddRepo { function doAddRepo {
echo "Add Repo" local architecture
local debinst
local distribution
local keyring
local keyringurl
local localrepo
local method
local prettyname
local remotefqdn
local remoterepo
local section
local sources
echo -en "What is the FQDN for the repo server you want to mirror? "
read -r remotefqdn
[[ "${remotefqdn}" =~ ^([a-z0-9](-?[a-z0-9])*\.)+[a-z]{2,}$ ]] || funcError "Not a valid FQDN..."
nslookup "${remotefqdn}" > /dev/null 2>&1 || funcError "FQDN does not resolve to an IP address..."
echo -en "What is the name of the repo on ${remotefqdn} you want to mirror? "
read -r remoterepo
[[ "${remoterepo}" =~ ^[a-z0-9]+([a-z0-9-]*[a-z0-9])?$ ]] || funcError "Invalid repo name...\nMust use lowercase letter, digits and/or dash - (dash can not be the first or last character)..."
echo -en "What is the name you want to use for the repo on your local mirror server ${localfqdn}?\n(Press ENTER to use ${remoterepo}) "
read -r localrepo
if [[ -z "${localrepo}" ]]; then
localrepo="${remoterepo}"
fi
[[ "${localrepo}" =~ ^[a-z0-9]+([a-z0-9-]*[a-z0-9])?$ ]] || funcError "Invalid repo name...\nMust use lowercase letter, digits and/or dash - (dash can not be the first or last character)..."
echo -en "What is the name of the section(s) on ${remotefqdn}/${remoterepo} that you want to mirror?\n(Use a comma , as a delimeter if you want to use more than one - no spaces) "
read -r section
[[ "${section}" =~ ^([a-z0-9]+([a-z0-9-]*[a-z0-9])?)(,([a-z0-9]+([a-z0-9-]*[a-z0-9])?))*$ ]] || funcError "Invalid section(s) name(s)...\nMust use lowercase letter, digits and/or dash - (dash can not be the first or last character)...\nYou can use a comma , as a delimiter for multiple sections, but no spaces..."
echo -en "What is the name of the distribution(s) on ${remotefqdn}/${remoterepo} that you want to mirror?\n(Use a comma , as a delimeter if you want to use more than one - no spaces) "
read -r distribution
[[ "${distribution}" =~ ^([a-z0-9]+([a-z0-9-]*[a-z0-9])?)(,([a-z0-9]+([a-z0-9-]*[a-z0-9])?))*$ ]] || funcError "Invalid distribution(s) name(s)...\nMust use lowercase letter, digits and/or dash - (dash can not be the first or last character)...\nYou can use a comma , as a delimiter for multiple distributions, but no spaces..."
echo -en "What hardware architecture(s) do you want to mirror? (Use a comma , as a delimeter\nif you want to use more than one - no spaces) "
read -r architecture
[[ "${architecture}" =~ ^([a-z0-9]+)(,[a-z0-9]+)*$ ]] || funcError "Invalid architecture string given...\nMust use lowercase letter, digits and/or dash - (dash can not be the first or last character)...\nYou can use a comma , as a delimiter for multiple architectures, but no spaces..."
echo -en "Must we use HTTPS for the remote repo? (Y/n) "
read -r -n 1 method
if [[ -z "${method}" || "${method,,}" == "y" ]]; then
echo "Using HTTPS..."
method="https"
else
echo "Using HTTP..."
method="http"
fi
echo -en "If this repo requires a GPG key then paste the URL to download it, or just press\nENTER if there is no GPG key. "
read -r keyringurl
if [[ -z "${keyringurl}" ]]; then
echo "No keyring is being used..."
keyring=false
else
echo "Downloading keyring file and saving it to /etc/debmirrorman/${localrepo}.gpg..."
curl -sSLo "/etc/debmirrorman/${localrepo}.gpg" "${keyringurl}" || funcError "Failed to down ${keyringurl}..."
keyring=true
fi
echo -en "Do you want to mirror the Source data and files (y/N) "
read -r -n 1 sources
if [[ -z "${sources}" || "${sources,,}" != "y" ]]; then
echo "Not including Source data..."
sources=false
else
echo "Including Source data..."
sources=true
fi
echo -en "Do you want to mirror the Debian Install data (normally only needed when mirroring\nthe main Debian repos at deb.debian.org) (y/N) "
read -r -n 1 debinst
if [[ -z "${debinst}" || "${debinst,,}" != "y" ]]; then
echo "Not including Debian Install data..."
debinst=false
else
echo "Including Debian Install data..."
debinst=true
fi
echo -en "Choose a memorable name that you can use to identify this repo in the future... "
read -r prettyname
echo "Writing configuration files..."
echo "declare -a localrepos=(" >> "/etc/debmirrorman/settings.conf" || funcError "Failed to write /etc/debmirrorman/settings.conf"
echo " \"${localrepo}\"" >> "/etc/debmirrorman/settings.conf" || funcError "Failed to write /etc/debmirrorman/settings.conf"
echo ")" >> "/etc/debmirrorman/settings.conf" || funcError "Failed to write /etc/debmirrorman/settings.conf"
echo "declare -A prettynames=(" >> "/etc/debmirrorman/settings.conf" || funcError "Failed to write /etc/debmirrorman/settings.conf"
echo " [${localrepo}]=\"${prettyname}\"" >> "/etc/debmirrorman/settings.conf" || funcError "Failed to write /etc/debmirrorman/settings.conf"
echo ")" >> "/etc/debmirrorman/settings.conf" || funcError "Failed to write /etc/debmirrorman/settings.conf"
echo "## Details for ${prettyname}" > "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare remotefqdn=\"${remotefqdn}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare remoterepo=\"${remoterepo}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare section=\"${section}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare distribution=\"${distribution}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare architecture=\"${architecture}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare method=\"${method}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare keyring=${keyring}" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare keyringurl=\"${keyringurl}\"" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare sources=${sources}" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "declare debinst=${debinst}" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo "## This file was last updated on $(date)" >> "/etc/debmirrorman/${localrepo}.repo" || funcError "Failed to write /etc/debmirrorman/${localrepo}.repo"
echo
exit exit
} }
@@ -25,6 +140,54 @@ function doHelperEditRepo {
exit exit
} }
function doHelperExitCodes {
echo "${TITLE} Documentation - Exit Codes"
echo
echo "Use up and down arrows to scroll or press Q to exit"
echo
echo " No Errors"
echo " 0 - Completed and exited with no errors"
echo
echo " Command Errors"
echo " 1 - Command not valid"
echo " 2 - Command does not support a local repo name"
echo " 3 - Command requires a local repo name"
echo " 4 - Local repo name is not valid"
echo " 5 - Local repo name is not found in ${etcdirectory}/settings.conf"
echo " 6 - Local repo file is not found in ${etcdirectory}"
echo " 9 - Unknown error with local repo"
echo
echo " Help Errors"
echo " 11 - No help documentation available for invalid command"
echo " 12 - No help documentation available for command"
echo
echo " Configuration Errors"
echo " 21 - ${etcdirectory}/settings.conf does not exist"
echo " 22 - No \${localfqdn} defined in ${etcdirectory}/settings.conf"
echo " 23 - Invalid \${localfqdn} defined in ${etcdirectory}/settings.conf"
echo " 29 - Unknown error loading ${etcdirectory}/settings.conf"
echo
echo " Adding Repo Errors"
echo " 31 - No local repo name given"
echo " 32 - Given local repo name is invalid"
echo " 33 - Given local repo name already exists in ${etcdirectory}/settings.conf"
echo " 34 - There is already a file {localreponame}.repo in /etc/debmirrorman"
echo " 35 - No pretty name given"
echo " 36 - No remote FQDN given"
echo " 37 - Given remote FQDN is invalid"
echo " 38 - Given remote FQDN does not resolve to an IP address"
echo " 39 - No remote repo name given"
echo " 40 - Given remote repo name is invalid"
echo " 41 - No section name given"
echo " 42 - Given section name is invalid"
echo " 43 - No distributions list given"
echo " 44 - Given distributions list is invalid"
echo " 45 - No architectures list given"
echo " 46 - Given architectures list is invalid"
echo " 47 - Given keyring URL is invalid"
echo " 48 - Given keyring URL cannot be downloaded"
}
function doHelperListRepos { function doHelperListRepos {
echo "Helper List" echo "Helper List"
exit exit
@@ -71,7 +234,44 @@ function doLicense {
} }
function doListRepos { function doListRepos {
echo "List Repos" local diff
local n
local repo
local reponamelength
local reponamemaxlength
reponamemaxlength=10
for repo in ${localrepos[@]}; do
reponamelength=${#repo}
[[ ${reponamelength} -gt ${reponamemaxlength} ]] && reponamemaxlength=${reponamelength}
done
diff=$((reponamemaxlength-7))
echo -n "Local Repo"
for ((n=0; n<${diff}; n++)); do
echo -n " "
done
echo "Pretty Name"
echo
for repo in ${localrepos[@]}; do
reponamelength=${#repo}
diff=$((reponamemaxlength-${reponamelength}+3))
echo -n "${repo}"
for ((n=0; n<${diff}; n++)); do
echo -n " "
done
echo "${prettynames[${repo}]}"
done | sort
echo
exit exit
} }
@@ -85,7 +285,52 @@ function doQuietSyncRepos {
} }
function doRemoveRepo { function doRemoveRepo {
echo "Remove Repo ${1}" local confirmation
local repo="${1}"
echo "Removing '${prettynames[${repo}]}'..."
echo -n "This cannot be undone. Type REMOVE then press ENTER to continue... "
read -r confirmation
if [[ "${confirmation,,}" != "remove" ]]; then
echo "Exiting without removing!"
echo
exit
fi
if [[ -f /etc/debmirrorman/${repo}.repo ]]; then
echo "Deleting /etc/debmirrorman/${repo}.repo..."
rm -f /etc/debmirrorman/${repo}.repo
fi
if [[ -f /etc/debmirrorman/${repo}.gpg ]]; then
echo "Deleting /etc/debmirrorman/${repo}.gpg..."
rm -f /etc/debmirrorman/${repo}.gpg
fi
echo "Writing /etc/debmirrorman/settings.conf..."
localrepos+=("${repo}")
localrepos=($(echo "${localrepos[@]}" | tr ' ' '\n' | sort | uniq -u))
echo "declare localfqdn=\"${localfqdn}\"" > /etc/debmirrorman/settings.conf
echo "declare -a localrepos=(" >> /etc/debmirrorman/settings.conf
for repo in ${localrepos[@]}; do
echo " \"${repo}\"" >> /etc/debmirrorman/settings.conf
done
echo ")" >> /etc/debmirrorman/settings.conf
echo "declare -A prettynames=(" >> /etc/debmirrorman/settings.conf
for repo in ${localrepos[@]}; do
echo " [${repo}]=\"${prettynames[${repo}]}\"" >> /etc/debmirrorman/settings.conf
done
echo ")" >> /etc/debmirrorman/settings.conf
echo "DONE!"
echo
exit exit
} }
@@ -124,5 +369,6 @@ function doUpdater {
function doVersion { function doVersion {
echo "DebMirror Manager version ${VERSION}" echo "DebMirror Manager version ${VERSION}"
echo
exit exit
} }

View File

@@ -1,8 +1,9 @@
#!/bin/bash #!/bin/bash
TITLE="DebMirror Manager" TITLE="DebMirror Manager"
VERSION="0.0.1" VERSION="0.0.3"
URL="https://git.3volve.net.za/thisiszeev/debmirrorman" URL="https://git.3volve.net.za/thisiszeev/debmirrorman"
LICENSE="GPL 3"
AUTHOR="Ze'ev Schurmann" AUTHOR="Ze'ev Schurmann"
AUTHORURL="https://reddit.com/u/thisiszeev" AUTHORURL="https://reddit.com/u/thisiszeev"
@@ -10,46 +11,54 @@ source vars.lib.sh
source functions.lib.sh source functions.lib.sh
source actions.lib.sh source actions.lib.sh
if funcValidateSettings; then
source "${etcdirectory}/settings.conf"
else
funcError "Unknown error loading '${etcdirectory}/settings.conf'..." 29
fi
if [[ -z "${1}" ]]; then if [[ -z "${1}" ]]; then
doHelper doHelper
exit exit
else else
command="${1,,}" command="${1,,}"
if [[ -z "${commands[${command}]}" ]]; then if [[ -z "${commands[${command}]}" ]]; then
echo "Command ${1} not valid..." funcError "Command '${1}' not valid..." 1
exit 1
else else
if [[ -n "${2}" ]]; then if [[ -n "${2}" ]]; then
if [[ "${commandsneedreponame[${command}]}" == "none" ]]; then if [[ "${commandsneedreponame[${command}]}" == "none" ]]; then
echo "Command ${1} does not support a repo name..." funcError "Command '${1}' does not support a repo name..." 2
exit 1
elif [[ "${commandsneedreponame[${command}]}" == "help" ]]; then elif [[ "${commandsneedreponame[${command}]}" == "help" ]]; then
helpcommand="${2,,}" helpcommand="${2,,}"
if [[ -z "${commands[${helpcommand}]}" ]]; then # if [[ -z "${commands[${helpcommand}]}" ]]; then
echo "Command ${2} not valid..." # funcError "Command '${2}' not valid..." 11
exit 1 # else
else
if [[ -z "${helpercommands[${helpcommand}]}" ]]; then if [[ -z "${helpercommands[${helpcommand}]}" ]]; then
echo "No help documentation for command ${2}..." funcError "No help documentation for command '${2}'..." 12
exit 1
else else
${helpercommands[${helpcommand}]} ${helpercommands[${helpcommand}]} | less
exit exit
fi fi
fi # fi
else else
if funcCheckLocalRepo "${2}"; then funcCheckLocalRepo "${2}"
ec=$?
if [[ ${ec} == 0 ]]; then
${commands[${command}]} "${2}" ${commands[${command}]} "${2}"
exit exit
elif [[ ${ec} == 1 ]]; then
funcError "Repo name '${2}' not valid..." 4
elif [[ ${ec} == 2 ]]; then
funcError "Repo name '${2}' is not found in '${etcdirectory}/settings.conf'..." 5
elif [[ ${ec} == 3 ]]; then
funcError "File '${etcdirectory}/${repo}.repo' does not exist..." 6
else else
echo "Invalid local repo name..." funcError "Unknown error with local repo '${2}'..." 9
exit 1
fi fi
fi fi
else else
if [[ "${commandsneedreponame[${command}]}" == "required" ]]; then if [[ "${commandsneedreponame[${command}]}" == "required" ]]; then
echo "Command ${1} requires a repo name..." funcError "Command '${1}' requires a repo name..." 3
exit 1
else else
${commands[${command}]} ${commands[${command}]}
exit exit
@@ -57,4 +66,5 @@ else
fi fi
fi fi
fi fi
exit 127
funcError "Unknown error with DebMirror Manager..." 127

View File

@@ -1,30 +1,319 @@
## DebMirror Manager Functions Library ## DebMirror Manager Functions Library
function funcCheckLocalRepo { function funcAddLocalRepo {
## This function performs several checks in a sequence...
## 1. Validates the given local repo name, checks if it is in ${localrepos} and that there is no existing repo file before adding it to ${localrepos} (must be lowercase, digits and dashes only, no leading or trailing dashes)
## 2. The given pretty name is added to ${prettynames}
## 3. Validates the given remote FQDN and checks if it can be resolved to an IP address (must contain lowercase, digits, dashes and periods only, no leading or trailing dashes, no leading or trailing periods, no dashes or periods adjacent to periods)
## 4. Validates the given remote repo name (must be lowercase, digits and dashes only, no leading or trailing dashes)
## 5. Validates the given section (must be lowercase, digits and dashes only, no leading or trailing dashes)
## 6. Validates the given distributions list (comma delimited list, must be lowercase and digits only)
## 7. Validates the given architectures list (comma delimited list, must be lowercase and digits only)
## 8. Validates the given method to be either http or https (if omitted it will default to https)
## 9. Validates the given keyring URL (must be a valid URL to the remote repo GPG key, if omitted no keyring will be used)
## 10. Validates the given boolean (true or false) for if sources data must be included in the local repo (normally only required if you intend to maintain the Deb packages on the mirror, if omitted then it will be set to false)
## 11. Validates the given boolean (true or false) for if the Debian Install data must be included in the local repo (normally only required when mirroring the official Debian repo, if omitted then it will be set to false)
## When all check pass, a new repo file {localreponame}.repo is created in /etc/debmirrorman, settings.conf is updated in /etc/debmirrorman, and if required the GPG key is downloaded and saved to /etc/debmirrorman as {localreponame}.gpg
## Example Usage: funcAddLocalRepo {localreponame} desc="{prettyname}" fqdn="{remotefqdn}" repo={remotereponame} sect={sectionname} dist="{distributions}" arch="{architectures}" meth={http|https} kurl="{keyringurl}" srcs={true|false} debi={true|false}
## If successful, this function will only returns exit code 0
## If any step fails, this function will output an error message and exit with the corresponding exit code
## 0 - Adding local repo was successful
## 31 - No local repo name given (hard exit)
## 32 - Given local repo name is invalid (hard exit)
## 33 - Given local repo name already exists in ${localrepos} (hard exit)
## 34 - There is already a file {localreponame}.repo in /etc/debmirrorman (hard exit)
## 35 - No pretty name given (hard exit)
## 36 - No remote FQDN given (hard exit)
## 37 - Given remote FQDN is invalid (hard exit)
## 38 - Given remote FQDN does not resolve to an IP address (hard exit)
## 39 - No remote repo name given (hard exit)
## 40 - Given remote repo name is invalid (hard exit)
## 41 - No section name given (hard exit)
## 42 - Given section name is invalid (hard exit)
## 43 - No distributions list given (hard exit)
## 44 - Given distributions list is invalid (hard exit)
## 45 - No architectures list given (hard exit)
## 46 - Given architectures list is invalid (hard exit)
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -z "${1}" ]]; then if [[ -z "${1}" ]]; then
return 5 funcDebugMessage "No repo name given..."
return 125
else
local localrepo="${1}"
fi
if [[ -z "${2}" ]]; then
funcDebugMessage "No pretty name given..."
return 126
else
local prettyname="${2}"
fi
if funcValidateRepoName "${repo}"; then
funcDebugMessage "Val"
echo ${localrepos}
fi
}
function funcRemoveLocalRepo {
# doRemoveRepo
donothing=0
}
function funcWriteSettingsFile {
# doAddRepo
donothing=0
}
function funcWriteRepoFile {
# doAddRepo
donothing=0
}
function funcCheckLocalRepo {
## Validates the given repo name, checks it is in ${localrepos} and that the repo file exists
## Example Usage: funcCheckLocalRepo {reponame}
## Given repo name must contain lowercase, digits and dashes only (no leading or trailing dashes)
## This function only returns exit codes
## 0 - All checks passed
## 1 - Invalid repo name
## 2 - Repo name is not in ${localrepos}
## 3 - Repo file does not exist
## 126 - No repo name given
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -z "${1}" ]]; then
funcDebugMessage "No repo name given..."
return 126
else else
local repo="${1}" local repo="${1}"
fi fi
if [[ "${localrepo}" =~ ^[a-z0-9]+([a-z0-9-]*[a-z0-9])?$ ]]; then if funcValidateRepoName ${repo}; then
if [[ -f "/etc/debmirrorman/settings.conf" ]]; then if funcIsLocalRepo ${repo}; then
source "/etc/debmirrorman/settings.conf" if funcDoesRepoFileExist ${repo}; then
if echo ${localrepos[@]} | tr ' ' '\n' | grep -q ^${localrepo}$; then funcDebugMessage "All checks passed..."
if [[ -f "/etc/debmirrorman/${localrepo}.repo" ]]; then
return 0 return 0
else else
funcDebugMessage "File '${etcdirectory}/${repo}.repo' does not exist..."
return 3 return 3
fi fi
else else
funcDebugMessage "Repo name is not in \${localrepos}..."
return 2 return 2
fi fi
else else
return 4 funcDebugMessage "Invalid repo name..."
fi
else
return 1 return 1
fi fi
funcDebugMessage "Unknown Error..."
return 127
}
function funcDebugMessage {
## If ${debugmode} == true then output the given text to STDERR
## Example Usage: funcDebugMessage "This is a debug message"
## 0 - Message sent to STDERR or ${debugmode} == false
## 126 - No message was given but ${debugmode} == true
## 127 - Unknown error
[[ -n ${debugmode} ]] || debugmode=false
[[ ${debugmode} == true ]] || return 0
[[ -n "${1}" ]] || return 126
local message="${1}"
echo -e "DEBUG [function ${FUNCNAME[1]}]: ${message}" >&2 && return 0
return 127
}
function funcDoesRepoFileExist {
## Checks that the given repo name exists as a file in /etc/debmirrorman
## Example Usage: funcDoesRepoFileExist {reponame}
## Given repo name must contain lowercase, digits and dashes only (no leading or trailing dashes)
## This function only returns exit codes
## 0 - Repo file exists
## 1 - Repo file does not exist
## 126 - No repo name given
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -z "${1}" ]]; then
funcDebugMessage "No repo name given..."
return 126
else
local repo="${1}"
fi
if [[ -f "${etcdirectory}/${repo}.repo" ]]; then
funcDebugMessage "File '${etcdirectory}/${repo}.repo' exists..."
return 0
else
funcDebugMessage "File '${etcdirectory}/${repo}.repo' does not exist..."
return 1
fi
funcDebugMessage "Unknown Error..."
return 127
}
function funcError {
## Outputs the given error message to STDERR and exits with the given exit code
## Example Usage: funcError "{errormessage}" {exitcode}
## Exit code must be an integer between 1 and 127. If omitted then 127 will be used.
funcDebugMessage "Function called..."
if [[ -z ${1} ]]; then
funcDebugMessage "No error message given..."
echo "ERROR: An unknown error occurred..." >&2
else
funcDebugMessage "Error message given..."
echo -e "ERROR: ${1}" >&2
fi
if [[ -n ${2} ]] && [[ ${2} -ge 1 ]] && [[ ${2} -le 127 ]]; then
funcDebugMessage "Valid exit code given..."
exit ${2}
fi
funcDebugMessage "No valid exit code given..."
exit 127
}
function funcIsLocalRepo {
## Checks that the given repo name exists in the array ${localrepos}
## Example Usage: funcIsLocalRepo {reponame}
## Given repo name must contain lowercase, digits and dashes only (no leading or trailing dashes)
## This function only returns exit codes
## 0 - Repo name is in ${localrepos}
## 1 - Repo name is not in ${localrepos}
## 126 - No repo name given
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -z "${1}" ]]; then
funcDebugMessage "No repo name given..."
return 126
else
local repo="${1}"
fi
if echo ${localrepos[@]} | tr ' ' '\n' | grep -q ^${repo}$; then
funcDebugMessage "Repo name is in \${localrepos}..."
return 0
else
funcDebugMessage "Repo name is not in \${localrepos}..."
return 1
fi
funcDebugMessage "Unknown Error..."
return 127
}
function funcValidateFQDN {
## Validates the given FQDN
## Example Usage: funcValidateFQDN "{fqdn}"
## Given FQDN must contain lowercase, digits, dashes and periods only (no leading or trailing dashes, no leading or trailing periods, no dashes or periods adjacent to periods)
## This function only returns exit codes
## 0 - FQDN is valid
## 1 - FQDN is not valid
## 126 - No FQDN given
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -z "${1}" ]]; then
funcDebugMessage "No FQDN name given..."
return 126
else
local fqdn="${1}"
fi
if [[ "${fqdn}" =~ ^([a-z0-9](-?[a-z0-9])*\.)+[a-z]{2,}$ ]]; then
funcDebugMessage "FQDN is valid..."
return 0
else
funcDebugMessage "FQDN is not valid..."
return 1
fi
funcDebugMessage "Unknown Error..."
return 127
}
function funcValidateRepoName {
## Checks that a given repo name is valid
## Example Usage: funcValidateLocalName {reponame}
## Given repo name must contain lowercase, digits and dashes only (no leading or trailing dashes)
## This function only returns exit codes
## 0 - Valid repo name
## 1 - Invalid repo name
## 126 - No repo name given
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -z "${1}" ]]; then
funcDebugMessage "No repo name given..."
return 126
else
local repo="${1}"
fi
if [[ "${repo}" =~ ^[a-z0-9]+([a-z0-9-]*[a-z0-9])?$ ]]; then
funcDebugMessage "Valid repo name..."
return 0
else
funcDebugMessage "Invalid repo name..."
return 1
fi
funcDebugMessage "Unknown Error..."
return 127
}
function funcValidateSettings {
## Checks if /etc/debmirrorman/settings.conf exists, confirms the existance of ${localfqdn} abd that it is a valid FQDN
## Example Usage: funcValidateSettings
## This function returns exit code 0 if all checks pass and exits with exit code 2 and an error message if any checks fail.
## 0 - /etc/debmirrorman/settings.conf passes all checks
## 15 - /etc/debmirrorman/settings.conf does not exist (hard exit)
## 16 - No ${localfqdn} defined in /etc/debmirrorman/settings.conf (hard exit)
## 17 - Invalid ${localfqdn} defined in /etc/debmirrorman/settings.conf (hard exit)
## 127 - Unknown error
funcDebugMessage "Function called..."
if [[ -f "${etcdirectory}/settings.conf" ]]; then
funcDebugMessage "'${etcdirectory}/settings.conf' exists..."
source "${etcdirectory}/settings.conf"
else
funcError "'settings.conf' not found at '${etcdirectory}'..." 21
fi
if [[ -z ${localfqdn} ]]; then
funcError "No \${localfqdn} defined in '${etcdirectory}/settings.conf'..." 22
else
if funcValidateFQDN "${localfqdn}"; then
funcDebugMessage "'${etcdirectory}/settings.conf' passed all checks..."
return 0
else
funcError "Invalid \${localfqdn} defined in '${etcdirectory}/settings.conf'..." 23
fi
fi
funcDebugMessage "Unknown Error..."
return 127 return 127
} }

6
source/list.temp Normal file
View File

@@ -0,0 +1,6 @@
apache2
bind
nginx
nginx-mainline
php
nginx

View File

@@ -0,0 +1,43 @@
declare etcdirectory="/etc/debmirrorman"
declare -a localrepos=(
"apache2"
"bind"
"nginx"
"php"
)
declare -A prettynames=(
[apache2]="Apache2 Repo"
[bind]="Bind9 Repo"
[nginx]="Nginx Repo"
[php]="PHP Repo"
)
function preTest {
local repo
echo "localrepos = ${localrepos[@]}"
echo "prettynames ="
for repo in ${localrepos[@]}; do
echo " [${repo}] = ${prettynames[${repo}]}"
done
echo
}
function postTest {
local repo
echo
echo "localrepos = ${localrepos[@]}"
echo "prettynames ="
for repo in ${localrepos[@]}; do
echo " [${repo}] = ${prettynames[${repo}]}"
done
echo
}

121
source/test-functions.sh Executable file
View File

@@ -0,0 +1,121 @@
#!/bin/bash
## Use this to test a function in functions.lib.sh
## Usage Examples:
## $0 {functionname}
## $0 {functionname} {testfile}
## $0 {functionname} {functiondataone}
## $0 {functionname} {functiondataone} {testfile}
## $0 {functionname} {functiondataone} {functiondatatwo}
## $0 {functionname} {functiondataone} {functiondatatwo} {testfile}
## functionname - The name of the function in functions.lib.sh to test
## functiondataone - The data to give to the function as first option
## functiondatatwo - The data to give to the function as second option
## testfile - The test file that contains starting data stored in variables
## The test file can also contain two functions 'preTest' and 'postTest'
## 'preTest' will be called before the given function is tested
## 'postTest' will be called after the given function is tested
## Example use of these two functions could be to output the contents
## of the variables in the test file, before and/or after the given
## function is tested.
## Exit code of this script is the same as the exit code of the tested function (0-127)
## Exit code 252 - If fourth option is given, it must be a file but the given file does not exist.
## Exit code 253 - Given function name does not exist in functions.lib.sh
## Exit code 254 - No function name was given
## Exit code 255 - Unknown error
## Change ${debugmode} between true and false to enable and disable debug messages.
## You can also redefine it in the test file, if a test file is to be used.
declare debugmode=true
source functions.lib.sh
if [[ -z ${1} ]]; then
echo "No function name given..." >&2
echo >&2
echo "Usage Examples:" >&2
echo " $0 {functionname}" >&2
echo " $0 {functionname} {testfile}" >&2
echo " $0 {functionname} {functiondataone}" >&2
echo " $0 {functionname} {functiondataone} {testfile}" >&2
echo " $0 {functionname} {functiondataone} {functiondatatwo}" >&2
echo " $0 {functionname} {functiondataone} {functiondatatwo} {testfile}" >&2
echo >&2
echo " functionname - The name of the function in functions.lib.sh to test" >&2
echo " functiondataone - The data to give to the function as first option" >&2
echo " functiondatatwo - The data to give to the function as second option" >&2
echo " testfile - The test file that contains starting data stored in variables" >&2
echo " The test file can also contain two functions 'preTest' and 'postTest'" >&2
echo " 'preTest' will be called before the given function is tested" >&2
echo " 'postTest' will be called after the given function is tested" >&2
echo " Example use of these two functions could be to output the contents" >&2
echo " of the variables in the test file, before and/or after the given" >&2
echo " function is tested." >&2
echo >&2
echo "You can also redefine the boolean value of \$debugmode from within the test file." >&2
echo "declare debugmode=true" >&2
echo " > This will turn debug messages on." >&2
echo "declare debugmode=false" >&2
echo " > This will turn debug messages off." >&2
echo >&2
echo "Exit code of this script is the same as the exit code of the tested function (0-127)" >&2
echo "Exit code 252 - If fourth option is given, it must be a file but the given file does not exist." >&2
echo "Exit code 253 - Given function name does not exist in functions.lib.sh" >&2
echo "Exit code 254 - No function name was given" >&2
echo "Exit code 255 - Unknown error" >&2
exit 254
fi
functionname="${1}"
if ! declare -F ${functionname} > /dev/null; then
echo "Function '${functionname}' does not exist in 'functions.lib.sh'..." >&2
exit 253
fi
if [[ -z ${2} ]]; then
${functionname}
exitcode=$?
else
if [[ -f "${2}" ]]; then
source "${2}"
declare -F preTest > /dev/null && preTest
${functionname}
exitcode=$?
else
functiondataone="${2}"
if [[ -z ${3} ]]; then
${functionname} "${functiondataone}"
exitcode=$?
else
if [[ -f "${3}" ]]; then
source "${3}"
declare -F preTest > /dev/null && preTest
${functionname} "${functiondataone}"
exitcode=$?
else
functiondatatwo="${3}"
if [[ -z ${4} ]]; then
${functionname} "${functiondataone}" "${functiondatatwo}"
exitcode=$?
else
if [[ -f "${4}" ]]; then
source "${4}"
declare -F preTest > /dev/null && preTest
${functionname} "${functiondataone}" "${functiondatatwo}"
exitcode=$?
else
echo "File '${4}' does not exist and cannot be sourced..."
exit 252
fi
fi
fi
fi
fi
fi
declare -F postTest > /dev/null && postTest
echo "Function '${functionname}' returned exit code ${exitcode}" && exit ${exitcode}
exit 255

View File

@@ -1,5 +1,7 @@
## DebMirror Manager Variables Declarations Library ## DebMirror Manager Variables Declarations Library
declare etcdirectory="/etc/debmirrorman"
declare -A commands=( declare -A commands=(
[add]="doAddRepo" [add]="doAddRepo"
[dryrun]="doTestRepo" [dryrun]="doTestRepo"
@@ -36,6 +38,7 @@ declare -A helpercommands=(
[add]="doHelperAdd" [add]="doHelperAdd"
[dryrun]="doHelperTestRepo" [dryrun]="doHelperTestRepo"
[edit]="doHelperEditRepo" [edit]="doHelperEditRepo"
[exitcodes]="doHelperExitCodes"
[list]="doHelperListRepos" [list]="doHelperListRepos"
[remove]="doHelperRemoveRepo" [remove]="doHelperRemoveRepo"
[usage]="doHelperRepoUsage" [usage]="doHelperRepoUsage"
@@ -44,3 +47,7 @@ declare -A helpercommands=(
[silentrun]="doHelperQuietSyncRepos" [silentrun]="doHelperQuietSyncRepos"
[update]="doHelperUpdater" [update]="doHelperUpdater"
) )
declare localfqdn
declare -a localrepos
declare -A prettynames