joeybuild/joeybuild.sh

309 lines
7.3 KiB
Bash
Executable file

#!/bin/bash -e
#
# JoeyBuild
# Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
#
# 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.
G_TARGET= # Current target.
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}"
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=
G_TARGET=${_MODULE}
_VALUE="$( source ${G_EHOME}/targets/${_MODULE}.target && ${_FUNCTION} ${_ARGS} )"
G_TARGET=
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() {
git config --global user.email "no-reply@kangaroopunch.com"
git config --global user.name "JoeyBuild VM Installer"
updateSystem
configureSFTP
withTargets install "Installing SDK"
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() {
# 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
withTargets buildJoeyLib "Building JoeyLib"
mkdir -p dist
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
# 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}"
# 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-get update
tSudo apt-get -y upgrade
tSudo apt-get -y dist-upgrade
# Shut Canonical up.
tSudo pro config set apt_news=false
#***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 ACTION="$2"
local ARGS=${*:3}
local PASS=
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
for PASS in "debug" "release"; do
tBoldBox tPURPLE "${ACTION} ${NAME} ${ARCH} (${PASS})..."
G_TARGET=${NAME}
G_INSTALLED=${G_EHOME}/installed/${NAME}-${ARCH}/${PASS}
G_DIST=dist/${G_TARGET}-${ARCH}/${PASS}
call RESULT ${NAME} ${FUNCTION} ${ARCH} ${PASS} ${ARGS}
G_DIST=
G_INSTALLED=
G_TARGET=
done
done
fi
done
}
# At the very end so we can stream this script from a web server.
startup $@ # 2>&1 | tee lastrun.log