mirror of
https://codeberg.org/angestoepselt/imagestack.git
synced 2025-05-24 14:46:16 +00:00
516 lines
14 KiB
Bash
516 lines
14 KiB
Bash
#!/bin/bash
|
||
# Install and configure a Ubuntu-PC for the charity organization angestöpselt e.V. | angestoepselt.de
|
||
# created by matthias of angestöpselt e.V.
|
||
# created at 2022-02-17
|
||
|
||
version=0.2
|
||
|
||
set -o errexit
|
||
exec 100>/tmp/z31.lock || exit 1
|
||
flock 100 || exit 1
|
||
|
||
# Speed up script by not using unicode.
|
||
LC_ALL=C
|
||
LANG=C
|
||
|
||
|
||
# some static variables
|
||
DEBIAN_FRONTEND=noninteractive
|
||
current_user=$(id 1000 | awk -F '[()]' '{print $2}')
|
||
lockfile=/tmp/z31.lock
|
||
sysinfofile=$HOME/.config/systeminfo.json
|
||
random_tmpdir=$(mktemp)
|
||
SCRIPT_DIR="$(dirname "$0")"
|
||
TIME=$(date +%Y%m%d%H%M)
|
||
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
|
||
LOGFILE="$SCRIPT_DIR/$TIME-z31.log"
|
||
|
||
# Set variables for stdout print
|
||
COLOR_N='\e[0m'
|
||
COLOR_GREEN='\e[1;32m'
|
||
COLOR_RED='\e[1;31m'
|
||
COLOR_BLUE='\e[1;34m'
|
||
COLOR_WHITE='\e[1;97m'
|
||
OK="[${COLOR_GREEN}ok${COLOR_N}]"
|
||
FAIL="[${COLOR_RED}fail${COLOR_N}]"
|
||
INFO="[${COLOR_BLUE}info${COLOR_N}]"
|
||
SKIP="[${COLOR_BLUE}skip${COLOR_N}]"
|
||
PROGRESS="[${COLOR_BLUE}..${COLOR_N}]"
|
||
|
||
# log actual command and it's stderr to logfile in one go
|
||
runcmd_stdout() {
|
||
echo "+ $1" >>"$LOGFILE"
|
||
bash -c -o pipefail "$1" 2>>"$LOGFILE" | tee -a "$LOGFILE"
|
||
}
|
||
|
||
runcmd() {
|
||
echo "+ $1" >>"$LOGFILE"
|
||
bash -c -o pipefail "$1" >>"$LOGFILE" 2>&1
|
||
}
|
||
|
||
printprog() {
|
||
echo -ne "${PROGRESS} $*\r"
|
||
}
|
||
|
||
printok() {
|
||
echo -e "\r${OK} $*"
|
||
}
|
||
|
||
printfail() {
|
||
echo -e "\r${FAIL} $*"
|
||
}
|
||
|
||
printinfo() {
|
||
echo -e "${INFO} $*"
|
||
}
|
||
|
||
printskip() {
|
||
echo -e "\r${SKIP} $*"
|
||
}
|
||
|
||
ErrorHandling() {
|
||
set -eu
|
||
printfail "Something went wrong, exiting. Check $LOGFILE for more details."
|
||
}
|
||
|
||
system_update() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog "update cache"
|
||
runcmd "sudo /usr/bin/apt-get update -qq"
|
||
printok "update cache"
|
||
|
||
printprog "upgrade system"
|
||
runcmd "sudo /usr/bin/apt-get dist-upgrade -y -qq"
|
||
printok "upgrade system"
|
||
}
|
||
|
||
system_install_base() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog "add anydesk repo to source.list.d"
|
||
|
||
if [ -f "/etc/apt/sources.list.d/anydesk-stable.list" ]; then
|
||
printskip "add anydesk repo to source.list.d"
|
||
else
|
||
runcmd "sudo /usr/bin/wget -qO - https://keys.anydesk.com/repos/DEB-GPG-KEY | sudo apt-key add - && \
|
||
echo "deb http://deb.anydesk.com/ all main" > /etc/apt/sources.list.d/anydesk-stable.list"
|
||
printok "add anydesk repo to source.list.d"
|
||
fi
|
||
|
||
echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections
|
||
|
||
printprog "install apt packages (this can take some time)"
|
||
runcmd "sudo /usr/bin/apt-get install --yes -qq -o Dpkg::Options::=--force-confdef --ignore-missing \
|
||
ubuntu-restricted-extras \
|
||
apt-transport-https \
|
||
vlc \
|
||
gdebi \
|
||
gparted \
|
||
tlp \
|
||
language-pack-de-base \
|
||
libreoffice \
|
||
libreoffice-l10n-de \
|
||
libreoffice-help-de \
|
||
libreoffice-help-en-gb \
|
||
libreoffice-l10n-en-gb \
|
||
firefox \
|
||
firefox-locale-de \
|
||
firefox-locale-en \
|
||
thunderbird \
|
||
thunderbird-locale-de \
|
||
thunderbird-locale-en \
|
||
thunderbird-locale-en-gb \
|
||
gimp \
|
||
anydesk \
|
||
libqt5qml5 \
|
||
language-selector-common \
|
||
openoffice.org-hyphenation \
|
||
language-pack-kde-ar \
|
||
language-pack-kde-uk \
|
||
language-pack-kde-ru \
|
||
language-pack-kde-fa"
|
||
printok "install apt packages"
|
||
}
|
||
|
||
system_install_edubuntu() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
# Edubuntu packages (official support until 18.04) https://wiki.ubuntuusers.de/Edubuntu_Programme
|
||
printprog "install Edubuntu packages (this can take some time)"
|
||
runcmd "sudo /usr/bin/apt-get install --yes -qq -o Dpkg::Options::=--force-confdef --ignore-missing \
|
||
blinken \
|
||
calibre \
|
||
cantor \
|
||
chemtool \
|
||
dia \
|
||
einstein \
|
||
fritzing \
|
||
gamine \
|
||
gcompris \
|
||
goldendict \
|
||
inkscape \
|
||
kalgebra \
|
||
kalzium \
|
||
kanagram \
|
||
kbruch \
|
||
kgeography \
|
||
khangman \
|
||
kig \
|
||
klettres \
|
||
kmplot \
|
||
kstars \
|
||
ktouch \
|
||
ktuberling \
|
||
kturtle \
|
||
kwordquiz \
|
||
laby \
|
||
lightspeed \
|
||
lybniz \
|
||
marble \
|
||
melting \
|
||
parley \
|
||
pencil2d \
|
||
ri-li \
|
||
rocs \
|
||
step \
|
||
tuxmath \
|
||
tuxpaint \
|
||
tuxtype \
|
||
yorick"
|
||
printok "install Edubuntu packages"
|
||
}
|
||
|
||
system_clean() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog "clean up apt cache and packages"
|
||
runcmd "sudo /usr/bin/apt-get autoremove --yes"
|
||
printok "clean up apt cache and packages"
|
||
}
|
||
|
||
system_configure() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog "set timezone"
|
||
runcmd "timedatectl set-timezone Europe/Berlin"
|
||
printok "set timezone"
|
||
}
|
||
|
||
system_files_download() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog ""
|
||
runcmd ""
|
||
printok ""
|
||
}
|
||
|
||
system_modify_dm() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
# TODO: detect dm of device and choose modification
|
||
# cat /etc/X11/default-display-manager > /usr/sbin/gdm3 (Gnome Desktop Manager)
|
||
# goals to cover
|
||
# - Wallpaper
|
||
# -
|
||
printprog ""
|
||
runcmd ""
|
||
printok ""
|
||
}
|
||
|
||
|
||
system_checkinfo() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
# this part checks if the device is already registered in snipe-IT
|
||
# is already registered it returns 1
|
||
# this is a new device it returns 0
|
||
|
||
if [ ! -f $sysinfofile ]; then
|
||
printprog "write systeminfo to $sysinfofile"
|
||
runcmd "mkdir /home/$current_user/.config/angestoepselt && /bin/bash /usr/local/bin/angestoepselt-info > $sysinfofile"
|
||
printok "write systeminfo to $sysinfofile"
|
||
fi
|
||
|
||
printprog "read systeminfo"
|
||
runcmd "jq -e . $sysinfofile >/dev/null 2>&1"
|
||
printok "read systeminfo"
|
||
|
||
HW_ADDRESS=$(cat $sysinfofile | jq -r .HW_ADDRESS)
|
||
ASSET_TAG=$(cat $sysinfofile | jq -r .Asset_Tag)
|
||
|
||
## start localcheck
|
||
if [[ $ASSET_TAG =~ ^[0-9]+$ ]]; then
|
||
printinfo "already in Snipe $ASSET_TAG"
|
||
return 1
|
||
elif
|
||
[ -f $SCRIPT_DIR/mac_white.list ] && grep -Fxq "$HW_ADDRESS" mac_white.list
|
||
then
|
||
unset HW_ADDRESS
|
||
printinfo "Device is using a charity owned USB Ethernet-Adapter"
|
||
return 1
|
||
## end localcheck
|
||
else
|
||
## start snipe-it check
|
||
printprog "check presence of snipe-IT API"
|
||
runcmd "curl -o /dev/null --silent https://$SNIPEIT_DOMAIN"
|
||
printok "check presence of snipe-IT API"
|
||
|
||
printinfo "fetch info from Snipe-IT"
|
||
result=$(curl --silent --request GET \
|
||
--url "https://$SNIPEIT_DOMAIN/api/v1/hardware?limit=1&search=${HW_ADDRESS//[:]/%3A}" \
|
||
--header 'accept: application/json' \
|
||
--header 'authorization: Bearer '$SNIPEIT_APIKEY'')
|
||
|
||
[[ $(echo $result | jq '(has("error"))') == true ]] && { printinfo "$(echo $result | jq .error)"; return 1; }
|
||
system_check_result=$(echo $result | jq .total) # doesn't work
|
||
asset_tag=$(echo $result | jq -r .rows[].asset_tag)
|
||
|
||
if [ -n "$asset_tag" ]; then
|
||
printinfo "Device already present in Snipe-IT: RE$asset_tag"
|
||
|
||
printprog "add ASSET_TAG to $sysinfofile"
|
||
runcmd "jq '. |= . + {"Asset_Tag": \"'${asset_tag}'\"}' $sysinfofile > $random_tmpdir/systeminfo.json.tmp && mv $random_tmpdir/systeminfo.json.tmp $sysinfofile"
|
||
printok "add ASSET_TAG to $sysinfofile"
|
||
else
|
||
printok "Device not in Snipe-IT"
|
||
system_checkinfo_value="newdevice"
|
||
return 0
|
||
fi
|
||
## end snipe-it check
|
||
fi
|
||
}
|
||
|
||
system_register() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
if [[ "$system_checkinfo_value" != "newdevice" ]]; then
|
||
printskip "register Device at Snipe-IT"
|
||
fi
|
||
|
||
# is snipe-IT reachable?
|
||
printprog "check presence of snipe-IT API"
|
||
runcmd "curl -o /dev/null --silent https://$SNIPEIT_DOMAIN"
|
||
printok "check presence of snipe-IT API"
|
||
|
||
# convert json to variables, like key=value
|
||
eval "$(jq -r '. | to_entries | .[] | .key + "=" + (.value | @sh)'< $sysinfofile)"
|
||
|
||
printinfo "fetching variables for register $Platform at Snipe-IT"
|
||
|
||
# get platform. at the moment this looks for a laptop in string. If ist not a laptop it is a desktop PC (model 2)
|
||
[[ "$Platform" == *"laptop"* ]] && { model=1; display="$Displaysize @ $Resolution"; } || model=2
|
||
# clean up anydesk variable. > room for improvement, only integer should be in the var. This can be handled in the angestoepselt-info script
|
||
[[ "$Anydesk_ID" == *"SERVICE_NOT_RUNNING"* ]] && unset Anydesk_ID
|
||
# cannont locate issue with true and false, simple workaround to fix it
|
||
[[ "$Optical_Drive" == "FALSE" ]] && Optical_Drive=nein || Optical_Drive=ja
|
||
|
||
|
||
# change this variables used in this post to your needs, read the README of this repo and read ahead in the Snipe-IT API docs for more Informations
|
||
# https://snipe-it.readme.io/reference/updating-custom-fields
|
||
post_data()
|
||
{
|
||
cat <<EOF
|
||
{
|
||
"status_id": "2",
|
||
"name": "$Model",
|
||
"model_id": "$model",
|
||
"serial": "$serialno",
|
||
"_snipeit_mac_address_1": "$HW_ADDRESS",
|
||
"_snipeit_betriebssystem_2": "$Distro",
|
||
"_snipeit_festplatte_4": "$HDD",
|
||
"_snipeit_prozessor_5": "$CPU",
|
||
"_snipeit_arbeitsspeicher_6": "$Memory",
|
||
"_snipeit_optisches_laufwerk_7": "$Optical_Drive",
|
||
"_snipeit_display_8": "$display",
|
||
"_snipeit_akku_9": "$Battery_life",
|
||
"_snipeit_anydeskid_10": "$Anydesk_ID"
|
||
}
|
||
EOF
|
||
}
|
||
printprog "register $Platform at Snipe-IT"
|
||
post_result=$(curl --silent --request POST \
|
||
--url 'https://'$SNIPEIT_DOMAIN'/api/v1/hardware' \
|
||
--header 'accept: application/json' \
|
||
--header 'authorization: Bearer '$SNIPEIT_APIKEY'' \
|
||
--header 'Content-Type: application/json' \
|
||
--data "$(post_data)")
|
||
|
||
post_status=$(echo $post_result |jq -r .status)
|
||
post_message=$(echo $post_result |jq -r .message)
|
||
asset_tag=$(echo $post_result |jq -r .payload.asset_tag)
|
||
|
||
if [ "$post_status" = "success" ]; then
|
||
printok "register $Platform at Snipe-IT"
|
||
|
||
printprog "add PC to $sysinfofile"
|
||
runcmd "jq '. |= . + {"Asset_Tag": \"'${asset_tag}'\"}' $sysinfofile > $random_tmpdir/systeminfo.json.tmp && mv $random_tmpdir/systeminfo.json.tmp $sysinfofile"
|
||
printok "add PC to $sysinfofile"
|
||
else
|
||
printfail "$post_message"
|
||
fi
|
||
}
|
||
|
||
script_check_root() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog "check root privileges"
|
||
runcmd "[ $(id -u) -eq 0 ]"
|
||
printok "check root privileges"
|
||
}
|
||
|
||
script_check_snipesecrets() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printprog "check .secrets.env"
|
||
runcmd "[ -f $SCRIPT_DIR/.secrets.env ] && export $(cat $SCRIPT_DIR/.secrets.env)"
|
||
printok "check .secrets.env"
|
||
}
|
||
|
||
script_prerequisites() {
|
||
set -o pipefail
|
||
trap ErrorHandling ERR INT
|
||
|
||
printinfo "install requirements"
|
||
|
||
printprog "install required packages"
|
||
runcmd "sudo /usr/bin/apt-get -qq --yes install jq moreutils dialog html2ps python3 python3-pip curl wkhtmltopdf"
|
||
printok "install required packages"
|
||
|
||
printprog "install angestoepselt-info"
|
||
runcmd "sudo /usr/bin/wget –quiet $REPO/raw/branch/master/angestoepselt-info -O /usr/local/bin/angestoepselt-info && sudo chmod +x /usr/local/bin/angestoepselt-info"
|
||
printok "install angestoepselt-info"
|
||
|
||
}
|
||
|
||
|
||
usage() {
|
||
printf "%s" "\
|
||
Usage: $0 --option
|
||
|
||
Options:
|
||
INFO:
|
||
-h|--help print this info
|
||
-v|--version show version of script
|
||
|
||
-a|--all running all task below
|
||
|
||
-u|--update perform an basic system update
|
||
-i|--install install all packages for this system
|
||
-r|--register Register PC in snipe-IT Asset Management
|
||
-c|--configure running basic system config settings
|
||
-d|--files_download download useful files to your HomeDirectory
|
||
-m|--modify_dm paint your Desktop Manager with angestoepselt design
|
||
--checkinfo Check if PC is already in snipe-IT present
|
||
--clean clean up trash, like files and from system tasks like packagemanger
|
||
|
||
"
|
||
exit 1
|
||
}
|
||
|
||
POSITIONAL_ARGS=()
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-h|--help)
|
||
usage
|
||
;;
|
||
-u|--update)
|
||
script_check_root
|
||
system_update
|
||
shift
|
||
shift
|
||
;;
|
||
-i|--install)
|
||
script_check_root
|
||
system_install_base
|
||
system_install_edubuntu
|
||
shift
|
||
shift
|
||
;;
|
||
--clean)
|
||
script_check_root
|
||
system_clean
|
||
shift
|
||
shift
|
||
;;
|
||
--charity)
|
||
charity=${OPTARG:=angestoepselt}
|
||
shift
|
||
shift
|
||
;;
|
||
-c|--configure)
|
||
script_check_root
|
||
system_configure
|
||
shift
|
||
shift
|
||
;;
|
||
-d|--files_download)
|
||
system_files_download
|
||
shift
|
||
shift
|
||
;;
|
||
-m|--modify_dm)
|
||
script_check_root
|
||
system_modify_dm
|
||
shift
|
||
shift
|
||
;;
|
||
--checkinfo)
|
||
script_check_snipesecrets
|
||
system_checkinfo
|
||
shift
|
||
shift
|
||
;;
|
||
-r|--register)
|
||
script_check_snipesecrets
|
||
system_register
|
||
shift
|
||
shift
|
||
;;
|
||
-a|--all)
|
||
script_check_root
|
||
system_update
|
||
system_install
|
||
system_clean
|
||
system_configure
|
||
system_files_download
|
||
system_modify_dm
|
||
script_check_snipesecrets
|
||
system_checkinfo
|
||
system_register
|
||
exit 0
|
||
;;
|
||
-v|--version)
|
||
printf '%s\n' "$0 v$version"
|
||
exit 1
|
||
;;
|
||
-*|--*)
|
||
echo "Unknown option $1"
|
||
usage
|
||
exit 1
|
||
;;
|
||
*)
|
||
POSITIONAL_ARGS+=("$1")
|
||
shift
|
||
;;
|
||
esac
|
||
done
|
||
|
||
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
|
||
|
||
if [[ -n $1 ]]; then
|
||
echo "Last line of file specified as non-opt/last argument:"
|
||
tail -1 "$1"
|
||
fi
|
||
|