#!/bin/bash # CALL SUBSHELL _subshell() { echo -e "\e[33mCalling bash subshell\e[0m" sleep 2 echo 'echo -e "\e[33mInside Subshell\e[0m"' >> /root/.bashrc echo 'echo -e "\e[33mExit to return back to parent\e[0m"' >> /root/.bashrc (clear; exec /bin/bash;) sed -i "/Inside Subshell/d" "/root/.bashrc" sed -i "/Exit to return back to parent/d" "/root/.bashrc" echo -e "\e[33mYou are back to parent\e[0m" } parameters_check() { if echo "$@" | grep -q '\--force-new' && ( ( echo "$@" | grep -q '\--lawful-good' || echo "$@" | grep -q '\-lg' ) ); then die "Warning: --force-new suppresses --lawful-good" sleep 2 fi if echo "$@" | grep -q '\--force-new' && echo "$@" | grep -q '\--enforce'; then _e_report_back "Warning: --force-new implies --enforce=*" sleep 2 fi if [[ "$(echo "$@" | grep '\--verbose')" || "$(echo "$@" | grep '\-v')" ]] && ! echo "$@" | grep -q '\--auto=yes'; then die "Error: Verbose & interactive mode can not be set at the same time. To use verbose, please set --auto=yes" fi if [[ "$(echo "$@" | grep '\--quiet')" || "$(echo "$@" | grep '\-q')" ]] && [[ "$(echo "$@" | grep '\--verbose')" || "$(echo "$@" | grep '\-v')" ]]; then die "Error: verbose & quiet can not be set at the same time" fi if echo "$@" | grep -q '\--lawful-good' && echo "$@" | grep -q '\--enforce'; then _e_report_back "Warning: --lawful-good suppresses --enforce" fi if echo "$@" | grep -q '\--force-new' && echo "$@" | grep -q '\--keep'; then die "Warning: --force-new suppresses --keep. This combination is know to give unexpected results." fi if echo "$@" | grep -q '\--health-check' && [[ "$#" != 1 ]]; then die "Warning: --health-check unknown parameters ${*:2}" fi if echo "$@" | grep -q '\--replace-new' && [[ "$#" != 1 ]]; then die "Warning: --replace-new: unknown parameters ${*:2}" fi if echo "$@" | grep -q '\--build-minimal' && echo "$" | grep -q '\--enforce' | grep -q 'gkernel'; then _e_report_back "Warning: --build-minimal suppresses kernel build {gkernel}" sleep 2 fi if echo "$@" | grep -q '\--build-minimal' && echo "$@" | grep -q '\--enforce' | grep -q 'ginitrd'; then _e_report_back "Warning: --build-minimal suppresses initramfs {ginitrd}" sleep 2 fi if echo "$@" | grep -q '\--build-minimal' && echo "$@" | grep -q '\--enforce' | grep -q 'ginst'; then _e_report_back "Warning: --build-minimal suppresses custom package installation {ginst}" sleep 2 fi } set_x() { if [[ "${_flag_verbose}" ]]; then set -x fi } die() { echo -e "\e[31m$*\e[0m" 1>&2 ; exit 1 } burn() { inspector "$@" # If keep flag is on, make a backup, then proceed with purge if [[ -n "${_flag_keep}" ]]; then if _keep "$(basename "$1")" "$1"; then echo -e "\e[31mPurging...\e[0m" if [[ -d "$1" ]]; then rm -rf "$1" else rm -f "$1" fi else die "Backup failed" fi else echo -e "\e[31mPurging...\e[0m" if [[ -d "$1" ]]; then rm -rf "$1" else rm -f "$1" fi fi } _keep(){ inspector "$@" # Create a date entry directory _date_var="$(date '+%y-%m-%d')" if [[ ! -e "/var/tmp/gse/${_date_var}" ]]; then mkdir -p "/var/tmp/gse/${_date_var}" fi _e_report_back "The keep flag has been detected." _e_report_back "Making backup of, $1 before proceeding with purging" if [[ -d "$2" ]]; then eval tar czvf "/var/tmp/gse/${_date_var}/$1.tar.bz2" "$2" "${_flag_silence}" \ && return 0 || return 1 elif [[ ! -d "$2" ]]; then cp "$2" "/var/tmp/gse/${_date_var}/$1" fi } _e_report_back() { echo -e "\e[33m$*\e[0m" 1>&2 } _o_report_back() { echo -e "\e[34m$*\e[0m" 1>&2 } inspector() { [[ -z "$*" ]] && print_inf_f } pass() { echo -e "[\e[34mDone\e[0m]" } print_inf_f() { clear echo -e "[\e[31mFATAL\e[0m]" echo -e "\e[31mIf this message is printed while using the Maim Menu\e[0m" echo -e "\e[31mThat means essential files are altered or something bad is happening.\e[0m" echo echo -e "\e[31mPlease run a health-check from the ~Main Menu~ and a Version check first.\e[0m" echo -e "\e[31mIf you see this again after the health/version check, please submit a bug report\e[0m" echo -e "\e[31mand stop using the program, or data loss may occur.\e[0m" echo echo -e "\e[31mExiting...\e[0m" exit 1 } help_f() { echo "Gentoo Stateless Environment, version: ${GSEVER}" echo "Distributed under the GNU General Public License, V2" echo "usage: gse [OPTIONS] / " echo echo " --time-state[?/=state_name] :Creates a state with the given option. Can be used from time-warp," echo " by it's state mark (^N). To view states use --time-state?" echo " and to delete states, use --time-state=-N" echo echo " --time-warp=[state's mark] :Calls a given state by it's mark (^N). The process is initiated " echo " as all arguments and configurations were passed at that given time." echo echo " --distcc=[on/pump] :Enable distcc for chroot phase with on/pump entry" echo " --ccache=[on{2G}/size{G}] :Enable ccache with on entry" echo " --auto=[yes/no] :Enable/Disable interactive mode with yes/no" echo echo "-fe --fetch-new :Fetch new flag, will force new downloads for portage/stage3 tarball" echo "-ns --start-new :Enables a global force flag. Everything starts from scratch" echo "-lg --lawful-good [hook point] :Stays passive on give part. Passive parts are skipped" echo "-ef --enforce [hook point] :Force a given part. If work is done, it will be purged." echo "-h --help :Call help menu and exit" echo "-k --keep :Keep flag. This flag saves old work to /var/tmp/gse/work-date" echo "-hc --health-check :Check for modified/corrput/lost files" echo "-rpn --replace-new :Replaces all core scripts and configuration files with default" echo "-nk --[no]-kernel={kernel_image} :Enable/disable kernel build. You can also give a prebuild kernel" echo "-ni --[no]-initramfs={initrd_image} :Enable/disable initramfs build. You can also give a prebuild image" echo "-bc --build-controller={kernel moddir} :This option will build the controller of gse project." echo "-bm --build-minimal :Builds a minimal system. It will be very close to a minimal s3 tb" echo "-v --verbose :Enables verbose output" echo "-q --quiet :Enables quiet mode. This imput enables a global silence flag." echo } _callying_catalyst(){ inspector "$@" echo -e "\e[34mCalling catalyst\e[0m" source "${CWORKDIR}/scripts/functions/init_stage3_seq" "$@" \ || return 1 } _extracting_catalyst() { CATDIR=$(grep storedir "${CCONFDIR}/system/catalyst/catalyst.conf" \ | sed '/^#/ d' | awk -F '=' '{ print $2 }' | sed -e "s_\"__g") \ && SNAPSHOTNAME="$(grep 'snapshot:' "${CCONFDIR}/system/catalyst/stage1.spec" \ | sed '/^#/ d' | sed '/^\s*$/d' | awk -F ' ' '{ print $2 }' | sed -e "s_\"__g")" \ && TARGETPATH="$(grep 'source_subpath' "${CCONFDIR}/system/catalyst/stage3.spec" \ | sed '/^#/ d' | awk -F ' ' '{ print $2 }' | sed -e "s_\"__g" | awk -F '/' '{ print $1 }')" \ && TARGETSTAMP="$(grep 'version_stamp' "${CCONFDIR}/system/catalyst/stage3.spec" \ | sed '/^#/ d' | awk -F ' ' '{ print $2 }' | sed -e "s_\"__g")" \ && _workdir_check "${CATDIR}/builds/${TARGETPATH}/stage3-${ARCH}-${TARGETSTAMP}.tar.bz2" \ "${CDISTDIR}/workdir-catalyst" \ "${CATDIR}/snapshots/portage-${SNAPSHOTNAME}.tar.bz2" "$@" \ || return 1 } sinit_flow_monitor() { # PROCESS FLOW TWEAKER DURING ALL BUT CHROOT STAGE. DO NOT EDIT THIS FILE! case "$1" in EXTRACTION) sed -i -e 's/EXTRACTION=0/EXTRACTION=1/g' "${CLOCALLG}/sinprog";; RESET) sed -i -e 's/1/0/g' "${CLOCALLG}/sinprog";; SEED) sed -i -e 's/SEED=0/SEED=1/g' "${CLOCALLG}/sinprog" sed -i -e 's/CHECK=0/CHECK=1/g' "${CLOCALLG}/sinprog";; PARTA) sed -i -e 's/PARTA=0/PARTA=1/g' "${CLOCALLG}/sinprog";; PARTB) sed -i -e 's/PARTB=0/PARTA=1/g' "${CLOCALLG}/sinprog";; CATALYST) sed -i -e 's/CATALYST=0/CATALYST=1/g' "${CLOCALLG}/sinprog";; PRECOMP) sed -i -e 's/PRECOMP=0/PRECOMP=1/g' "${CLOCALLG}/sinprog";; RDEP) sed -i -e 's/RDEP=0/RDEP=1/g' "${CLOCALLG}/sinprog";; dn) ;; esac } # RDEP CHECK _dependencies_check() { if [[ "${CREL}" == "Gentoo" ]]; then echo -e "\e[33mHost system:\e[0m \e[35m${CREL}\e[0m" echo -e "\e[33mBefore you begin, it is strongly recommended to make a\e[0m \e[35mruntime dependency\e[0m \e[33mcheck on the host machine\e[0m" echo -e "\e[33mThis check is a simple\e[0m \e[35meix\e[0m \e[33m--installed foo check, which will be very fast and also verify\e[0m" echo -e "\e[33mthat during the process, nothing unexpected will occur\e[0m" echo -e "\e[33mIf\e[0m \e[35meix\e[0m \e[33mis not installed, do no worry, it will get installed\e[0m" echo while true; do echo -e "\e[33mCheck dependencies? Y/N: \e[0m" read -rp "Input :: <= " YN case "${YN}" in [yY]) echo -e "\e[34mChecking for dependencies\e[0m" _lcreq 1 || die break;; [nN]) _e_report_back "If you have not run a dependency check before, please abort" break;; esac done unset YN else echo -e "\e[33mHost system:\e[0m \e[33m${CREL}\e[0m" echo -e "\e[33mBefore you begin, it is strongly recommended to make a\e[0m \e[35mruntime dependency\e[0m \e[33mcheck on the host machine\e[0m" echo -e "\e[33mIf the all runtime dependencies are located, the process will continue, otherwise this window will exit. and expect you to manually install them\e[0m" echo -e "\e[33mSince only Gentoo is officially upported, it is expected to manually install any missing dependencies\e[0m" while true; do echo "Check dependencies? Y/N: " read -rp "Input :: <= " YN case "${YN:-n}" in [yY]) echo -e "\e[34mChecking for dependencies\e[0m" _lcreq 2 die break;; [nN]) echo "If you have not run a dependency check before, please abort" for i in {1..5}; do sleep 1 printf "\r $i" done break;; esac done fi unset YN } _pseudo_check_purge(){ [[ -n "$(grep "dist.d/workdir-" "/proc/mounts" | awk -F ' ' '{ print $2 }')" ]] \ && while true; do while read -r i; do eval umount -l "$i"/* >/dev/null 2>&1 eval umount -l "$i" >/dev/null 2>&1 done < <(grep 'dist.d/workdir-' "/proc/mounts" | awk -F ' ' '{ print $2 }') [[ -z $(grep "dist.d/workdir-" "/proc/mounts" | awk -F ' ' '{ print $2 }') ]] \ && break done if [[ -n "$*" && -z "$(cat /proc/mounts | grep "workdir-$2")" ]]; then if [[ -e "$1" ]]; then echo -e "\e[34mMarking workdir for purge\e[0m" burn "$1" fi else print_inf_f fi } _start_again() { set +x # PROMPT TO CONTINUE OR START ANEW if ! echo "$@" | grep -q 'force'; then while true; do echo -e "\e[33mDo you want to continue from last time?\e[0m" echo -e "\e[33mIf you choose\e[0m \e[31mSTART NEW\e[0m\e[33m, workdir will be\e[0m \e[31mpurged\e[0m" echo -e "\e[33mAnswer Yes or START NEW: \e[0m" read -p "Input :: <= " YN echo case "${YN:-n}" in [Yy][eE][sS]|[yY]) break;; "START NEW") echo -e "\e[33mChecking...\e[0m" _pseudo_check_purge "$1" \ && sinit_flow_monitor "RESET" && sed -i -e 's/1/0/g' "${CWORKDIR}/scripts/chroot_scripts/chsinprog"; break;; * ) echo "Wrong answer";; esac done elif echo "$@" | grep -q 'force'; then echo -e "\e[31mForce is active!\e[0m" echo -e "\e[34mResetting\e[0m" _pseudo_check_purge "$1" \ && sinit_flow_monitor "RESET" && sed -i -e 's/1/0/g' "${CWORKDIR}/scripts/chroot_scripts/chsinprog" fi unset YN set_x } _extract_tarball() { [[ -z "$*" && -d "$2" ]] && die "Wrong Parameters" mkdir -p "$2" echo -e "\e[34mExtracting tarball\e[0m" if eval tar xvjpf "$1" -C "$2" --xattrs --numeric-owner "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Extracted" if echo "${_flag_base}" | grep -q 'catalyst'; then echo -e "\e[34mExtracting portage\e[0m" if eval tar xvjpf "$3" --xattrs --numeric-owner -C "$2/usr/" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Extracted" else die "Extracting portage FAILED" fi fi else die "Extracting tarball FAILED" fi } _workdir_check() { [[ -z "$*" && -d "$2" ]] && die "Wrong Parameters" if echo "$@" | grep -q 'force'; then _e_report_back "This may take some time" _e_report_back "Checking..." _pseudo_check_purge "$2" _extract_tarball "$@" else if [[ -d "$2" ]]; then if ! echo "$@" | grep -q '_flag_auto'; then while true; do echo -e "Seems that there already has been done some work at the \e[34mbuilderdir\e[0m" echo "You could either continue from where you left, or backup/purge then start anew" echo -e "Give one of: \e[32mCONTINUE\e[0m/\e[34mOLD\e[0m/\e[31mPURGE\e[0m " read -rp "Input :: <= " ANS case $ANS in OLD) echo "Backing up..." mv "$2" "$2.old" _extract_tarball "$@" break;; PURGE) _e_report_back "This may take some time" _e_report_back "Checking..." _pseudo_check_purge "$2" _extract_tarball "$@" break;; CONTINUE) break;; esac done fi else _extract_tarball "$@" fi fi } _am_i_root() { if [[ "$1" != "0" ]] then echo -e "\e[31mThis operation requires root privileges\e[0m" echo "Returning back..." sleep 2 BACKTO="MM" return 1 fi return 0 } _export_latest() { GENTOOKEY="$(lynx -dump ${SIGNING_KEY} | grep "(4096-bit RSA)" | head -1 | awk -F '(' '{ print $1}')" export GENTOOKEY GENTOOLATEST="$DIST/$(wget -q -O- "${DIST}/latest-stage3-$ARCH.txt" | tail -n 1 | awk -F ' ' '{ print $1 }')" export GENTOOLATEST STAGE3TB=$(wget -q -O- "${DIST}/latest-stage3-$ARCH.txt" | tail -n 1 | awk -F ' ' '{ print $1 }' | awk -F '/' '{ print $2 }') export STAGE3TB GENTOOLATESTASC="$DIST/$(wget -q -O- "${DIST}/latest-stage3-$ARCH.txt" | tail -n 1 | awk -F ' ' '{ print $1 }').DIGESTS.asc" export GENTOOLATESTASC } _gentoo_key() { [[ -z "${GENTOOKEY}" ]] && die "Wrong Parameters" && return 1 if eval gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys "${GENTOOKEY}" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m]\e[32m Fetching Key\e[0m" else echo -e "[\e[31m*\e[0m]\e[31m Fetching Key\e[0m" return 1 fi } _get_latest() { inspector "$@" [[ -z "${GENTOOLATEST}" || -z "${GENTOOLATESTASC}" ]] && die "Wrong Parameters" && return 1 mkdir -p "${CDISTDIR}/dists" if [[ -n "${_flag_fetch}" ]] || echo "$@" | grep -q 'force'; then echo -e "[\e[34m*\e[0m] Marking stage3-${ARCH}-latest.tar.bz2 for purging" burn "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2" echo -e "[\e[34m*\e[0m] Marking stage3-${ARCH}-latest.tar.bz2.DIGESTS.asc for purging" burn "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2.DIGESTS.asc" echo -e "[\e[34m*\e[0m] Marking stage3-${ARCH}-latest.tar.bz2.DIGESTS for purging" burn "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2.DIGESTS" echo -e "[\e[32m*\e[0m] Fetching \e[34m${STAGE3TB}\e[0m" if eval wget -c -O "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2" "${GENTOOLATEST}" "${_flag_silence}"; then echo "${STAGE3TB}" > "${CDISTDIR}/dists/latest.info" pass else die "FAILED" fi else echo -e "[\e[32m*\e[0m] Fetching \e[34m${STAGE3TB}\e[0m" if wget -c -O "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2" "${GENTOOLATEST}"; then echo "${STAGE3TB}" > "${CDISTDIR}/dists/latest.info" pass else die "FAILED" fi fi if eval wget -c -O "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2.DIGESTS.asc" "${GENTOOLATESTASC}" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Fetching \e[34m${GENTOOLATEST}\e[0m" else echo -e "[\e[31m*\e[0m] \e[31mFAILD\e[0m: Fetching \e[34m${GENTOOLATEST}\e[0m" die fi if eval wget -c -O "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2.DIGESTS" "${GENTOOLATEST}.DIGESTS" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Fetching \e[34m${GENTOOLATEST}.DIGESTS\e[0m" else echo -e "[\e[31m*\e[0m] \e[31mFAILD\e[0m: Fetching $\e[34m${GENTOOLATEST}.DIGESTS\e[0m" die fi } _verify_download() { if eval gpg --verify "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2.DIGESTS.asc" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Verifying \e[35mcryptographic signature\e[0m" else echo -e "[\e[31m*\e[0m] \e[31mFAILD\e[0m: Verifying \e[31mcryptographic signature\e[0m" die fi [[ $(grep -A 1 -i sha512 "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2.DIGESTS.asc" | head -n 2 | grep stage3 | awk -F ' ' '{ print $1 }') \ == $(sha512sum "${CDISTDIR}/dists/stage3-${ARCH}-latest.tar.bz2" | awk -F ' ' '{ print $1 }') ]] \ && echo -e "[\e[32m*\e[0m] Verifying \e[35msha512sums\e[0m" \ || { echo -e "[\e[31m*\e[0m] \e[31mFAILD\e[0m: Verifying \e[31msha512sums\e[0m"; exit 1; } } _call_fetch_new() { source "${CWORKDIR}/scripts/functions/catalyst_functions" || { echo -e "\e[32mMissing scripts\e[0m" && exit 1; } _fetch_new "$@" _get_latest_snapshot "$@" } _call_force_new() { while true; do echo -e "\e[31mForce new parameter detected\e[0m" echo -e "\e[31mThis option will force everything and purge what stands in its way\e[0m" echo -e "\e[31mAre you sure? Y/N \e[0m" read -rp "Input :: <= " YN case "${YN:-n}" in [yY]) if [[ -z $(echo "$@" | grep 'gcat') && -z $(echo "$@" | grep 'catalyst') ]]; then source "${CWORKDIR}/scripts/sinit" "$@" fi break;; [nN]) exit 0;; esac done } _fetch_new() { # CHECK FOR THE POSITIONAL PARAMETERS AND BAILOUT IF THEY ARE MISSING [[ -z "$*" ]] && die "Wrong parameters" echo -e "\e[33mSearching for tarball...\e[0m" if [[ -n "${_flag_fetch}" ]] || echo "$@" | grep -q 'force'; then _export_latest # FETCH THE KEYS FOR THE CRYPTOGRAPHIC AUTHENTICATION _gentoo_key # GET LATEST STAGE3 TARBALL, .DIGEST && .DIGEST.asc _get_latest "$@" # VERIFY THE AUTHENTICATION OF THE DOWNLOADED FILES _verify_download else _export_latest # GET LATEST STAGE3 TARBALL, .DIGEST && .DIGEST.asc local_stage3="$(cat "${CDISTDIR}/dists/latest.info")" if [[ "${local_stage3}" == "${STAGE3TB}" ]]; then echo -e "[\e[32m*\e[0m] Latest stage3 is already present locally" else # FETCH THE KEYS FOR THE CRYPTOGRAPHIC AUTHENTICATION _gentoo_key # GET LATEST STAGE3 TARBALL, .DIGEST && .DIGEST.asc _get_latest "$@" "fetch_new" # VERIFY THE AUTHENTICATION OF THE DOWNLOADED FILES _verify_download fi fi } # KEEP DOING UMOUNT -l UNTIL THERE IS NO DIST.D/WORKDIR ENTRY ON STDOUT _unmount() { k=0 if [[ -n "$(grep "dist.d/workdir-"$2 "/proc/mounts" | awk -F ' ' '{ print $2 }')" ]]; then while true; do while read -r i; do eval umount -l "$i"/* "${_flag_silence}" eval umount -l "$i" "${_flag_silence}" done < <(grep 'dist.d/workdir-' "/proc/mounts" | awk -F ' ' '{ print $2 }') if [[ -z $(grep "dist.d/workdir-"$2 "/proc/mounts" | awk -F ' ' '{ print $2 }') ]]; then break fi [[ "$k" -ge 20 ]] && return 1 ((++k)) done return 0 fi } # MOUNT DEV & SYS WITH RBIND THEN RSLAVE ON TARGET BUILDDIR _mount_dev_sys() { inspector "$@" if mount --rbind "/$2" "$1/$2"; then if mount --make-rslave "$1/$2"; then echo -e "[\e[32m*\e[0m] Mounting $2" else echo -e "[\e[31*\e[0m] Mounting $2" die "Failed" fi else die "Failed mounting $2" fi } # MOUNT PROC ON TARGET BUILDDIR _mount_proc() { inspector "$@" if mount -t proc /proc "$1/proc"; then echo -e "[\e[32m*\e[0m] Mounting proc" else echo -e "[\e[31m*\e[0m] Mounting proc" die "Failed" fi } # THIS SCRIPT IS SOURCED AT THE BEGINING FOR CHECKING THE BUILDER'S RUNTIME DEPENDENCIES _lcreq() { set +x CRDPENDS='' _am_i_root_sub() { if [[ "$1" == "0" ]]; then return 0 else return 1 fi } # GENTOO SECTION case "$1" in 1) if ! [[ $(command -v eix) ]]; then echo -e "[\e[33m*\e[0m] \e[35mPlease install eix to proceed!\e[0m" if _am_i_root_sub "$UID"; then echo -e "[\e[32m*\e[0m] Root privileges found" emerge -aq eix && echo -e "[\e[33m*\e[0m] \e[35mUpdating database\e[0m" eval eix-sync -a "${_flag_silence}" else echo -e "[\e[31m*\e[0m] Could not get root privileges" die "Please resolve this issue and start again" fi fi mapfile -t lreq < <(cat "${CLOCALLG}/loc_req" | sed '/^#/ d' | sed '/^\s*$/d') for i in "${lreq[@]}"; do sleep 0.1 if eval eix --installed "$i" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Searching for \e[32m$i\e[0m" else echo -e "[\e[31m*\e[0m] Searching for $i" echo -e "[\e[33m*\e[0m] Attempting to resolve the missing dependency" if _am_i_root $UID && echo -e "[\e[32m*\e[0m] Root privileges found"; then emerge -aq "$i" else echo -e "[\e[31m*\e[0m] Could not get root privileges" die"Please resolve this issue and start again" fi fi done;; 2) # NOT SUPPORTED mapfile -t lreq < <(cat "${CLOCALLG}/nogloc_req" | sed '/^#/ d' | sed '/^\s*$/d') for i in "${lreq[@]}"; do sleep 0.1 if eval command -v "$i" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Searching for \e[32m$i\e[0m" else echo -e "[\e[31m*\e[0m] Searching for $i" CRDPENDS=1 fi done [[ "${CRDPENDS}" == 1 ]] && while true; do echo -e "\e[33mIf you think some of those dependencies are name missmatch or not important\e[0m" echo -e "\e[33mYou can choose to continue at your own ristk\e[0m" echo -e "\e[33mContinue? Y/N: " read -rp "Input :: <= " ANS case "${ANS}" in [yY]) break;; [nN]) echo "Exiting..." && sleep 1 && exit 1;; esac done esac } # CREATE ARRAY OF ENABLED ARGUMENTS _case_args() { case "$1" in gfund|gseed|gcat|gextr|gprec|gparta|gupdate|gportage|grebuild|gsnap|gconfigure|ginst|grun|gkernel|ginitrd|gdes|gpartb|gclean ) _on_eargs+=("$1");; * ) die "Error: $2 unknown argument $1" esac } # EXPORT ARGUMENTS _export_args() { if [[ "$1" != *'='* ]]; then die "Missing arguments for $2" else _check_args="${1#*=}" if [[ "${_check_args}" == '' ]]; then die "No arguments were set for $2. Aborting..." else declare -a _ARGARRAY=("gfund" "gseed" "gcat" "gextr" "gprec" "gparta" \ "gupdate" "gportage" "grebuild" "gconfigure" "ginst" "grun" "gkernel" "ginitrd" "gpartb" "gdes" "gclean") _on_eargs=() if [[ "$(echo "${_check_args}" | cut -d ',' -f 1)" == "$(echo "${_check_args}" | cut -d ',' -f 2)" ]]; then j="$(echo "${_check_args}" | cut -d ',' -f 1)" _case_args "$j" "$2" else for i in {1..14}; do if [[ -n "$(echo "${_check_args}" | cut -d ',' -f $i)" ]]; then if [[ -n "$(echo "${_ARGARRAY[@]}" | grep "$(echo "${_check_args}" | cut -d ',' -f $i)")" ]]; then j="$(echo "${_check_args}" | cut -d ',' -f $i)" _case_args "$j" "$2" else die "Error: $2 unknown argument $(echo "${_check_args}" | cut -d ',' -f $i)" fi else break fi done fi fi fi unset _ARGARRAY } # FLAGS AND ARGUMENTS librarium() { _e_report_back "====================================================================================================================" _flag_fetch='' _flag_force_new='' _flag_keep='' _flag_health='' _flag_replace='' _flag_keep='' _flag_initrd='' _flag_minimal='' _flag_controller='' _flag_enforce='' _flag_lawful='' _flag_verbose='' _flag_quiet='' _flag_test='' _flag_silence='' _flag_chroot_silence='' _flag_network='' _flag_mm='' _flag_do='' _flag_g='' _flag_sdir='' _flag_auto='' _flag_time_warp='' _flag_time_state='' _flag_check=0 while true; do [[ -z "$*" ]] && return 0 case "$1" in --fetch-new|-fn ) _e_report_back "Fetch new is enabled" _flag_fetch=0 export _flag_fetch;; --force-new|-fcn ) _flag_force_new=0 export _flag_force_new;; --help|-h ) help_f _e_report_back "====================================================================================================================" exit 0;; --base*|-b* ) if [[ "$1" != *'='* ]]; then die "Missing argument for base method" else _base_method="${1#*=}" if [[ "${_base_method}" == '' ]]; then die "No target base. Aborting..." else case "${_base_method}" in catalyst ) _flag_base="catalyst" _e_report_back "Selected Base " _o_report_back "catalyst" export _flag_base;; precomp ) _flag_base="precomp" _e_report_back "Selected Base " _o_report_back "precomp" export _flag_base;; * ) die "Wrong target base. Choose either catalyst or precomp" esac fi fi ;; --keep|-k ) _flag_keep=0 _e_report_back "Keep old work is enabled" _e_report_back "Everything will be saved at /var/gse/work-date" export _flag_keep;; --health-check|-hc ) _flag_health=0 _e_report_back "Health check is enabled" export _flag_health;; --replace-new|-rpn ) _flag_replace=0 _e_report_back "Replacing base scripts..." export _flag_replace;; --no-kernel|-nk ) _flag_kernel=1 _e_report_back "Kernel and initramfs will be excluded" export _flag_kernel;; --no-initramfs|-ni ) _flag_initrd=1 _e_report_back "Initramfs will be excluded" export _flag_initrd;; --build-controller*|-bc* ) if [[ "$1" != *'='* ]]; then die "Missing argument for controller's path" else _flag_controller_path="${1#*=}" [[ ${_flag_controller_path:0:1} != "/" ]] && _flag_controller_path="/${_flag_controller_path}" if [[ "${_flag_controller_path}" == '/' ]]; then die "Root is not allowed to be set as moddir path. Aborting..." else if [[ -d "${_flag_controller_path}" ]]; then _flag_controller=0 export _flag_controller export _flag_controller_path _e_report_back "Controller flag enabled" else die "Error: moddir's target is not a directory" fi fi fi ;; --auto* ) if [[ "$1" != *'='* ]]; then die "Missing = for --auto" fi if [[ "${1#*=}" == '' ]]; then die "No argument specified" fi if [[ "${1#*=}" == 'yes' ]]; then _e_report_back "Automatic mode has been enabled" _flag_auto=0 export _flag_auto elif [[ "${1#*=}" == 'no' ]]; then _e_report_back "Automatic mode has been disabled" _flag_auto=1 export _flag_auto else die "Wrong input for --auto" fi ;; --build-minimal|-bm ) _flag_minimal=0 _e_report_back "Minimal build detected" _e_report_back "Custom packages will be excluded" _e_report_back "Custom profile will be excluded" _e_report_back "Custom flags will be excluded" _e_report_back "Kernel build will be excluded" _e_report_back "Initramfs will be excluded" export _flag_minimal;; --enforce* ) _export_args "$1" "enforce" _enforce_args=() for i in "${_on_eargs[@]}"; do _enforce_args+=("$i") done unset _on_eargs #_enforce_args _flag_enforce=0 export _flag_enforce _e_report_back "The following enforcer arguments have been enabled" _o_report_back "${_enforce_args[@]}" ;; --lawful-good* ) _export_args "$1" "lawful-good" _lawful_args=() for i in "${_on_eargs[@]}"; do _lawful_args+=("$i") done unset _on_eargs #_lawful_args _flag_lawful=0 export _flag_lawful _e_report_back "The following lawful arguments have been enabled" _o_report_back "${_lawful_args[@]}" ;; --time-warp* ) if [[ "$1" != *'='* ]]; then die "Missing = for --time-warp" fi if [[ "${1#*=}" == '' ]]; then die "No argument was given" fi echo -e "\e[35mTime warp enabled for $(ls "${CLOCALLG}/states" | grep "^${1#*=}_")\e[0m" if ls "${CLOCALLG}/states" | grep "^${1#*=}_"; then _flag_time_warp="${CLOCALLG}/states/$(ls "${CLOCALLG}/states" | grep "^${1#*=}_")" export _flag_time_warp else die "No such a mark: ${1#*=}" fi ;; --time-state* ) if [[ "${1#*--time-state}" == '' ]]; then die "No option was given for time state" fi if [[ "${1#*--time-state}" == '-' ]]; then rm -rf "${CLOCALLG}/states/$(ls "${CLOCALLG}/states" | grep "^${1#*=}_")" elif [[ "${1#*--time-state}" == '?' ]]; then _o_report_back "Time States" echo -e "\e[35m$(ls "${CLOCALLG}/states")\e[0m" else _flag_time_state=0 state_name="${1#*=}" fi ;; --distcc* ) if [[ "$1" != *'='* ]]; then die "Missing = for --distcc" fi if [[ "${1#*=}" == '' ]]; then die "Please select either on or pump mode." fi _flag_distcc=0 export _flag_distcc if [[ "${1#*=}" == 'on' ]]; then if [[ "$(cat "${CCONFDIR}/system/coptions" | sed '/^#/ d' | sed '/^\s*$/d' | grep "distcc")" ]]; then _e_report_back "Dist is already set from the coptions configuration file." _e_report_back "Resetting..." fi _o_report_back "Distcc enabled" _opt_distcc=normal export _opt_distcc elif [[ "${1#*=}" == 'pump' ]]; then if [[ "$(cat "${CCONFDIR}/system/coptions" | sed '/^#/ d' | sed '/^\s*$/d' | grep "pump")" ]]; then _e_report_back "Pump mode is already set from the coptions configuration file." _e_report_back "Resetting..." fi _o_report_back "Distcc: Pump mode enabled" _opt_distcc=pump export _opt_distcc else die "Unknown option" fi ;; --ccache* ) if [[ "$1" != *'='* ]]; then die "Missing = for --ccache" fi if [[ "${1#*=}" == '' ]]; then die "Please select a value in G for ccache." fi if [[ -z "$(echo ${i#*=} | sed 's/[!0-9]//g')" ]]; then die "Size order not specified. Please give the value in G or M" fi if [[ "${1: -1}" == 'G' ]]; then : elif [[ "${1: -1}" == 'M' ]]; then if [[ "$(echo ${i#*=} | sed 's/[a-zA-Z]//g')" -le '500' ]]; then _e_report_back "Ccache value is very low." fi else die "Ccache value is out of expected boundaries, aborting..." fi if [[ "$(cat "${CCONFDIR}/system/coptions" | sed '/^#/ d' | sed '/^\s*$/d' | grep "ccache")" ]]; then _e_report_back "Ccache is already set from the coptions configuration file." _e_report_back "Command line will overwrite the configs." _e_report_back "Overwriting..." fi _o_report_back "Ccache has been enabled, with a value of ${1#*=}" _flag_ccache=0 export _flag_ccache _ccache_val="${1#*=}" export _ccache_val ;; --no-checks ) _flag_check=1 export _flag_check ;; --verbose|-v ) _e_report_back "Verbose flag is enabled" _flag_verbose=0 export _flag_verbose;; --quiet|-q ) _e_report_back "Silence flag is enabled" _flag_quiet=0 export _flag_quiet;; -mm ) _flag_mm=0 export _flag_mm;; --sdir*) if [[ "$1" != *'='* ]]; then die "Missing argument for script's dir path" else _flag_sdir_path="${1#*=}" [[ ${_flag_sdir_path:0:1} != "/" ]] && _flag_sdir_path="/${_flag_sdir_path}" if [[ -d "${_flag_sdir_path}" ]]; then _flag_sdir=0 export _flag_sdir export _flag_sdir_path _e_report_back "Script's dir flag enabled" else die "Error: script's dir target is not a directory" fi fi if [[ "${2%=*}" != '--do' ]]; then die "Missing --do flag" fi if [[ "$2" != *'='* ]]; then die "Missing --do arguments" fi if [[ "${3%=*}" != '-g' ]]; then die "Missing -g flag" fi if [[ "$3" != *'='* ]]; then die "Missing argument after -g" fi _flag_doargs="${2#*=}" _flag_gargs="${3#*=}" echo "# Requested Scripts" > "${CLOCALLG}/doscripts" echo "# SCRIPT'S PATH" >> "${CLOCALLG}/doscripts" echo "SCP:${_flag_sdir_path}" >> "${CLOCALLG}/doscripts" echo "# Hook:Script" >> "${CLOCALLG}/doscripts" for i in {1..14}; do if [[ -n "$(echo "${_flag_doargs}" | awk -v j="$i" -F ' ' '{print $j}')" ]]; then if [[ -n "$(echo "${_flag_gargs}" | awk -v j="$i" -F ',' '{print $j}')" ]]; then GVAR0="$(echo "${_flag_gargs}" | awk -v j="$i" -F ',' '{print $j}')" if [[ "$(echo "${GVAR0:0:1}")" == '+' || "$(echo "${GVAR0:0:1}")" == '-' ]]; then GVAR1="${GVAR0:1}" if _case_args "${GVAR1}"; then : fi else die "Missing + or - from $(echo "${_flag_gargs}" | awk -v j="$i" -F ',' '{print $j}')" fi else die "Missing hook point for ${DOVAR1}" fi DOVAR0="$(echo "${_flag_doargs}" | awk -v j="$i" -F ' ' '{print $j}')" l=1 while true; do if [[ -n "$(echo "${DOVAR0}" | awk -v k="$l" -F ',' '{print $k}')" ]]; then DOVAR1="$(echo "${DOVAR0}" | awk -v k="$l" -F ',' '{print $k}')" if [[ ! -e "${_flag_sdir_path}/${DOVAR1}" ]]; then die "There is no such a ${DOVAR1} file" fi echo "${GVAR0}:${DOVAR1}" >> "${CLOCALLG}/doscripts" else break fi ((++l)) done else break fi done _e_report_back "With hooked scripts at: " _o_report_back "$(cat "${CLOCALLG}/doscripts")" shift 2 ;; --test ) _e_report_back "Test flag is enabled" _flag_test=0 export _flag_test source "${CWORKDIR}/scripts/sinit" "$@" ;; * ) die "Unknown $1 operation" ;; esac shift done } # CHECK GIVEN SPACE CONDITIONS _free_space() { if [[ $(echo "$1" | sed 's/[^G]*//g') == "G" ]]; then if [[ "$(echo "$1" | sed 's/[^0-9]*//g')" -le "$2" ]]; then _e_report_back "$3 has less than $2G available space." _e_report_back "The average disk space $4" _e_report_back "Please resolve this issue with freeing at least $2G and start again" _e_report_back "When building the chaintool and bootstraping the system" die "Bailing out..." fi elif [[ $(echo "$1" | sed 's/[^M]*//g') == "M" ]]; then die "The storedir $1 has less than 1G of space. Aborting..." fi } # MAKE SOME CHECKS BEFORE INITIATING THE REST OF THE PROCESSES witch_hunt() { inspector "$@" # CHECK IF CATALYST STOREDIR, PORTDIR AND DISTDIR ARE DIRECTORiES _export_catalyst_workdirs for i in "${CATDIR}" "${CATPORTDIR}" "${CATDISTDIR}"; do if [[ -e "$i" && ! -d "$i" ]]; then die "Error: $i is not a directory. Aborting" fi done # CHECK IF DIST.D EXISTS AND IS A DIRECTORY [[ -e "${CDISTDIR}" && ! -d "${CDISTDIR}" ]] && die "FATAL: dist.d is not a directory" # CHECK AVAILABLE SPACE OF STOREDIR AND DIST.D DIR _tmp_catdir=$(df -h "$CATDIR" | awk -F ' ' '{ print $4 }' | tail -n +2) _tmp_distdir=$(df -h "$CDISTDIR" | awk -F ' ' '{ print $4 }' | tail -n +2) _free_space "${_tmp_catdir}" "50" "Catalysts storedir" "catalyst will use for a stage3 tarball will be around 50G" _free_space "${_tmp_distdir}" "15" "Dist.d dir" "dist.d will use is at least 15G" unset CATDIR unset _tmp_distdir unset _tmp_catdir # CHECK FOR SUPERUSER PRIVILAGES if _am_i_root "$UID"; then _o_report_back "Superuser detected" else die "User is not superuser. Aborting" fi # PRIORITY CHECK FOR THE SCRIPT'S PID if [[ "$(ps -fl $$ | tail -n +2 | awk -F ' ' '{ print $8}')" -le 0 ]]; then _e_report_back "The priority of $0 is not high, and currently greater or equal to 0" _o_report_back "Changing priority to -5" renice -n -5 -p "$$" >/dev/null fi # ISSUE WARNING IF CONNECTION SEEMS TO BE FROM SSHD if [[ -n "${SSH_CLIENT}" || -n "${SSH_TTY}" ]]; then if [[ "$(echo "${TERM}")" == "screen" ]]; then _o_report_back "Session detected: ssh" _o_report_back "Tmux/Screen detected" _flag_tty="sshd" export _flag_tty else set +x while true; do _e_report_back "====================================================================================================================" _e_report_back "It appears you are running connected via ssh session" _e_report_back "It is recommended, if you haven't done yet, to stop this process" _e_report_back "and start it new from a tmux or screen session." _e_report_back "Most of the processes will require much time for normal computers, " _e_report_back "therefore it is a good idea to have a failsafe in case of a disconnect." _e_report_back "Do you wish to continue? {Not recommended}" _e_report_back "Answer Y/N " _e_report_back "====================================================================================================================" read -rp "Input :: <= " YN case "$YN" in [yY]) _flag_tty="sshd" export _flag_tty break;; [nN]) _e_report_back "Please restart from a detachable shell" die;; esac done set_x fi fi # EXPORT NETWORK CONDITION _e_report_back "Scanning for networking..." if ping -c 3 www.gentoo.org >/dev/null 2>&1; then _e_report_back "Network detected" _flag_network=0 export _flag_network else _e_report_back "Network not detected" _flag_network=1 export _flag_network fi return 0 } # INQUSITOR. CHECK FOR VERBOSITY LEVEL, CALL WITCH HUNT AND PROMPT IN CASE OF FORCE NEW inquisitor() { set +x inspector "$@" # ISSUE PARAMETER WARRNINGS parameters_check "$@" # PROMPT FOR FLAGS if [[ "${_flag_auto}" == 1 ]]; then while true; do _e_report_back "====================================================================================================================" _e_report_back "Do you wish to apply those and proceed?" _e_report_back "Answer: Y/N " read -rp "Input :: <= " YN case "$YN" in [yY]) break;; [nN]) die "Requested exit.";; *) _e_report_back "Please answer Y/N " esac done fi # PROMPT FOR CONTINUE IF FORCE_NEW IS PRESENT if [[ -n "$(echo ${_flag_force_new})" ]]; then _e_report_back "================================================" _e_report_back "================================================" _e_report_back "Warning: Force new flag has been enabled." _e_report_back "This flag will enable force globally." _e_report_back "Forced parts will always proceed to next part while purging everything that stands in the way" _e_report_back "See --enforce for forcing certain areas of the process, instead of this flag." _e_report_back "Are you sure? Y/N (Not recommended)" _e_report_back "================================================" _e_report_back "================================================" while true; do read -rp "Input :: <= " YN case "$YN" in [yN]) break;; [nN]) die "Requested exit." ;; * ) _e_report_back "Please answer Y/N " esac done fi # MAKE CHECKS AS DESCRIBED IN WITCH HUNT if [[ "${_flag_check}" == 0 ]]; then witch_hunt "$@" fi # PERFORM RUNTIME DEPENDENCIES CHECK. ISSUE WARNING FOR ALL BUT GENTOO if [[ "$(awk -F '=' '/RDEP/{ print $2 }' <"${CLOCALLG}/sinprog")" == 0 ]]; then _dependencies_check && sinit_flow_monitor "RDEP" fi } _auto_def_silence_def() { # AUTOMODE if ! echo "$@" | grep -q '\--auto=yes'; then _flag_auto=1 export _flag_auto fi # CONFIGURE SILENCE MODE if [[ "$(echo "${_flag_verbose}")" == 0 ]]; then # THIS SECTION ENABLES (set -x) _flag_silence="2>&1 | tee -a ${CLOCALLG}/log/sinit_log" elif [[ "$(echo "${_flag_quiet}")" == 0 ]]; then _flag_silence=">>${CLOCALLG}/log/sinit_log 2>&1" else _flag_silence="2>&1 | tee -a ${CLOCALLG}/log/sinit_log" fi export _flag_silence } # TIME STATE _time_state() { if [[ "${_flag_time_state}" == 0 && -n "${state_name}" ]]; then k=1 mkdir -p "${CLOCALLG}/states" while true; do if [[ -z "$(find "${CLOCALLG}/states" -name "${k}_*")" ]]; then mkdir -p "${CLOCALLG}/states/${k}_${state_name}" break fi ((++k)) done echo "state_name:${state_name}" > "${CLOCALLG}/states/${k}_${state_name}/main_flags" echo "_flag_base:${_flag_base}" >> "${CLOCALLG}/states/${k}_${state_name}/main_flags" for i in "${_flags_listA[@]}"; do echo "$i:${!i}" >> "${CLOCALLG}/states/${k}_${state_name}/main_flags" done if [[ -e "${CLOCALLG}/states/${k}_${state_name}/${state_name}_enforce" ]]; then rm -f "${CLOCALLG}/states/${k}_${state_name}/${state_name}_enforce" fi if [[ -e "${CLOCALLG}/states/${k}_${state_name}/${state_name}_lawful" ]]; then rm -f "${CLOCALLG}/states/${k}_${state_name}/${state_name}_lawful" fi if [[ -n "$(echo "${_enforce_args[@]}")" ]]; then for i in "${_enforce_args[@]}"; do echo "$i" >> "${CLOCALLG}/states/${k}_${state_name}/${state_name}_enforce" done fi if [[ -n "$(echo "${_lawful_args[@]}")" ]]; then for i in "${_lawful_args[@]}"; do echo "$i" >> "${CLOCALLG}/states/${k}_${state_name}/${state_name}_lawful" done fi if [[ -n "${_flag_sdir}" ]]; then rm -f "${CLOCALLG}/states/${k}_${state_name}/doscripts" if [[ "$(ls "${CLOCALLG}/doscripts")" ]]; then cp "${CLOCALLG}/doscripts" "${CLOCALLG}/states/${k}_${state_name}" fi fi cp -r "${CCONFDIR}" "${CLOCALLG}/states/${k}_${state_name}" _e_report_back "===========================================================================================" _e_report_back "State has been saved. To refer at this state in the future, use --time-warp=[state's mark]" _e_report_back "===========================================================================================" exit 0 fi } # TIME WARP _warping_time() { if [[ -n "${_flag_time_warp}" ]]; then # EXPORT STORED CONFIG.D LOCATION CCONFDIR="${_flag_time_warp}/config.d" export CCONFDIR if [[ -e "${_flag_time_warp}/doscripts" ]]; then _flag_sdir=0 cp "${_flag_time_warp}/doscripts" "${CLOCALLG}/doscripts" _flag_sdir_path="$(grep SCP "${CLOCALLG}/doscripts" | awk -F 'SCP:' '{ print $2 }')" export _flag_sdir export _flag_sdir_path fi # EXPORT THE STATE'S NAME, AND SAVED FLAGS while read -r s; do eval "${s%:*}"="${s#*:}" export "${s%:*}" done < <(cat "${_flag_time_warp}/main_flags" | grep '_') for i in "${_flags_listA[@]}"; do if [[ "$(echo ${!i})" == 0 ]]; then _flags_stagea+=("${i}") fi done # EXPORT ENFORCE SAVED ARGS if [[ -e "${_flag_time_warp}/${state_name}_enforce" ]]; then _flag_enforce=0 _enforce_args=() while read -r s; do _enforce_args+=("${s}") done < <(cat "${_flag_time_warp}/${state_name}_enforce") fi # EXPORT LAWFUL SAVED ARGS if [[ -e "${_flag_time_warp}/${state_name}_lawful" ]]; then _flag_lawful=0 _lawful_args=() while read -r s; do _lawful_args+=("${s}") done < <(cat "${_flag_time_warp}/${state_name}_lawful") fi _auto_def_silence_def "$@" "${_flags_stagea[@]}" _flags_stagea+=("${_flag_base}") _o_report_back "Warp time is enabled" _o_report_back "Selected state holds" _e_report_back "base:$_flag_base" if [[ "${_flag_auto}" ]]; then _e_report_back "auto:$_flag_auto" fi if [[ "${_flag_silence}" == 0 ]]; then _e_report_back "Silence is enabled" elif [[ "${_flag_silence}" == 1 ]]; then _e_report_back "Silence is disabled" fi if [[ "${_flag_sdir}" ]]; then _e_report_back "sdir:$_flag_sdir" _e_report_back "sdir_path:$_flag_sdir_path" fi if [[ "${_flag_enforce}" ]]; then _e_report_back "Enforce entries" _e_report_back "${_enforce_args[@]}" fi if [[ "${_flag_lawful}" ]]; then _e_report_back "Lawful entries" _e_report_back "${_lawful_args[@]}" fi # MAKE CHECKS AS DESCRIBED IN WITCH HUNT if [[ "${_flag_check}" == 0 ]]; then witch_hunt "$@" fi source "${CWORKDIR}/scripts/sinit" "${_flags_stagea[@]}" exit 0 fi } warp() { # DIE IF PP ARE NULL inspector "$@" # FILTER AND EXPORT ALL FLAGS AND ARGUMENTS. DIE UNLESS CONDITIONS ARE TRUE librarium "$@" # STAGE A & B # THE ITEMS IN THIS LIST THAT ARE NOT NULL, WILL BE EXPORTED _flags_stagea=() _flags_listA=("_flag_fetch" \ "_flag_force_new" \ "_flag_keep" \ "_flag_minimal" \ "_flag_enforce" \ "_flag_controller_path" \ "_enforce_args" \ "_flag_lawful" \ "_flag_controller" \ "_flag_initrd" \ "_lawful_args" \ "_flag_verbose" \ "_flag_quiet" \ "_flag_replace" \ "_flag_test" \ "_flag_health" \ "_flag_network" \ "_flag_sdir" \ "_flag_auto" \ "_flag_silence" \ "_flag_ccache" \ "_flag_distcc") _warping_time "$@" # SAVE ENABLED FLAGS for i in "${_flags_listA[@]}"; do if [[ "$(echo ${!i})" == 0 ]]; then _flags_stagea+=("${i}") fi done _time_state "$@" # THIS FUNCTION WILL ISSUE ESSENTIAL SYSTEM CHECKS, BEFORE PROCEEDING. inquisitor "$@" _flags_list0=("$_flag_fetch" \ "$_flag_force_new" \ "$_flag_keep" \ "$_flag_health" \ "$_flag_replace" \ "$_flag_keep" \ "$_flag_initrd" \ "$_flag_minimal" \ "$_flag_controller" \ "$_flag_controller_path" \ "$_flag_enforce" \ "$_enforce_args" \ "$_flag_lawful" \ "$_lawful_args" \ "$_flag_verbose" \ "$_flag_quiet" \ "$_flag_test" "$_flag_network") if [[ -z "${_flag_base}" ]]; then _e_report_back "You must choose a base if your run gse without main menu. Aborting..." _e_report_back "See man 1 gse for base options." die "Aborting actions..." fi _auto_def_silence_def "$@" _flags_stagea+=("${_flag_base}") if [[ -n "${_flag_base}" ]]; then source "${CWORKDIR}/scripts/sinit" "${_flags_stagea[@]}" elif [[ -z "${_flag_base}" && -n "${_flag_fetch}" ]]; then _call_fetch_new "$@" fi # STAGE C } _clean_target() { inspector "$@" [[ -z "$(echo "$@" | grep 'workdir')" ]] && print_inf_f rm -f "$1/LAST_FAILED_COMMAND" rm -f "$1/LAST_ACTION" rm -f "$1/issues.info" rm -f "$1/root/.bash*" } _archive_() { _o_report_back "Preparing to archive the system" _e_report_back "Unbinding..." _unmount "${_flag_base}" TARGETSTAMP="$(grep 'version_stamp' "${CCONFDIR}/system/catalyst/stage3.spec" \ | sed '/^#/ d' | awk -F ' ' '{ print $2 }' | sed -e "s_\"__g")" SUBBUILD=0 GVEX="${GSEVER}.${SUBBUILD}" EXCLUDE="--exclude=root/* \ --exclude=dev/* \ --exclude=proc/* \ --exclude=run/* \ --exclude=sys/* \ --exclude=boot/* \ --exclude=tmp/* \ --exclude=usr/portage/* \ --exclude=usr/src/* \ --exclude=usr/tmp/* \ --exclude=var/lock/* \ --exclude=var/cache/* \ --exclude=var/tmp/* \ --exclude=var/db/* \ --exclude=var/empty/* \ --exclude=var/spool/* \ --exclude=var/log/* \ --exclude=var/run/* \ --exclude=sinit.d" \ _e_report_back "Generating name..." while true; do if ! ls "${CDISTDIR}/stage3-amd64-${GVEX}.tar.bz2" >/dev/null 2>&1; then (cd "$1" _o_report_back "Creating the stage4 tarball" if [[ "${_flag_base}" == 'catalyst' ]]; then eval tar -cjpP --ignore-failed-read "${EXCLUDE}" -f "${CDISTDIR}/stage3-amd64-${TARGETSTAMP}-${GVEX}.tar.bz2" . "${_flag_silence}" elif [[ "${_flag_base}" == 'precomp' ]]; then eval tar -cjpP --ignore-failed-read "${EXCLUDE}" -f "${CDISTDIR}/stage3-amd64-prc-${GVEX}.tar.bz2" . "${_flag_silence}" fi ) \ && { _o_report_back "Archived" && echo -e "\e[34mYou can find your system @ ${CDISTDIR}\e[0m" echo -e "\e[34mWith version extension: ${GVEX}\e[0m"; } \ || die "Failed" break else GVEX="${GSEVER}.${SUBBUILD}" ((++SUBBUILD)) fi done } _do_rs() { while read -r s;do source "${_flag_sdir_path}/$s" done < <(grep "$1" "${CLOCALLG}/doscripts" | sed '/^#/ d' | sed '/^\s*$/d' | awk -F ':' '{ print $2 }') } _do_hs() { if grep -q "$1" "${CLOCALLG}/doscripts" && [[ -n "${_flag_sdir}" ]]; then _e_report_back "Sourcing scripts $2 $3" _do_rs "$1" fi } _repeat_part() { set +x while true; do echo -e "\e[33m$1: Has been completed\e[0m" echo "Run again? Y/N: " read -rp "Input :: <= " YN case "${YN}" in [yN]) return 0;; [nN]) return 1;; esac done set_x } _call_hook_points() { set_x if ! echo "$@" | grep -q '_flag_auto'; then if echo "${_lawful_args[@]}" | grep -q "$2"; then _o_report_back "Lawful entry detected on $2, proceeding..." else if [[ "$(grep "$1" "${CLOCALLG}/sinprog" | awk -F '=' '{ print $2 }')" == 0 || -n "${_flag_force_new}" ]] || echo "${_enforce_args[@]}" | grep -q "$2"; then if [[ -n "${_flag_force_new}" ]] || echo "${_enforce_args[@]}" | grep -q "$2"; then _e_report_back "Force entry detected on $3, forcing..." eval "$4" "${@:5}" "force" || die else eval "$4" "${@:5}" || die fi else if _repeat_part "$3"; then eval "$4" "${@:5}" else _e_report_back "Proceeding" fi fi fi else if echo "${_lawful_args[@]}" | grep -q "$2"; then _o_report_back "Lawful entry detected on $2, proceeding..." else eval "$4" "${@:5}" || die fi fi } # SUBSHELL LOOP FUNCTION subshell_loop() { set +x while true; do _subshell _e_report_back "If you fixed the issue, say CONTINUE proceed" _e_report_back "You can answer SHELL to open shell again, or call die with EXIT" _e_report_back "Answer? CONTINUE/SHELL/EXIT: " read -rp "Input :: <= " AANS case "${AANS}" in CONTINUE) LOOPVAR="EXITSHELL" break;; SHELL) LOOPVAR="SHELL" ;; EXIT) die "Exit Requested";; esac done set_x } _trap_sigs() { trap_var=0 export trap_var } # CALL SHELL FUNCtiON ask_for_shell() { set +x while true; do _e_report_back "$*" _e_report_back "Do you wish to call shell function and fix the issues manually?" _e_report_back "Answer SHELL/BREAK " read -rp "Input :: <= " YN case "$YN" in SHELL) sinit_master_loop "SHELL" break;; BREAK) break;; esac done set_x } # SINIT MASTER LOOP FUNCTION. CONTROLLS LOOP SUBSHELL sinit_master_loop() { inspector "$@" LOOPVAR="$1" while true; do case "${LOOPVAR}" in SHELL) subshell_loop;; EXITSHELL) break;; esac done } # PREPARE THE BUILDERDIR AND INITIATE CHROOT, DIE IF ANYENTRY FAILS _prepare_chroot() { inspector "$@" if [[ ! -e "$1" ]]; then _e_report_back "No workdir can be detected. Seems like $1 does not exist." _e_report_back "This can occur when Part: A is skipped." _e_report_back "If that's not the case, please submit a bug report, otherwise repeat the process without skipping Part: A" die "No workdir detected" fi rm -f "$1/etc/resolv.conf" cp -L /etc/resolv.conf "$1/etc/" || die "Failed" if [[ -n $(echo "$@" | grep 'catalyst') ]]; then # CHECK IF PSEUDOS ARE MOUNTED if [[ -n $(cat /proc/mounts | grep 'dist.d/workdir-catalyst' | awk -F ' ' '{ print $1 }') ]]; then echo -e "\e[31mPseudos possibly mounted at target directory\e[0m" echo -e "\e[33mResolving the issue...\e[0m" _unmount "catalyst" || die fi echo -e "\e[34mMounting pseudo\e[0m" [[ -z $(grep 'dist.d/workdir-catalyst' /proc/mounts | awk -F ' ' '{ print $1 }') ]] \ && _mount_proc "$1" || die elif [[ -n $(echo "$@" | grep 'precomp') ]]; then if [[ -n $(cat /proc/mounts | grep 'dist.d/workdir-precomp' | awk -F ' ' '{ print $1 }') ]]; then echo -e "\e[31mPseudos possibly mounted at target directory\e[0m" echo -e "\e[33mResolving the issue...\e[0m" _unmount "precomp" || die fi echo -e "\e[34mMounting pseudo\e[0m" [[ -z $(grep 'dist.d/workdir-precomp' /proc/mounts | awk -F ' ' '{ print $1 }') ]] \ && _mount_proc "$1" || die fi \ && _mount_dev_sys "$1" "dev" \ && _mount_dev_sys "$1" "sys" \ || die "Something went wrong" mkdir -p "$1/sinit.d" set -e if [[ ! -e "$1/sinit.d/chsinprog" ]] ; then eval rsync -aAXr "${CWORKDIR}/scripts/chroot_scripts/" "$1/sinit.d/" "${_flag_silence}" else eval rsync -aAXr --exclude="chsinprog" "${CWORKDIR}/scripts/chroot_scripts/" "$1/sinit.d/" "${_flag_silence}" fi if eval rsync -aAXr "${CCONFDIR}/system/portage/" "$1/sinit.d/" "${_flag_silence}"; then if eval rsync -aAXr --exclude="portage" "${CCONFDIR}/system/" "$1/sinit.d/" "${_flag_silence}"; then echo -e "[\e[32m*\e[0m] Copying \e[34mbuilder's\e[0m files to new system" else echo -e "[\e[31m*\e[0m] Copying \e[34mbuilder's\e[0m files to new system" fi fi set +e # CREATE REPOS.CONF DIRECOTRY & AND COPY REPOS.CONF TO IT mkdir -p "$1/etc/portage/repos.conf" cp "$1/usr/share/portage/config/repos.conf" "$1/etc/portage/repos.conf/gentoo.conf" || die # Set local timezone if set if [[ -n $(cat /etc/timezone) ]]; then TIMEZONE=$(cat /etc/timezone) sed -i -e "s_TMZ_${TIMEZONE}_g" "$1/sinit.d/chinit.conf" unset TIMEZONE fi echo -e "[\e[32m*\e[0m] Copying requested files" if [[ -n $(cat ${CCONFDIR}/system/inject_files | sed '/^#/ d' | sed '/^\s*$/d') ]]; then while read -r INJFL; do f1="$(echo $INJFL | awk -F ' ' '{ print $1 }')" f2="${BWORKDIR}/(echo $INJFL | awk -F ' ' '{ print $2 }')" echo "Copying $f1 to $f2" eval rsync -aAXPhrv "$f1" "$f2" "${_flag_silence}" \ && pass || { mapfile -t INJFLERR < <($INJFL | awk -F ' ' '{ print $1 }'); } done < <(cat "${CCONFDIR}/system/inject_files" | sed '/^#/ d' | sed '/^\s*$/d') unset INJFL if [[ -n "${INJFLERR}" ]]; then echo "Failed to copy the following packages: " echo "${INJFLERR[@]}" while true; do echo "You can list the failed files again, continue, request terminal or exit" echo "Please choose: LIST/CONTINUE/TERMINAL/EXIT" read -rp "Input :: <= " INJFLANS case "$INJFLANS" in LIST) clear; echo "${INJFLERR[@]}";; CONTINUE) while true; do echo "Are you sure? Y/N " read -p "Input :: <= " YN case $YN in [yY]) echo "Proceeding" INJFLESC=0 break;; [nN]) INJFLESC=1 ;; esac done;; TERMINAL) _subshell INJFLESC=0;; EXIT) while true; do echo "Are you sure? Y/N " read -p "Input :: <= " YN case $YN in [yY]) echo "Aborting..." exit 0;; [nN]) INJFLESC=1 break;; esac done;; esac [[ "$INJFLESC" == 0 ]] && break done fi unset YN unset INJFLESC unset INJFLANS unset INJFLERR else echo -e "[\e[32m*\e[0m] List empty" fi # COPY THE SCRIPTS AND DOSCRIPTS AT CHROOTDIR if [[ -n "${_flag_sdir}" ]]; then if [[ -e "$1/sinit.d/cscripts" ]]; then rm -rf "$1/sinit.d/cscripts" fi mkdir -p "$1/sinit.d/cscripts" rsync -aAXhrvq "${_flag_sdir_path}/" "$1/sinit.d/cscripts/" chmod +x "$1/sinit.d/cscripts/"* cp -r "${CLOCALLG}/doscripts" "$1/sinit.d/cscripts/doscripts" fi mkdir -p "$1/sinit.d/array_args" rm -f "$1/sinit.d/array_args/enforce_args" if [[ -n "${_enforce_args}" ]]; then for i in "${_enforce_args[@]}"; do echo "$i" >> "$1/sinit.d/array_args/enforce_args" done fi mkdir -p "$1/sinit.d/distcc_ccache" if [[ -n "${_opt_distcc}" ]]; then echo "${_opt_distcc}" > "$1/sinit.d/distcc_ccache/distcc_opt" else rm -f "$1/sinit.d/distcc_ccache/distcc_opt" fi if [[ -n "${_ccache_val}" ]]; then echo "${_ccache_val}" > "$1/sinit.d/distcc_ccache/ccache_val" else rm -f "$1/sinit.d/distcc_ccache/ccache_val" fi rm -f "$1/sinit.d/array_args/lawful_args" if [[ -n "${_lawful_args}" ]]; then for i in "${_lawful_args[@]}"; do echo "$i" >> "$1/sinit.d/array_args/lawful_args" done fi echo -e "\e[34mChrooting at new system\e[0m" # PASS ALL PP AND INITIATE CHROOT if chroot "$1" "sinit.d/chroot_init" "$@"; then _o_report_back "Chroot staged finished" else die "Chrooting configuration failed" fi }