Merge branch 'devel' into 'main'

Shellcheck and General fixes

See merge request release-engineering/public/toolkit!2
This commit is contained in:
Louis Abel 2021-07-06 20:25:13 +00:00
commit e47d87a03b
34 changed files with 108 additions and 69 deletions

View File

@ -28,12 +28,15 @@ function r_checkExitStatus() {
# just having the files named differently, but that seemed more annoying than
# just setting +x
function r_processor() {
# shellcheck disable=SC2068
exec 8< $@
# shellcheck disable=SC2162
while read -u 8 file; do
# shellcheck disable=SC2086
if [[ "$(basename ${file})" =~ README|^\.|^_ ]]; then
continue
fi
[ -x ${file} ] && ${file}
[ -x "${file}" ] && "${file}"
done
return 0
}
@ -45,6 +48,7 @@ function r_processor() {
# Args: Any number of $1..X
function p_installPackageNormal() {
r_log "internal" "Attempting install: $*"
# shellcheck disable=SC2086
/usr/bin/dnf --assumeyes --debuglevel ${DNFDEBUG} install "$@"
r_checkExitStatus $?
}
@ -54,6 +58,7 @@ function p_installPackageNormal() {
# Args: Any number of $1..X
function p_installPackageNoWeaks() {
r_log "internal" "Attempting install: $*"
# shellcheck disable=SC2086
/usr/bin/dnf --assumeyes --debuglevel ${DNFDEBUG} --setopt install_weak_deps=0 install "$@"
r_checkExitStatus $?
}
@ -62,6 +67,7 @@ function p_installPackageNoWeaks() {
# Args: Any number of $1..X
function p_removePackage() {
r_log "internal" "Attempting uninstall: $*"
# shellcheck disable=SC2086
/usr/bin/dnf --assumeyes --debuglevel ${DNFDEBUG} remove "$@"
r_checkExitStatus $?
}
@ -70,6 +76,7 @@ function p_removePackage() {
# Args: Any number of $1..X
function p_enableModule() {
r_log "internal" "Enabling module: $*"
# shellcheck disable=SC2086
/usr/bin/dnf --assumeyes --debuglevel ${DNFDEBUG} module enable "$@"
r_checkExitStatus $?
}
@ -78,20 +85,21 @@ function p_enableModule() {
# Args: Any number of $1..X
function p_resetModule() {
r_log "internal" "Resetting module: $*"
# shellcheck disable=SC2086
/usr/bin/dnf --assumeyes --debuglevel ${DNFDEBUG} module reset "$@"
r_checkExitStatus $?
}
function p_getPackageRelease() {
rpm -q --queryformat '%{RELEASE}' $1
rpm -q --queryformat '%{RELEASE}' "$1"
}
function p_getPackageArch() {
rpm -q --queryformat '%{ARCH}' $1
rpm -q --queryformat '%{ARCH}' "$1"
}
function p_getDist() {
rpm -q $(rpm -qf /etc/redhat-release) --queryformat '%{version}\n' | cut -d'.' -f1
rpm -q "$(rpm -qf /etc/redhat-release)" --queryformat '%{version}\n' | cut -d'.' -f1
}
################################################################################
@ -101,10 +109,13 @@ function p_getDist() {
# prevent potential race conditions.
function m_serviceCycler() {
if [ "$2" = "cycle" ]; then
# shellcheck disable=SC2086
/bin/systemctl stop $1
sleep 3
# shellcheck disable=SC2086
/bin/systemctl start $1
else
# shellcheck disable=SC2086
/bin/systemctl $2 $1
fi
sleep 3
@ -113,6 +124,7 @@ function m_serviceCycler() {
function m_checkForPort() {
while true; do
sleep 1
# shellcheck disable=SC2086
if echo > /dev/tcp/localhost/$1 >/dev/null 2>&1; then
r_log "internal" "Waiting for TCP port $1 to start listening"
break

View File

@ -68,7 +68,7 @@ r_log "archive" "Check that -r functions"
mkdir /var/tmp/gziptest
touch /var/tmp/gziptest/{a,b}
gzip -r /var/tmp/gziptest
[ "$(ls /var/tmp/gziptest/*.gz | wc -l)" -eq "2" ] || r_checkExitStatus 1
[ "$(find /var/tmp/gziptest/*.gz | wc -l)" -eq "2" ] || r_checkExitStatus 1
# check different compression levels
r_log "archive" "Check compression levels"

View File

@ -1,4 +1,4 @@
#!/bin/bash
r_log "bc" "Testing simple calculations"
test $(echo "8 + 5 * 2 / 10 - 1" | bc) -eq "8"
test "$(echo "8 + 5 * 2 / 10 - 1" | bc)" -eq "8"
r_checkExitStatus $?

View File

@ -1,6 +1,8 @@
#!/bin/bash
r_log "coreutils" "Testing pathchk"
pathchk -p "<>" 2> /dev/null
# shellcheck disable=SC2181
[ $? -eq 1 ] && pathchk /var/tmp/fakePathAndFile
# shellcheck disable=SC2181
[ $? -eq 0 ] && pathchk /var/tmp
r_checkExitStatus $?

View File

@ -6,6 +6,7 @@ touch -t 199104230420 /tmp/touch-1
touch -t 199104240420 /tmp/touch-2
r_log "coreutils" "Verify that the oldest file is last"
# shellcheck disable=SC2012
ls -lt /tmp/touch-? | tail -n 1 | grep -q 'touch-1'
r_checkExitStatus $?

View File

@ -3,6 +3,7 @@ r_log "coreutils" "Test the yes command"
touch /var/tmp/yes-123
touch /var/tmp/yes-345
# shellcheck disable=SC2216
yes | /bin/rm -i /var/tmp/yes-* || r_checkExitStatus 1
deleted=1

View File

@ -11,6 +11,7 @@ PASSER=/var/tmp/cpio/pass
r_log "cpio" "Test basic copy out"
mkdir -p "$OUTTER" "$INNER" "$PASSER"
# shellcheck disable=2012
ls /tmp | cpio -o > "$OUTTER"/cpio.out
r_checkExitStatus $?

View File

@ -7,5 +7,5 @@ if [ -z "$pngFile" ]; then
exit 0
fi
file -i $pngFile | grep -q 'image/png'
file -i "$pngFile" | grep -q 'image/png'
r_checkExitStatus $?

View File

@ -5,7 +5,7 @@ TMPDIR=/var/tmp/find
[ -e $TMPDIR ] && rm -rf "$TMPDIR"
mkdir -p "$TMPDIR" || { r_log "findutils" "Can't create $TMPDIR"; exit $FAIL; }
mkdir -p "$TMPDIR" || { r_log "findutils" "Can't create $TMPDIR"; exit "$FAIL"; }
touch "$TMPDIR/file1"
touch "$TMPDIR/file with a space"
r_log "findutils" "Check that find just works(tm)"
@ -23,7 +23,7 @@ fi
r_log "findutils" "Prepare for xargs test"
LINES=$(find "$TMPDIR" -print0 | wc -l)
if [ $LINES -eq 0 ]; then
if [ "$LINES" -eq 0 ]; then
r_checkExitStatus 0
else
r_checkExitStatus 1
@ -34,8 +34,10 @@ find "$TMPDIR" -type f -print0 | xargs -0 ls &> /dev/null
r_checkExitStatus $?
r_log "findutils" "Perform for xargs test: fails with spaces in the name"
find "$TMPDIR" -type f | xargs ls &> /dev/null && { r_log "findutils" "Why did this get a 0 exit?"; exit $FAIL; }
if [ $? -ne 0 ]; then
# shellcheck disable=SC2038
find "$TMPDIR" -type f | xargs ls &> /dev/null && { r_log "findutils" "Why did this get a 0 exit?"; exit "$FAIL"; }
ret_val=$?
if [ "$ret_val" -ne 0 ]; then
r_checkExitStatus $?
fi

View File

@ -2,8 +2,8 @@
r_log "gcc" "Ensure gcc can build a simple program"
OUTPUTPROG=$(mktemp)
gcc ./common/files/hello.c -o $OUTPUTPROG
$OUTPUTPROG | grep -q "Hello!"
gcc ./common/files/hello.c -o "$OUTPUTPROG"
"$OUTPUTPROG" | grep -q "Hello!"
r_checkExitStatus $?
rm $OUTPUTPROG
rm "$OUTPUTPROG"

View File

@ -2,8 +2,8 @@
r_log "gcc" "Ensure g++ can build a simple program"
OUTPUTPROG=$(mktemp)
g++ -x c++ ./common/files/hello.cpp -o $OUTPUTPROG
$OUTPUTPROG | grep -q "Hello!"
g++ -x c++ ./common/files/hello.cpp -o "$OUTPUTPROG"
"$OUTPUTPROG" | grep -q "Hello!"
r_checkExitStatus $?
rm $OUTPUTPROG
rm "$OUTPUTPROG"

View File

@ -2,7 +2,7 @@
r_log "kernel" "Testing the kernel keyring (GPG)"
ARCH=$(uname -m)
KERNEL=$(uname -r | cut -d'-' -f1)
#KERNEL=$(uname -r | cut -d'-' -f1)
if [ "${ARCH}" == "aarch64" ]; then
r_log "kernel" "Architecture not tested: $ARCH"

View File

@ -1,8 +1,7 @@
#!/bin/bash
r_log "kernel" "Testing debrand"
kernver=$(uname -r)
strings /boot/vmlinuz-$(uname -r) | grep -qi rhel
strings "/boot/vmlinuz-$(uname -r)" | grep -qi rhel
ret_val=$?
if [ "$ret_val" -eq "0" ]; then

View File

@ -4,7 +4,7 @@ r_log "network" "Checking that iptraf runs and returns non-zero"
TMPFILE=/var/tmp/iptraf
[ -e ${TMPFILE} ] && rm ${TMPFILE}
[ ${EUID} -eq 0 ] || { r_log "network" "SKIP: Not running as root."; exit $PASS; }
[ ${EUID} -eq 0 ] || { r_log "network" "SKIP: Not running as root."; exit "$PASS"; }
mkdir -p ${TMPFILE}
@ -14,7 +14,7 @@ KILL=$(which iptraf-ng)
STAT=$(which iptraf-ng)
for x in $IPTRAF $PING $KILL $STAT; do
[ ! -f "$x" ] && { r_log "network" "$x not found. This is likely a problem."; exit $FAIL; }
[ ! -f "$x" ] && { r_log "network" "$x not found. This is likely a problem."; exit "$FAIL"; }
done
r_log "network" "Run iptraf on all available interfaces"
@ -24,6 +24,7 @@ r_log "network" "Do a simple ping for iptraf"
${PING} -c 6 127.0.0.12 &> /dev/null
LOGSIZE=$(stat -c '%s' ${TMPFILE})
# shellcheck disable=SC2086
kill -USR2 "$(pidof $IPTRAF)"
r_log "network" "Verifying that iptraf log has data"

View File

@ -2,12 +2,13 @@
r_log "network" "Test bridging functionality (non-network manager)"
bridge=dummybr0
# shellcheck disable=SC1091
. "$(dirname "$0")"/imports.sh
r_log "network" "Add a dummy bridge $bridge"
ret_val=$(iproute_add_bridge $bridge)
r_checkExitStatus $ret_val
r_checkExitStatus "$ret_val"
r_log "network" "Clean up/Remove bridge"
ret_val=$(iproute_del_bridge $bridge)
r_checkExitStatus $ret_val
r_checkExitStatus "$ret_val"

View File

@ -9,7 +9,7 @@ m_serviceCycler nfs-server restart
r_log "nfs" "Mount NFS share"
mount -t nfs 127.0.0.1:/export/rotest /mnt
ls -la /mnt | grep -q "nfsfile"
find /mnt | grep -q "nfsfile"
r_checkExitStatus $?
umount /mnt

View File

@ -10,7 +10,7 @@ m_serviceCycler nfs-server restart
r_log "nfs" "Mount NFS share"
mount -t nfs 127.0.0.1:/export/rwtest /mnt
ls -la /mnt | grep -q "nfsfile"
find /mnt | grep -q "nfsfile"
r_checkExitStatus $?
r_log "nfs" "Test that the NFS share is writeable"

View File

@ -15,7 +15,7 @@ m_serviceCycler nfs-server restart
m_serviceCycler rpcbind restart
m_serviceCycler autofs restart
r_log "nfs" "Attempt to access /export/autotest via autofs"
ls -la /mnt/autofs | grep -q autofile
find /mnt/autofs | grep -q autofile
r_checkExitStatus $?
# Remove unneeded configuration

View File

@ -46,7 +46,8 @@ else
fi
cp "$DROPDIR/openssl.crt" "$SSLPATH/certs/"
HASH=$(openssl x509 -noout -hash -in $SSLPATH/certs/openssl.crt)
# shellcheck disable=SC2086
HASH="$(openssl x509 -noout -hash -in $SSLPATH/certs/openssl.crt)"
ret_val=$?
if [ $ret_val -ne 0 ]; then
r_log "openssl" "Could not create hash"

View File

@ -2,7 +2,8 @@
r_log "postfix" "Test basic MTA"
REGEX='250\ 2\.0\.0\ Ok\:\ queued\ as\ ([0-9A-Z]*).*'
mailresp=$(echo -e "helo localhost\nmail from: root@localhost\nrcpt to: root@localhost\ndata\nt_functional test\n.\nquit\n" | nc -w 5 127.0.0.1 25 | grep queued)
if [ $? -eq 0 ]; then
ret_val=$?
if [ "$ret_val" -eq 0 ]; then
r_log "postfix" "Mail queued successfully"
MTA_ACCEPTED=0
else
@ -13,7 +14,7 @@ fi
sleep 2
# Verify that /var/log/maillog is working, if not dump it out
mailresp_id=$(echo $mailresp | cut -d' ' -f6)
mailresp_id=$(echo "$mailresp" | cut -d' ' -f6)
grep -q "${mailresp_id}" /var/log/maillog
if [ $? -eq 1 ]; then
journalctl -u postfix >> /var/log/maillog

View File

@ -14,7 +14,7 @@ echo "Obsidian is the Release Name" > /srv/smb/test.txt
mount -t cifs -o guest,ro //127.0.0.1/rocky /mnt/smb
sleep 1
cat /mnt/smb/test.txt | grep -q "Obsidian"
grep -q "Obsidian" /mnt/smb/test.txt
ret_val=$?
umount /mnt/smb

View File

@ -28,6 +28,7 @@ r_checkExitStatus $?
# lastlog
r_log "shadow" "Verify lastlog"
# shellcheck disable=SC2063
lastlog -u obsidian | grep -q "**Never logged in**"
r_checkExitStatus $?

View File

@ -23,6 +23,8 @@ r_checkExitStatus $?
# newgrp
r_log "shadow" "Attempt to use newgrp for onyxuser"
groups onyxuser | grep -q "onyxuser onyxgroup" || { r_log "shadow" "Groups information is incorrect."; r_checkExitStatus 1; }
# I'll fix this eventually
# shellcheck disable=SC2046,SC2005
echo $( su - onyxuser << EOF
newgrp onyxgroup
groups
@ -73,7 +75,7 @@ fi
r_log "shadow" "Make sure that when a group is a primary user group, groupdel returns 8"
groupdel onyxuser
ret_val=$?
if [ "$retval" -eq 8 ]; then
if [ "$ret_val" -eq 8 ]; then
r_checkExitStatus 0
else
r_log "shadow" "The group was removed..."
@ -108,6 +110,6 @@ r_log "shadow" "Test sg"
sg onyxuser "touch /var/tmp/onyxsg"
r_checkExitStatus $?
r_log "shadow" "Verify sg worked"
ls -l /var/tmp/onyxsg | grep -q onyxuser
stat --format="%U" /var/tmp/onyxsg | grep -q onyxuser
r_checkExitStatus $?
rm /var/tmp/onyxsg

View File

@ -1,6 +1,5 @@
#!/bin/bash
r_log "strace" "Run basic strace tests"
STRACE=$(which strace)
/usr/bin/strace ls &> /dev/null
ret_val=$?

View File

@ -4,7 +4,7 @@ r_log "sysstat" "Test basic iostat disk measurements"
TMPFILE=/var/tmp/iostat.disk
BLOCKS=4096
COUNT=10100
SUM="$(expr $BLOCKS \* $COUNT / 1024)"
SUM="$(( BLOCKS * COUNT / 1024 ))"
DISK="$(fdisk -l | grep -Po -m1 '^/dev/[\D]+')"
[ -e $TMPFILE ] && /bin/rm -f $TMPFILE
@ -13,13 +13,13 @@ DISK="$(fdisk -l | grep -Po -m1 '^/dev/[\D]+')"
echo 1 > /proc/sys/vm/drop_caches
r_log "sysstat" "Running iostat on $DISK"
/usr/bin/iostat -dkx 1 5 $DISK > $TMPFILE &
/usr/bin/iostat -dkx 1 5 "$DISK" > $TMPFILE &
# wait
sleep 4
# Generate traffic
/bin/dd if=$DISK of=/dev/null bs=$BLOCKS count=$COUNT &> /dev/null
/bin/dd if="$DISK" of=/dev/null bs=$BLOCKS count=$COUNT &> /dev/null
# wait
sleep 6

View File

@ -17,7 +17,7 @@ echo 1 > /proc/sys/vm/drop_caches
# wait
sleep 5
/bin/dd if=$DISK bs=$BLOCKS count=$COUNT 2> /dev/null | sha256sum -b - &> /dev/null
/bin/dd if="$DISK" bs=$BLOCKS count=$COUNT 2> /dev/null | sha256sum -b - &> /dev/null
# wait
sleep 5

View File

@ -1,8 +1,8 @@
#!/bin/bash
r_log "telnet" "Basic telnet test"
telnet_sshd_test=`telnet 127.0.0.1 22 << EOF
EOF`
telnet_sshd_test=$(telnet 127.0.0.1 22 << EOF
EOF
)
echo "$telnet_sshd_test" | grep -q "Escape character is '^]'"
r_checkExitStatus $?

View File

@ -17,11 +17,12 @@ SELINUX=$(getenforce)
# End
################################################################################
# shellcheck source=/dev/null
# shellcheck source=/dev/null disable=SC2015
[ -f $COMMON_EXPORTS ] && source $COMMON_EXPORTS || { echo -e "\n[-] $(date): Variables cannot be sourced."; exit 1; }
# shellcheck source=/dev/null
# shellcheck source=/dev/null disable=SC2015
[ -f $COMMON_IMPORTS ] && source $COMMON_IMPORTS || { echo -e "\n[-] $(date): Functions cannot be sourced."; exit 1; }
# Init log
# shellcheck disable=SC2015
[ -e "$LOGFILE" ] && m_recycleLog || touch "$LOGFILE"
# SELinux check
if [ "$SELINUX" != "Enforcing" ]; then
@ -37,10 +38,12 @@ r_log "internal" "Starting Release Engineering Core Tests"
# Skip tests in a list - some tests are already -x, so it won't be an issue
if [ -e skip.list ]; then
r_log "internal" "Disabling tests"
# shellcheck disable=SC2162
grep -E "^${RL_VER}" skip.list | while read line; do
testFile=$(echo $line | cut -d '|' -f 2)
# shellcheck disable=SC2086
testFile="$(echo $line | cut -d '|' -f 2)"
r_log "internal" "SKIP ${testFile}"
chmod -x ${testFile}
chmod -x "${testFile}"
done
r_log "internal" "WARNING: Tests above were disabled."
fi

View File

@ -22,11 +22,14 @@ cleanup_repo () {
# plus is actually 'rockyplus'. Others may as well(?)
if [[ "${repo}" =~ ^(plus)$ ]]; then
repo="rocky${repo}"
# nfv is actually 'NFV'
elif [[ "${repo}" =~ ^(nfv)$ ]]; then
repo="${repo^^}"
else
repo="${repo}"
fi
# Everything has an 8 appended to it
repo="${repo}-8"
return 0
}
@ -38,17 +41,18 @@ for repo in "${ALL_REPOS[@]}"; do
# Print a nice header
printf "================\n${repo}\n================\n"
for arch in "${ARCHES[@]}" "source"; do
# Source is treated as its own architecture
if [[ "${arch}" == "source" ]]; then
_repo="${repo}-8-source"
else
_repo="${repo}-8"
repo="${repo}-source"
fi
result=$(curl -s "${MIRRORLIST_BASE}?repo=${_repo}&arch=${arch}&time&country=global")
# Get the normal repo/arch combinations
result=$(curl -s "${MIRRORLIST_BASE}?repo=${repo}&arch=${arch}&time&country=global")
print_result
# x86 and a64 have 'debug' types, as well
if [[ "${arch}" =~ ^(x86_|aarch)64$ ]]; then
result=$(curl -s "${MIRRORLIST_BASE}?repo=${_repo}-debug&arch=${arch}&time&country=global")
result=$(curl -s "${MIRRORLIST_BASE}?repo=${repo}-debug&arch=${arch}&time&country=global")
print_result
fi
done

View File

@ -0,0 +1,10 @@
#!/bin/bash
# Performs a full on sync of a minor release, directories and all. It calls the
# other scripts in this directory to assist.
# Source common variables
# shellcheck disable=SC2046,1091
source $(dirname "$0")/common
# sync all pieces of a release, including extras, nfv, etc
# move around the ISOs a bit, make things comfortable

View File

@ -12,6 +12,7 @@
# Compose dir example: /mnt/repos-staging/mirror/pub/rocky/8.4-RC2
# Source common variables
# shellcheck disable=SC2046,1091
source $(dirname "$0")/common
echo "** Updating source repos"
@ -64,7 +65,7 @@ for x in "${ARCHES[@]}"; do
if [ "$ret_val" -eq 0 ]; then
createrepo --update "${STAGING_ROOT}/${RELEASE_DIR}/${y}/${x}/os" \
--groupfile="/mnt/compose/8/latest-Rocky-8/work/${x}/comps/comps-${y}.${x}.xml" \
--xz --revision=${REVISION} \
--xz --revision="${REVISION}" \
"--distro=cpe:/o:rocky:rocky:${REVISION:0:1},Rocky Linux ${REVISION:0:1}" \
--workers=8 --checksum=sha256
else

View File

@ -2,18 +2,17 @@
# Syncs everything from staging to production
# Source common variables
# shellcheck disable=SC2046,1091
source $(dirname "$0")/common
REV=${1}
cd "${STAGING_ROOT}/${CATEGORY_STUB}/${REV}"
cd "${STAGING_ROOT}/${CATEGORY_STUB}/${REV}" || { echo "Failed to change directory"; ret_val=1; exit 1; }
ret_val=$?
if [ $ret_val -eq "0" ]; then
TARGET="${PRODUCTION_ROOT}/${CATEGORY_STUB}/${REV:0:3}"
mkdir -p "${TARGET}"
sudo -l && find **/* -maxdepth 0 -type d | parallel --will-cite -j 18 sudo rsync -av --chown=10004:10005 --progress --relative --human-readable \
{} ${TARGET}
else
echo "Failed to change directory"
{} "${TARGET}"
fi

View File

@ -1,6 +1,7 @@
#!/bin/bash
# Source common variables
# shellcheck disable=SC2046,1091
source $(dirname "$0")/common
# Major Version (eg, 8)
@ -12,14 +13,12 @@ REV=${3}
# Note, this should be lowercase. eg, storage.
SIG=${4}
cd /mnt/compose/${MAJ}/latest-${SHORT}-${MAJ}
cd "/mnt/compose/${MAJ}/latest-${SHORT}-${MAJ}" || { echo "Failed to change directory"; ret_val=1; exit 1; }
ret_val=$?
if [ $ret_val -eq "0" ]; then
local TARGET=${STAGING_ROOT}/${CATEGORY_STUB}/${REV}/${SIG}
mkdir -p ${TARGET}
TARGET=${STAGING_ROOT}/${CATEGORY_STUB}/${REV}/${SIG}
mkdir -p "${TARGET}"
sudo -l && find **/* -maxdepth 0 -type d | parallel --will-cite -j 18 sudo rsync -av --chown=10004:10005 --progress --relative --human-readable \
{} ${TARGET}
else
echo "Failed to change directory"
{} "${TARGET}"
fi

View File

@ -1,6 +1,7 @@
#!/bin/bash
# Source common variables
# shellcheck disable=SC2046,1091
source $(dirname "$0")/common
# Major Version (eg, 8)
@ -10,14 +11,12 @@ SHORT=${2}
# The directory where we're going to, usually MAJOR.MINOR, sometimes it's MAJOR.MINOR-RCX
REV=${3}
cd /mnt/compose/${MAJ}/latest-${SHORT}-${MAJ}
cd "/mnt/compose/${MAJ}/latest-${SHORT}-${MAJ}" || { echo "Failed to change directory"; ret_val=1; exit 1; }
ret_val=$?
if [ $ret_val -eq "0" ]; then
local TARGET=${STAGING_ROOT}/${CATEGORY_STUB}/${REV}
mkdir -p ${TARGET}
TARGET="${STAGING_ROOT}/${CATEGORY_STUB}/${REV}"
mkdir -p "${TARGET}"
sudo -l && find **/* -maxdepth 0 -type d | parallel --will-cite -j 18 sudo rsync -av --chown=10004:10005 --progress --relative --human-readable \
{} ${TARGET}
else
echo "Failed to change directory"
{} "${TARGET}"
fi