Skip to content

Instantly share code, notes, and snippets.

@floffel
Created November 12, 2018 18:30
Show Gist options
  • Select an option

  • Save floffel/4372ddba35b09cfb46b32013957025ed to your computer and use it in GitHub Desktop.

Select an option

Save floffel/4372ddba35b09cfb46b32013957025ed to your computer and use it in GitHub Desktop.
transform an "mtemplate.sh" created jail into a thin-jail-template
#!/bin/sh
##########################################################
# Make me a thin jail template #
# Written by Florian Minnecker on 03.11.2018 at 11:34 #
##########################################################
# This script takes a normal template an creates a
# thin-jail-template out of it.
#
# This script assumes that you have a directory structure
# like this - if not, you will need to provide cli args
# redundan/jailtemplates
##########################################################
# Changelog:
# 12.11.2018: written...
##########################################################
# TODOS:
# + Implement some more tests e.g. test for zfs mountpoint
##########################################################
# based pretty much on this great walkthrough:
# https://clinta.github.io/freebsd-jails-the-hard-way/
# defaults. Can be overwritten by arguments
SOURCE="redundant/jailtemplates/11.2-RELEASE"
DESTINATION="zroot/thinjailtemplates"
UI="false"
# internal vars
VERSION="" # will get the last part of the source path id as value
CLEANUP_STEPS="" # will be a complete list of: "root" "destination"
PUSHD=""
ABORT="false"
#*** GENERAL HELPER FUNCTIONS ***
usage() {
cat << EOH
Usage: $0 [OPTIONS]
Takes your template and creates an thin-jail-template. Falls back to the dialog.
Note: destination will get the last path of the source appended.
Options:
--source string Source of the base template that will be transformed
--destination string Destination where to write the skeleton template (default "$DESTINATION")
--version string Set the Version manually
EOH
}
getArgs() {
while [ $# -gt 0 ]; do
k="$1"
shift
case "$k" in
--source|-s)
echo "set source to $1"
SOURCE="$1"
shift
;;
--destination|-d)
echo "set destination to $1"
DESTINATION="$1"
shift
;;
-h|--help|help)
echo "showing help"
usage
#$($0 -h);
exit 0
;;
*)
echo "undefined key: $k";
;;
esac
done
}
checkArgs() {
if [ -z "$SOURCE" ]; then
echo 'Argument "source" is mandatory.'
usage
exit 0
fi
if [ -z "$VERSION" ]; then
VERSION=`echo "$SOURCE" | awk -F"/" ' { print $NF } '`
fi
# todo simplify and exernalize the following
# todo2 check or set / on the left of the path
# if [ ! -d "$SOURCE" ]; then
# if [ -d "/${SOURCE}" ]; then
# SOURCE="/${SOURCE}"
# fi
# fi
# if [ ! -d "$DESTINATION" ]; then
# if [ -d "/${DESTINATION}" ]; then
# DESTINATION="/${DESTINATION}"
# fi
# fi
}
#*** MAIN HELPER FUNCTIONS ***
pushd() {
POPD="$PWD $POPD"
cd "$1"
}
popd() {
i=0
for p in $POPD; do
if [ "$i" -eq 0 ]; then
POPD=" "
cd "$p"
else
POPD="$POPD $p"
fi
done
}
# TODO: implemet this as a dialog.. :)
errorReader() {
echo "Shall we continue? Press [ENTER] for yes, [CTRL][C] to abort."
read ab
}
mkZfsRoot() {
# check if the ZfsRoot is a normal file system..
# todo: check if we need to do a "zfs create -p"
if [ -e "${DESTINATION}/${VERSION}" ] || [ `zfs list | awk -v s="${DESTINATION}/${VERSION}" ' NR>1 { if( s == $1 ) { print $1 } } '` ]; then
echo "ZFS Root exists..."
errorReader
else
zfs create -p -o compress=lz4 "${DESTINATION}/${VERSION}"
CLEANUP_STEPS="ZFS_ROOT $CLEANUP_STEPS"
fi
}
rmZfsRoot() {
if [ `zfs list | awk -v s="${DESTINATION}/${VERSION}" ' NR>1 { if( s == $1 ) { print $1 } } '` ]; then
zfs destroy "${DESTINATION}/${VERSION}"
else
echo "ZFS destroy called but none of my created volumes available to destory. Destroy manually: ${DESTINATION}/${VERSION}"
fi
}
transformTemplate() {
mkdir -p "/${DESTINATION}/${VERSION}/usr/ports/distfiles" "/${DESTINATION}/${VERSION}/home" "/${DESTINATION}/${VERSION}/portsbuild"
pushd "/$SOURCE"
chflags noschg ./var/empty
for d in "etc" "usr/local" "tmp" "var" "root"; do
mv "./${d}" "/${DESTINATION}/${VERSION}/${d}"
done
chflags schg /${DESTINATION}/${VERSION}/var/empty
mkdir skeleton
ln -s skeleton/etc etc
ln -s skeleton/home home
ln -s skeleton/root root
ln -s skeleton/usr/local usr/local
ln -s skeleton/usr/ports/distfiles usr/ports/distfiles
ln -s skeleton/tmp tmp
ln -s skeleton/var var
#touch etc/make.conf
#echo "WRKDIRPREFIX?= /skeleton/portbuild" >> etc/make.conf
popd
CLEANUP_STEPS="TRANSFORM $CLEANUP_STEPS"
}
rmTransformTemplate() {
pushd "/${DESTINATION}/${VERSION}"
for d in "etc" "usr/local" "tmp" "var" "root"; do
mv "./${d}" "/${SOURCE}/${d}"
done
popd
pushd "/$SOURCE"
rm -Rf skeleton
popd
}
leave() {
echo "*** Starting cleanup Tasks ***"
echo "CLEANUP_STEPS= $CLEANUP_STEPS"
abort="$1"
for i in $CLEANUP_STEPS; do
case "$i" in
TRANSFORM)
if [ "$abort" == "true" ]; then
rmTransformTemplate
fi
;;
ZFS_ROOT)
if [ "$abort" == "true" ]; then
rmZfsRoot
fi
;;
*)
echo "unknown cleanup command... $i"
;;
esac
done
}
signal_handler() {
echo "aborting."
leave "true"
exit
#signal(SIGINT, SIG_DFL);
#kill(getpid(), SIGINT);
}
#** init trap **
trap signal_handler INT
#*** MAIN ***
getArgs
checkArgs
if [ "$UI" == "true" ]; then
# todo: start a fancy dialog
echo "UI not implemented yet. Feel free to do so.."
else
mkZfsRoot
transformTemplate
fi
leave
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment