compose/late_command.sh
2022-05-19 11:03:55 +02:00

515 lines
14 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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