#!/bin/bash -e # # JoeyBuild # Copyright (C) 2018-2023 Scott Duensing # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. # # # This is intended to be used on a clean install of ubuntu-20.04.x-live-server-amd64.iso # G_EHOME="$(getent passwd $(logname) | cut -d: -f6)" # Home for this user. G_SRC="${G_EHOME}/joeylib/joeylib/src" # Location of JoeyLib source. G_TEMP="${G_EHOME}/temp" # Directory to store temporary data. G_TITLE="JoeyBuild" # Title of application. G_ORIGINAL_PATH=${PATH} # Original system path. function addBuildUser() { local USER=$1 local PASS=$2 local SALT=$(LC_ALL=C tr -cd "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" < /dev/urandom | head -c 8) local CRYPT=$(perl -e 'print crypt($ARGV[0], $ARGV[1])' ${PASS} ${SALT}) tSudo useradd -m -G sftponly -s /sbin/false -p "${CRYPT}" "${USER}"e tSudo chown root:root /home/${USER} tSudo chmod 755 /home/${USER} tSudo mkdir -p /home/${USER}/build tSudo chown ${USER}:${USER} /home/${USER}/build tSudo chmod u+rwX /home/${USER}/build tSudo chmod go-rwx /home/${USER}/build } function call() { local _RESULT=$1 local _MODULE=$2 local _FUNCTION=$3 local _ARGS=${*:4} local _VALUE= _VALUE="$( source ${G_EHOME}/targets/${_MODULE}.target && ${_FUNCTION} ${_ARGS} )" eval $_RESULT=\${_VALUE} } function configureSFTP() { if [[ ! -f /etc/ssh/sftponly_ready ]]; then tSudo addgroup sftponly || true tSudo sed -i 's/^Subsystem/#Subsystem/g' /etc/ssh/sshd_config echo "Subsystem sftp internal-sftp -f AUTH -l VERBOSE" | tSudo tee -a /etc/ssh/sshd_config echo "Match Group sftponly" | tSudo tee -a /etc/ssh/sshd_config echo -e "\tChrootDirectory %h" | tSudo tee -a /etc/ssh/sshd_config echo -e "\tForceCommand internal-sftp" | tSudo tee -a /etc/ssh/sshd_config echo -e "\tAllowTcpForwarding no" | tSudo tee -a /etc/ssh/sshd_config echo -e "\tX11Forwarding no" | tSudo tee -a /etc/ssh/sshd_config tSudo systemctl restart sshd tSudo touch /etc/ssh/sftponly_ready fi } function delBuildUser() { local USER=$1 tSudo userdel -f -r ${USER} } function doBuild() { true } function doInstall() { # Do we have an automation file? if [[ ! -f "${G_EHOME}/automated.install" ]]; then tBoldBox tRED "Cannot find automated.install file!" exit 1 fi source "${G_EHOME}/automated.install" tSudoSetPassword "${AUTOMATED_SUDO}" git config --global user.email "no-reply@kangaroopunch.com" git config --global user.name "JoeyBuild VM Installer" updateSystem configureSFTP withTargets install rebuildJoeyLib # Start build server on reboot. if [[ ! -f /etc/rc.local ]]; then echo "#!/bin/bash" | tSudo tee /etc/rc.local > /dev/null echo "${BASH_SOURCE[0]} server ${G_EHOME}/dist ${G_EHOME}/builds.log &> /dev/null &" | tSudo tee -a /etc/rc.local > /dev/null echo "exit 0" | tSudo tee -a /etc/rc.local > /dev/null fi } function rebuildJoeyLib() { local TARGET= local RESULT= local NAME= local ARCHS= local ARCH= local PASS= # Do we have JoeyLib yet? if [[ ! -f ${G_EHOME}/joeylib/LICENSE ]]; then tBoldBox tBLUE "Downloading JoeyLib source..." git clone https://skunkworks.kangaroopunch.com/skunkworks/joeylib.git ${G_EHOME}/joeylib &> /dev/null fi for TARGET in ${G_EHOME}/targets/*.target; do NAME=$(basename -s .target ${TARGET}) call RESULT ${NAME} enabled if [[ ${RESULT} -eq 1 ]]; then call ARCHS ${NAME} architectures for ARCH in ${ARCHS}; do rm -rf dist/${NAME}-${ARCH} || true for PASS in "debug" "release"; do tBoldBox tPURPLE "Building JoeyLib ${NAME} ${ARCH} (${PASS})..." mkdir -p dist/${NAME}-${ARCH}/${PASS} pushd dist/${NAME}-${ARCH}/${PASS} call RESULT ${NAME} buildJoeyLib ${ARCH} ${PASS} popd done done fi done cp -f ${G_SRC}/joey.h dist/. mkdir -p dist/3rdparty/memwatch cp -f ${G_SRC}/3rdparty/memwatch/* dist/3rdparty/memwatch/. } function startup() { local ARGS=$@ local ACTION=$1 local NAME="$(basename $0)" # Do we have Towel yet? if [[ ! -f "${G_EHOME}/towel/towel.sh" ]]; then # Do we have GIT? if [[ "$(which git || true)" == "" ]]; then echo "Installing git..." #***TODO*** This should be the only use of non-Towel sudo. sudo apt-get -y install git fi echo "Downloading towel.sh support library..." git clone https://skunkworks.kangaroopunch.com/skunkworks/towel.git "${G_EHOME}/towel" &> /dev/null fi # Load Towel source "${G_EHOME}/towel/towel.sh" # Give Towel a chance to handle arguments. tArgsHandler ${ARGS} # Anything after this, don't run as root. if [[ ${EUID} -eq 0 ]]; then echo "Do not run this script as root." exit 1 fi # Be sure we can silently sudo. (for mountORCA) tSudo case ${ACTION} in add) addBuildUser "${2}" "${3}" ;; build) doBuild "${2}" "${3}" ;; del) delBuildUser "${2}" ;; install) doInstall "${2}" "${3}" ;; rebuild) rebuildJoeyLib ;; server) startBuildServer "${2}" "${3}" ;; *) #set +x tBoldBox tGREEN "${G_TITLE} Options" echo "${NAME} add USER PASS" echo "${NAME} build DIST SRC" echo "${NAME} del USER" echo "${NAME} install" echo "${NAME} rebuild" echo "${NAME} server DIST LOG" #set -x ;; esac } function startBuildServer() { true } function updateSystem() { local MISSING= tBoldBox tBLUE "Examining system..." tSudo apt update tSudo apt -y upgrade tSudo apt -y dist-upgrade #***TODO*** Split this into target modules. tSudo dpkg --add-architecture i386 tCheckPackages MISSING \ attr \ autoconf \ bison \ build-essential \ bzip2 \ clang \ cmake \ cpio \ flex \ gawk \ gcc-multilib \ git \ gzip \ libbz2-dev \ liblzma-dev \ libssl-dev \ libxml2-dev \ libzstd-dev \ llvm \ mingw-w64 \ mtools \ nasm \ patch \ php-cli \ sed \ unzip \ uuid-dev \ xz-utils \ zlib1g-dev \ genisoimage \ jfsutils \ msitools \ ragel if [[ "${MISSING}" != "" ]]; then tSudo apt-get -y install ${MISSING} fi } function withTargets() { local FUNCTION=$1 local ARGS=${*:2} local TARGET= local RESULT= local NAME= local ARCHS= local ARCH= for TARGET in ${G_EHOME}/targets/*.target; do NAME=$(basename -s .target ${TARGET}) call RESULT ${NAME} enabled if [[ ${RESULT} -eq 1 ]]; then call ARCHS ${NAME} architectures for ARCH in ${ARCHS}; do call RESULT ${NAME} ${FUNCTION} ${ARCH} ${ARGS} done fi done } # At the very end so we can stream this script from a web server. startup $@