diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a87f155 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.secrets.env \ No newline at end of file diff --git a/.secrets.env b/.secrets.env index 84ef985..d1cc54d 100644 --- a/.secrets.env +++ b/.secrets.env @@ -1,4 +1,4 @@ -SNIPEIT_APIKEY= -SNIPEIT_DOMAIN= -REPO= -BRANCH= \ No newline at end of file +SNIPEIT_APIKEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiYzQxODdjMzgyODJkYjZlYjNhYTRjMmY5YWI0NWMzYTgyYjI1YzYwMTk5MDA1ODM5NjkzYmY2M2Y5NmZkNDAyNDExMTBlOTk0ZmRlYTg3ZmEiLCJpYXQiOjE3MjQ3ODg0MjEuMTY2NDMsIm5iZiI6MTcyNDc4ODQyMS4xNjY0MzYsImV4cCI6MjM1NTk0MDQyMS4xNTU4MjcsInN1YiI6IjEiLCJzY29wZXMiOltdfQ.gdL2ku_CXZ0DoISpBASMRkauUX9on0EWJ9HkUf0Ar3y_LLACEsD8xDAKuXe4TZc-ksviCK35spPUW6MQyo-LfNMTro9jIy8Rf-uBYskEK_ykma2VlmkKQyA_Gx787JIMLgTEDF4KQcKjp5fL7PIDj-1uxdxughkft6OnV8GKwByLSulHBHzULy1DJhJamjxwObnj2xwzG4pV_54Nd3JsLgSYUwVuVcgFteLJtbxDjGUSb3zxSgnlMMEO67TePmDcgzy0FsHQklaDPhdoNPMRY5_iw7-_pBin6TSK5GzFqiMAjIqVLPiURWc5cv65bKHXQ94Z2jWJLMfNRsl6MneujIAoXZHYjZdttnmqA9knW7Rff4fDBLBx1EZQs485iBghdZo1JrOLurYsDrI74U749oPsZKLJvE4n7pHmL5qfYR6GXLenJ8C-p7et-jGqFw3jPhCxDn6FF7QwbBI1-2shsw9rhNNznpx8CtDia9quuzJQqeEjAqkvG_TWD8A5AZOTMko3sT1Ed0ydMe3jDtNuOiluy55HPu6Bv1Ztd_qK8pzNTV25qrK14FTdLuyPfBLjjOb9m-1Z49zJcePRA7GSpHfPWeFo4HbATckH-DCWyfXCDcCFEKtZzhn0_UrEU4Dy-hWc_aXUGces0lsohvQntWw__5MW3GP-tduiY1x2yx0 +SNIPEIT_DOMAIN=computer.z31.it +REPO=https://codeberg.org/angestoepselt/compose +BRANCH=main \ No newline at end of file diff --git a/README.md b/README.md index 8f5c2fa..8ddb12c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Please make sure to create the file `.secrets.env` with the following content: ``` SNIPEIT_APIKEY= # https://snipe-it.readme.io/reference/generating-api-tokens -SNIPEIT_DOMAIN= # orga.z31.it +SNIPEIT_DOMAIN= # computer.z31.it REPO= # The URL of the Repo were your want to get the angestoepselt-info info Script, like https://codeberg.org/angestoepselt/compose BRANCH= # the Branach of the REPO, default at codeberg.org is main ``` @@ -56,4 +56,4 @@ BRANCH= # the Branach of the REPO, default at codeberg.org is main ``` export $(cat .secrets-env) && \ curl --silent --request GET --url "https://$SNIPEIT_DOMAIN/api/v1/fields" --header 'accept: application/json' --header 'authorization: Bearer '$SNIPEIT_APIKEY'' | jq .rows[].db_column_name -``` \ No newline at end of file +``` diff --git a/angestoepselt-info b/angestoepselt-info deleted file mode 100755 index db0e7bc..0000000 --- a/angestoepselt-info +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash - -# This ist a small script which collect system information of a Linux PC and print it as json -# copy this script to /usr/local/bin and make it executable -# created by matthias of Angestöpselt e.V. -# created at 2022-02-17 -# modified at 2024-08-25 - -# Script muss mit sudo Rechten ausgeführt werden -if [ "$EUID" -ne 0 ] - then echo "Please run as root" - exit -fi - -install_if_not_exist() { - if /usr/bin/dpkg -s "$1" &>/dev/null; then - PKG_EXIST=$(/usr/bin/dpkg -s "$1" | grep "install ok installed") - if [[ -n "$PKG_EXIST" ]]; then - return - fi - fi - /usr/bin/apt-get install --no-install-recommends --yes "$1" -} - -install_if_not_exist jq -install_if_not_exist jc - -# Werte aus dmidecode auslesen -dmidecode_output=$(jc dmidecode) - -type=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Chassis Information") | .values.type') -manufacturer=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.manufacturer') -product_name=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.product_name') -serial_number=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.serial_number') -family=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.family') -memory_size=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Memory Device" and .values.bank_locator == "BANK 0") | .values.size') -memory_type=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Memory Device" and .values.bank_locator == "BANK 0") | .values.type') -cpu_family=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.family') -cpu_manufacturer=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.manufacturer') -cpu_version_raw=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.version') -cpu_core_count=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.core_count') -cpu_thread_count=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.thread_count') - -# Formatiere Variablen für eine schöne Ausgabe -# Im Moment ist es nur auf einem Intel Laptop getestet mit einem Intel Core i5 -cpu_version=$(echo "${cpu_version_raw%" CPU"*}") - - -# Laptop spezifischen Werte, Batterie, Display -battery_dir="/sys/class/power_supply/BAT0" - -# Überprüfen, ob das Verzeichnis existiert (d.h. ob eine Batterie vorhanden ist) -if [ -d "$battery_dir" ]; then - charge_full_design=$(cat "$battery_dir/charge_full_design") - charge_full=$(cat "$battery_dir/charge_full") - - # Bestimme auch Display Größe und Auflösung sofern ein Akku vorhanden ist - display_resolution=$(xdpyinfo | awk '/dimensions/ {print $2}') - display_size_raw=$(xrandr | awk '/ connected/{print sqrt( ($(NF-2)/10)^2 + ($NF/10)^2 )/2.54}' | head -n 1) - display_size=$(LC_ALL=C /usr/bin/printf "%.*f\n" 2 $display_size_raw) - - # Sicherstellen, dass beide Werte numerisch sind - if [[ "$charge_full_design" =~ ^[0-9]+$ ]] && [[ "$charge_full" =~ ^[0-9]+$ ]]; then - if [ "$charge_full_design" -ne 0 ]; then - bat_capacity=$((100 * charge_full / charge_full_design)) - fi - fi -else - bat_capacity="no_battery" - display_resolution="n/a" - display_size="n/a" -fi - - -# Erstelle das JSON-Objekt -jq -n \ - --arg type "$type" \ - --arg manufacturer "$manufacturer" \ - --arg product_name "$product_name" \ - --arg serial_number "$serial_number" \ - --arg family "$family" \ - --arg memory_size "$memory_size" \ - --arg memory_type "$memory_type" \ - --arg cpu_family "$cpu_family" \ - --arg cpu_manufacturer "$cpu_manufacturer" \ - --arg cpu_version "$cpu_version" \ - --arg cpu_core_count "$cpu_core_count" \ - --arg cpu_thread_count "$cpu_thread_count" \ - --arg bat_capacity "$bat_capacity" \ - --arg display_resolution "$display_resolution" \ - --arg display_size "$display_size" \ - '{ - type: $type, - manufacturer: $manufacturer, - product_name: $product_name, - serial_number: $serial_number, - family: $family, - memory_size: $memory_size, - memory_type: $memory_type, - cpu_family: $cpu_family, - cpu_manufacturer: $cpu_manufacturer, - cpu_version: $cpu_version, - cpu_core_count: $cpu_core_count, - cpu_thread_count: $cpu_thread_count, - bat_capacity: $bat_capacity, - display_resolution: $display_resolution, - display_size: $display_size - }' diff --git a/angestoepselt-tool b/angestoepselt-tool new file mode 100755 index 0000000..1fb54d9 --- /dev/null +++ b/angestoepselt-tool @@ -0,0 +1,719 @@ +#!/bin/bash +# Install and configure a Linux Mint 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/setup_system.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/setup_system.lock +sysinfofolder=/var/angestoepselt +sysinfofile=systeminfo.json +random_tmpfile=$(mktemp) +SCRIPT_DIR="$(dirname "$0")" +TIME=$(date +%Y%m%d%H%M) +LOGTIME=$(date "+%Y-%m-%d %H:%M:%S") +LOGFILE="$SCRIPT_DIR/$TIME-setup_system.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 "/usr/bin/apt-get update -qq" + printok "update cache" + + printprog "upgrade system" + runcmd "/usr/bin/apt-get dist-upgrade -y -qq" + printok "upgrade system" +} + + +install_if_not_exist() { + if /usr/bin/dpkg -s "$1" &>/dev/null; then + PKG_EXIST=$(/usr/bin/dpkg -s "$1" | grep "install ok installed") + if [[ -n "$PKG_EXIST" ]]; then + return + fi + fi + /usr/bin/apt-get install --no-install-recommends --yes "$1" +} + +system_install_rustdesk() { + set -o pipefail + trap ErrorHandling ERR INT + + # get lastest version of Rustdesk + RUSTDESK_VERSION=$(curl -sL https://api.github.com/repos/rustdesk/rustdesk/releases/latest | jq -r ".tag_name") + + printprog "downloading rustdesk version $RUSTDESK_VERSION" + runcmd "/usr/bin/wget \ + https://github.com/rustdesk/rustdesk/releases/download/$RUSTDESK_VERSION/rustdesk-$RUSTDESK_VERSION-x86_64.deb \ + -O /tmp/rustdesk-$RUSTDESK_VERSION-x86_64.deb" + printok "downloading rustdesk $RUSTDESK_VERSION" + + printprog "install rustdesk" + runcmd "/usr/bin/apt-get install -fy /tmp/rustdesk-$RUSTDESK_VERSION-x86_64.deb" + printok "install rustdesk" + + printprog "add rustdesk ID to $sysinfofile" + RDP_ID=$(/usr/bin/rustdesk --get-id) + runcmd "/usr/bin/jq --arg rdp_id "$RDP_ID" '. + {RDP_ID: $rdp_id}' "$sysinfofolder/$sysinfofile" > tmp.json && mv tmp.json "$sysinfofolder/$sysinfofile"" + printok "add rustdesk ID to $sysinfofile" +} + +system_install_base() { + set -o pipefail + trap ErrorHandling ERR INT + printprog "install apt packages (this can take some time)" + runcmd "distro=$(if echo " una bookworm vanessa focal jammy bullseye vera uma " | grep -q " $(lsb_release -sc) "; then lsb_release -sc; else echo focal; fi) ; \ + /usr/bin/wget -O- https://deb.librewolf.net/keyring.gpg | gpg --dearmor -o /usr/share/keyrings/librewolf.gpg \ + ; \ + /usr/bin/tee /etc/apt/sources.list.d/librewolf.sources << EOF > /dev/null +Types: deb +URIs: https://deb.librewolf.net +Suites: $distro +Components: main +Architectures: amd64 +Signed-By: /usr/share/keyrings/librewolf.gpg +EOF + ; \ + /usr/bin/apt-get install --yes -qq -o Dpkg::Options::=--force-confdef --ignore-missing \ + 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 \ + librewolf \ + thunderbird \ + thunderbird-locale-de \ + thunderbird-locale-en \ + thunderbird-locale-en-gb \ + gimp \ + 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 "/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 "/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 "" +} + +snipeit_add_asset_to_sysinfofile() { + set -o pipefail + trap ErrorHandling ERR INT + + mkdir $random_tmpdir + printprog "add ASSET_TAG to $sysinfofile" + runcmd "/usr/bin/jq --arg asset_tag "$asset_tag" '. + {Asset_Tag: $asset_tag}' "$sysinfofolder/$sysinfofile" > "$random_tmpfile" && mv "$random_tmpfile" "$sysinfofolder/$sysinfofile"" + printok "add ASSET_TAG to $sysinfofile" +} + +snipeit_instance_check() { + set -o pipefail + trap ErrorHandling ERR INT + + # is snipe-IT reachable? + printprog "check presence of snipe-IT API" + runcmd "/usr/bin/curl -o /dev/null --silent https://$SNIPEIT_DOMAIN" + printok "check presence of snipe-IT API" +} + +system_pcinfo_file() { + set -o pipefail + trap ErrorHandling ERR INT + + install_if_not_exist jq + install_if_not_exist jc + # Werte auslesen und in variable speichern + dmidecode_output=$(jc dmidecode) + lshw_output=$(lshw -json) + [ -f /usr/bin/rustdesk ] && RDP_ID=$(/usr/bin/rustdesk --get-id) + os_name=$(lsb_release -sd) + # for now I only want the size of the first disk /dev/sda + disk_size=$(lsblk -J | jq -r '.blockdevices[] | select(.name == "sda") | .size') + optical_drive=$(lsblk -J | jq -e '.blockdevices[] | select(.type == "rom" or .type == "cdrom")' > /dev/null 2>&1 && echo "ja" || echo "nein") + + type=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Chassis Information") | .values.type') + manufacturer=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.manufacturer') + product_name=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.product_name') + serial_number=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.serial_number') + family=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "System Information") | .values.family') + memory_size=$(echo "$lshw_output" | jq '.children[]?.children[]? | select(.id == "memory") | .size / (1024 * 1024 * 1024)') + memory_type=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Memory Device" and .values.bank_locator == "BANK 0") | .values.type') + cpu_family=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.family') + cpu_manufacturer=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.manufacturer') + cpu_version_raw=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.version') + cpu_core_count=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.core_count') + cpu_thread_count=$(echo "$dmidecode_output" | jq -r '.[] | select(.description == "Processor Information") | .values.thread_count') + network_hwaddress=$(echo "$lshw_output" | jq -r '.children[]?.children[]?.children[]? | select(.id == "network") | .serial') + # Formatiere Variablen für eine schöne Ausgabe + # Im Moment ist es nur auf einem Intel Laptop getestet mit einem Intel Core i5 + cpu_version=$(echo "${cpu_version_raw%" CPU"*}") + + + # Laptop spezifischen Werte, Batterie, Display + battery_dir="/sys/class/power_supply/BAT0" + + # Überprüfen, ob das Verzeichnis existiert (d.h. ob eine Batterie vorhanden ist) + if [ -d "$battery_dir" ]; then + charge_full_design=$(cat "$battery_dir/charge_full_design") + charge_full=$(cat "$battery_dir/charge_full") + + # Bestimme auch Display Größe und Auflösung sofern ein Akku vorhanden ist + display_resolution=$(xdpyinfo | awk '/dimensions/ {print $2}') + display_size_raw=$(xrandr | awk '/ connected/{print sqrt( ($(NF-2)/10)^2 + ($NF/10)^2 )/2.54}' | head -n 1) + display_size=$(LC_ALL=C /usr/bin/printf "%.*f\n" 2 $display_size_raw) + + # Sicherstellen, dass beide Werte numerisch sind + if [[ "$charge_full_design" =~ ^[0-9]+$ ]] && [[ "$charge_full" =~ ^[0-9]+$ ]]; then + if [ "$charge_full_design" -ne 0 ]; then + bat_capacity=$((100 * charge_full / charge_full_design)) + fi + fi + else + bat_capacity="no_battery" + display_resolution="n/a" + display_size="n/a" + fi + + if [[ -f "$sysinfofolder/$sysinfofile" ]]; then + printskip "$sysinfofile existiert bereits" + return 0 + else + + printprog "create systeminfo File" + # Erstelle das JSON-Objekt + /usr/bin/jq -n \ + --arg type "$type" \ + --arg manufacturer "$manufacturer" \ + --arg os_name "$os_name" \ + --arg product_name "$product_name" \ + --arg serial_number "$serial_number" \ + --arg family "$family" \ + --arg memory_size "$memory_size" \ + --arg memory_type "$memory_type" \ + --arg cpu_family "$cpu_family" \ + --arg cpu_manufacturer "$cpu_manufacturer" \ + --arg cpu_version "$cpu_version" \ + --arg cpu_core_count "$cpu_core_count" \ + --arg cpu_thread_count "$cpu_thread_count" \ + --arg disk_size "$disk_size" \ + --arg optical_drive "$optical_drive" \ + --arg network_hwaddress "$network_hwaddress" \ + --arg bat_capacity "$bat_capacity" \ + --arg display_resolution "$display_resolution" \ + --arg display_size "$display_size" \ + --arg RDP_ID "$RDP_ID" \ + '{ + type: $type, + manufacturer: $manufacturer, + os_name: $os_name, + product_name: $product_name, + serial_number: $serial_number, + family: $family, + memory_size: $memory_size, + memory_type: $memory_type, + cpu_family: $cpu_family, + cpu_manufacturer: $cpu_manufacturer, + cpu_version: $cpu_version, + cpu_core_count: $cpu_core_count, + cpu_thread_count: $cpu_thread_count, + disk_size: $disk_size, + optical_drive: $optical_drive, + network_hwaddress: $network_hwaddress, + bat_capacity: $bat_capacity, + display_resolution: $display_resolution, + display_size: $display_size, + RDP_ID: $RDP_ID + }' > "$sysinfofolder/$sysinfofile" + + printok "create systeminfo File" + return 0 + fi +} + +system_pcinfo() { + 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 + + printprog "read systeminfo" + runcmd "/usr/bin/jq -e . $sysinfofolder/$sysinfofile >/dev/null 2>&1" + printok "read systeminfo" + + network_hwaddress=$(cat $sysinfofolder/$sysinfofile | /usr/bin/jq -r .network_hwaddress) + ASSET_TAG=$(cat $sysinfofolder/$sysinfofile | /usr/bin/jq -r .Asset_Tag) + + ## start localcheck + if [[ $ASSET_TAG =~ ^[0-9]+$ ]]; then + printinfo "already in Snipe-IT: RE$ASSET_TAG" + exit 0 + elif + [ -f $SCRIPT_DIR/mac_white.list ] && grep -Fxq "$network_hwaddress" mac_white.list + then + unset network_hwaddress + printinfo "Device is using a charity owned USB Ethernet-Adapter" + return 1 + ## end localcheck + else + ## start snipe-it check + + printinfo "fetch info from Snipe-IT" + result=$(/usr/bin/curl --silent --request GET \ + --url "https://$SNIPEIT_DOMAIN/api/v1/hardware?limit=1&search=${network_hwaddress//[:]/%3A}" \ + --header 'accept: application/json' \ + --header 'authorization: Bearer '$SNIPEIT_APIKEY'') + + [[ $(echo $result | /usr/bin/jq '(has("error"))') == true ]] && { printinfo "$(echo $result | /usr/bin/jq .error)"; return 1; } + system_check_result=$(echo $result | jq .total) # doesn't work + asset_tag=$(echo $result | /usr/bin/jq -r .rows[].asset_tag) + + if [ -n "$asset_tag" ]; then + printinfo "Device already present in Snipe-IT: RE$asset_tag" + snipeit_add_asset_to_sysinfofile + return 0 + else + printok "Device not in Snipe-IT" + system_pcinfo_value="newdevice" + return 0 + fi + ## end snipe-it check + fi +} + +system_register() { + set -o pipefail + trap ErrorHandling ERR INT + + if [[ "$system_pcinfo_value" != "newdevice" ]]; then + printskip "register Device at Snipe-IT" + exit 0 + fi + + # convert json to variables, like key=value + eval "$(/usr/bin/jq -r '. | to_entries | .[] | .key + "=" + (.value | @sh)'< $sysinfofolder/$sysinfofile)" + + printinfo "fetching variables for register $type 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 1) + [[ "${type,,}" =~ laptop|notebook ]] && { model=2; display="$Displaysize @ $Resolution"; } || model=1 + # cannont locate issue with true and false, simple workaround to fix it + # FIXME + + + # 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 </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 < $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