#!/usr/bin/env bash # prefer to target .sh over BASH for wider compatibility # Designed for and tested on Ubuntu 24.04 LXC on Proxmox host # Using Proxmox Ubuntu 24.04 Standard AMD64 template # Prerequisites: # 1. Download Ubuntu 24.04 Standard AMD64 LXC template # 2. Create new LXC # - Minimum 4 cores # - Minimum 12GB RAM, 16GB recommended # - Minimum 32GB Disk space # - Recommend 64GB disk space or 24GB with additional mapped storage # - Unpriviliged container is acceptable # - AMD64 architecture # - Use 'ubuntu-24.04-standard_24.04-[any]_amd64' template # 3. Boot container and connect to shell # 4. Configure locales: `root@7dtd:~# dpkg-reconfigure tzdata` # 5. Update Ubuntu: `root@7dtd:~# apt update && apt upgrade -y` # 6. Reboot: `root@7dtd:~# reboot` # 7. Download and modify the settings template # - `root@7dtd:~# wget xx.yy.zz/ul-bootstrap.conf` # - `root@7dtd:~# nano ul-bootstrap.conf` # 8. Download and run the bootstrap script # - `root@7dtd:~# wget xx.yy.zz/bootstrap.sh` # check if root if [ "$EUID" -ne 0 ]; then echo "Must be run as root" exit fi set -eu if [ ! -z ${DEV+x} ] && [ "$DEV" -eq "1" ]; then # enable early debugging with `DEV=1 build.sh` set -x PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' else set -eu fi __SCRIPTARGS="$*" __SCRIPTNAME="devenv.sh" __SCRIPTFULLNAME="$0" # Common variables and functions _TRUE=1 _FALSE=0 # DOWNLOADS: Directory where build script will cache downloaded files DOWNLOADS="${DOWNLOADS:-download}" # TMP: Temporary working directory used by build script TMP="${TPM:-tmp}" # DEV_DIR: Directory where development environment is set up DEV_DIR="${DEV_DIR:-dev}" # OUT: Output directory for files generated by the script for the project OUT="${OUT:-out}" # OUT_FILES: List of files generated by these scripts OUT_FILES="${OUT_FILES:-bl_update_payload}" # name of BUP file generated by Nvidia script BUPFILE="${BUPFILE:-bl_update_payload}" # UPDATE_SCRIPT: Name of final update file used to distribute updates to Nano UPDATE_SCRIPT="${UPDATE_SCRIPT:-czup.sh}" #=============================================================================== #===== FUNCTIONS ===== #=============================================================================== #--- FUNCTION ---------------------------------------------------------------- # NAME: __cleanup # DESCRIPTION: Cleanup temporary files; disabled when devmode=true # USAGE: __cleanup #------------------------------------------------------------------------------- __cleanup() { if [ "$_DEV" -eq "$_FALSE" ]; then O_DIR="$(pwd)" cd "${WORK_DIR}" if [ -e "${TMP}" ]; then echo "Removing temporary files..." __sudo rm -rf "${TMP}" fi #if [ -e "Linux_for_Tegra" ]; then # echo "Removing Linux_for_Tegra directory..." # rm -rf "Linux_for_Tegra" #fi if [ -e "devicetree_binaries.tgz" ]; then __sudo rm "devicetree_binaries.tgz" fi if [ -e "tpm.tgz" ]; then __sudo rm "tpm.tgz" fi if [ -e "tpm-rng.tgz" ]; then __sudo rm "tpm-rng.tgz" fi if [ -e "${BUPFILE}" ]; then __sudo rm "${BUPFILE}" fi if [ -e "Module.symvers" ]; then __sudo rm "Module.symvers" fi cd "${O_DIR}" fi } #--- FUNCTION ---------------------------------------------------------------- # NAME: __check_command_exists # DESCRIPTION: Check if a command exists. # USAGE: if [!] (__check_command_exists [command]); then #------------------------------------------------------------------------------- __check_command_exists() { command -v "$1" > /dev/null 2>&1 } #--- FUNCTION ---------------------------------------------------------------- # NAME: __sudo # DESCRIPTION: Perform action as root. # USAGE: __sudo cp $a $b #------------------------------------------------------------------------------- __sudo() { sudo "$@" } #--- FUNCTION ---------------------------------------------------------------- # NAME: __env # DESCRIPTION: Print the environment variables to output # USAGE: __env #------------------------------------------------------------------------------- __env() { #echo "$(printenv)" #comm -3 <(comm -3 <(declare | sort) <(declare -f | sort)) <(env | sort) diff <(bash -cl 'set -o posix && set') \ <(set -o posix && set && set +o posix) | \ grep -E "^>|^\+" | \ grep -Ev "^(>|\+|\+\+) ?(BASH|COLUMNS|LINES|HIST|PPID|SHLVL|PS(1|2)|SHELL|FUNC)" | \ sed -r 's/^> ?|^\+ ?//' } #--- FUNCTION ---------------------------------------------------------------- # NAME: __wget # DESCRIPTION: Download if file doesn't exist. # USAGE: __wget [outfile] [url] # NOTES: if [outfile] exists, it will be tested to verify it is a regular file #------------------------------------------------------------------------------- __wget() { # check usage if [ -z "${1}" ] || [ -z "${2}" ]; then echo "__wget function usage:" echo " \$ __wget [outfile] [url]" exit 1 fi # Create the DOWNLOADS directory if it doesn't already exist if [ ! -d "${DOWNLOADS}" ]; then mkdir -p "${DOWNLOADS}" || ( echo "error creating \"${DOWNLOADS}\" directory" && exit 1 ) fi # test if [outfile] exists but is not a regular file # ie: [outfile] is device, directory, link, etc if [ -e "${DOWNLOADS}/${1}" ] && [ ! -f "${DOWNLOADS}/${1}" ]; then echo "__wget: [outfile] \"${DOWNLOADS}/${1}\" exists, but is not a regular file" exit 1 fi # download [outfile] if it doesn't already exist if [ ! -e "${DOWNLOADS}/${1}" ]; then if ! (__check_command_exists wget); then __sudo apt-get update || ( echo "Unable to update apt packages" && exit 1 ) __sudo apt-get install wget || ( echo "Unable to install wget" && exit 1 ) fi if [ -f "../${DOWNLOADS}/${1}" ]; then echo "Copying ${1}" cp -v "../${DOWNLOADS}/${1}" "${DOWNLOADS}/${1}" || ( echo "error copying ${1} from parent directory" && exit 1 ) else echo "Downloading ${1}" wget -q --show-progress -O "${DOWNLOADS}/${1}" "${2}" || ( echo "error downloading ${1}" && exit 1 ) fi fi } #--- FUNCTION ---------------------------------------------------------------- # NAME: realpath # DESCRIPTION: Cross-platform realpath command. Because Mac. #------------------------------------------------------------------------------- realpath() { perl -e 'use Cwd "abs_path";print abs_path(shift)' "$1" } #--- FUNCTION ---------------------------------------------------------------- # NAME: __usage # DESCRIPTION: Display program help # USAGE: __usage #------------------------------------------------------------------------------- __usage() { cat << EOT Usage: ${__SCRIPTNAME} [options] [action]... Actions: - dtb Build Devicetree binary files - blob Build Mass Flash tool to flash Nano over USB - bup Build Bootloader Update Package - tpm Build the TPM kernel modules - tpm-rng Build the TPM hardware random number generator module - pkg Build the update package to distribute to Nano - dev Enable development (debug) mode. Mainly, disables cleanup of temporary files created during program execution - all Same as ${__SCRIPTNAME} dtb bup tpm pkg blob Does not build the optional tpm-rng module - env Print list of variables and their values - help Display usage Options: -h Display this help -D Enable debugging mode Examples: - ${__SCRIPTNAME} all - ${__SCRIPTNAME} all dev - ${__SCRIPTNAME} dtb tpm bup EOT } #=============================================================================== #===== BEGIN ===== #=============================================================================== # cleanup existing temporary working directories; force regardless of _DEV option _DEV=$_FALSE __cleanup mkdir -p "${TMP}" #------------------------------------------------------------------------------- #----- Command Line Args ----- #------------------------------------------------------------------------------- _BLOB=${BLOB:-$_FALSE} _BUP=${BUP:-$_FALSE} _DTB=${DTB:-$_FALSE} _TPM=${TPM:-$_FALSE} _TPMRNG=${TPMRNG:-$_FALSE} _DEV=${DEV:-$_FALSE} _PKG=${PKG:-$_FALSE} # default option all if no options or actions specified if [ $# -eq 0 ]; then set -- "all" fi # restrict $_DEV values to $_TRUE or $_FALSE if [ "$_DEV" -eq "$_TRUE" ]; then _DEV=$_TRUE else _DEV=$_FALSE fi while getopts 'Dh-:' OPT; do # support long options: https://stackoverflow.com/a/28466267/519360 if [ "$OPT" = "-" ]; then # long option: reformulate opt and optarg OPT="${OPTARG%%=*}" # extract long option name OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) OPTARG="${OPTARG#=}" # if long option argument, remove assigning '=' fi case "${OPT}" in D ) echo "DEVELOPER MODE ENABLED"; _DEV=$_TRUE ;; h | help ) __usage; rm -rf "${TMP}"; exit 0 ;; ??* ) die "Illegal option --$OPT" ;; # bad long option ? ) exit 2 ;; # bad short option (error reported via getopts) esac done shift $((OPTIND-1)) while [[ "$#" -gt 0 ]]; do case $1 in env ) __env ;; all ) _DTB=$_TRUE; _BUP=$_TRUE; _TPM=$_TRUE; _PKG=$_TRUE; _BLOB=$_TRUE ;; dtb ) _DTB=$_TRUE ;; bup ) _BUP=$_TRUE ;; tpm ) _TPM=$_TRUE ;; pkg ) _PKG=$_TRUE ;; tpm-rng ) _TPMRNG=$_TRUE ;; dev ) _DEV=$_TRUE ;; help | --help ) __usage; exit 0 ;; esac shift done # Configure environment for debugging if [ "$_DEV" -eq "$_TRUE" ]; then set -x PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' else set -eu fi # TODO: bootstrap system from here # # 7dtd.sh package prerequisites described here: https://7dtd.illy.bz/wiki/Prerequisites # # verify packages: # - xmlstarlet # - expect # - lib32gcc-s1 # - lib32stdc++6 # - make # - gcc # # Should be available, but verify may be a good idea: # - wget # - rsync # - pkill # - netstat # - bash # - init system: either SysVInit or systemd # - cut, tr, tail, stdbuf # - grep, sed, dd, date, mkdir, touch, nc # # Should be compiled and installed from bootstrap: # - start-stop-daemon # # # Modify the 7dtd.illy script for our purposes # - # # Additional steps notes - unordered list # - Install steamcmd # - Install 7dtd Alpha 20.7 # - Download Undead Legacy # - Correct version for a20.7b1 is UL 2022.11.25 - 2.6.17 # - URL: https://ul.subquake.com/dl?v=stable # - default 'UndeadLegacyStable-main.zip' # - wget -O ul-20221125-v2.6.17.zip https://ul.subquake.com/dl?v=stable # - Script version v.115 is the historical version originally in use during Alpha 20 # - If using v.115, incorporate necessary future version features # - v.116 added pygmentize feature for printxml to print serverconfig.xml # - Current revision is v.118. v.118 might be usable or patchable for our purposes # - Enable bash completion # - Download the correct illy server fixes mod # - Per https://7dtd.illy.bz/wiki/Server%20fixes#a7DaystoDievsModversioncompatibility # - Correct version for Alpha 20.7 b1 is Mod version 22_24_39, SVN rev 370 # - URL: https://illy.bz/fi/7dtd/server_fixes_v22_24_39.tar.gz # - Extract UL to 7dtd engine directory (parent to Mods) # - copy BepInEx from .zip to engine/BepInEx # - copy Mods from .zip to engine/Mods # - copy doorstop_libs from .zip to engine/doorstop_libs # - copy doorstop_config.ini from .zip to engine/doorstop_config.ini # - copy run_bepinex_server.sh from .zip to engine/run_bepinex_server.sh # - Might also need to add to 7DaysToDieServer_Data/MonoBleedingEdge/etc/mono/config # - see https://ul.subquake.com/servers under Dedicated Server - Linux # - Create the serverconfig.xml, admins.xml, 7dtd.conf # # - Install steamcmd # - install 7dtd a20.7b1 # - install 7dtd.sh # - create 7dtd.conf # - install allocs server fixes # - install undead legacy # - configure server instance compatible with 7dtd.sh server manager # - create serverconfig.xml # - create admins.xml # # The goal of this project is to allow multiple different versions of 7DTD to run from the same server. # 7dtd.sh will need to be modified for this purpose # 7dtd.sh will also need to be made compatible to manage the undead legacy mod # #