From 95d3f92607498d8978003ec27d904ef5e64441a9 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 27 Oct 2023 11:40:41 +0200 Subject: [PATCH] renamed a bunch of files --- btrfs-snapshots.sh | 61 +++++++++++++++++++++++++++++ clone-vmdk.sh | 74 +++++++++++++++++++++++++++++++++++ odroid-fancontrol.sh | 75 +++++++++++++++++++++++++++++++++++ request-certificate.sh | 28 +++++++++++++ switch-desktop.sh | 44 +++++++++++++++++++++ watch-containers.sh | 89 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 371 insertions(+) create mode 100755 btrfs-snapshots.sh create mode 100755 clone-vmdk.sh create mode 100755 odroid-fancontrol.sh create mode 100755 request-certificate.sh create mode 100755 switch-desktop.sh create mode 100755 watch-containers.sh diff --git a/btrfs-snapshots.sh b/btrfs-snapshots.sh new file mode 100755 index 0000000..22f01a2 --- /dev/null +++ b/btrfs-snapshots.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# this will take read-only btrfs snapshots and make it available in /srv/snapshots + +# Information +NAME="btrfs-snapshots.sh" +VERSION="0.2.0" +AUTHOR="david@socialnerds.org" +LICENSE="MIT" +DESCRIPTION="$NAME (v$VERSION) takes snapshots of BTRFS volumes. It is written by $AUTHOR and published unter the $LICENSE license." + +# variables +SUBVOLUMES="/" +DESTINATION_ROOT=/srv/snapshots +TIMESTAMP=$(date +%Y%m%d%H%M) #add %S if you want sub-minute snapshots +PREFIX="snapshot-" +NAME="$PREFIX$TIMESTAMP" +MAX_SNAPSHOTS=28 #how many snapshots should be kept? + +# preflight checks +if [ $(whoami) != "root" ]; then + echo "error: you need to be root" + exit 1 +fi + +# take the snapshots +for SUBVOLUME in $SUBVOLUMES; do + if [ -z ${SUBVOLUME#/} ]; then + SNAPSHOT_PATH="$DESTINATION_ROOT" + else + PATH="$DESTINATION_ROOT/${SUBVOLUME#/}" + fi + if [ ! -d $SNAPSHOT_PATH ]; then + echo "warning: snapshot path ($SNAPSHOT_PATH) does not yet exist. creating." + mkdir -p $SNAPSHOT_PATH + fi + if [ -d $SNAPSHOT_PATH/$NAME ]; then + echo "warning: snapshots with same name already exists. skipping." + else + #TODO: handle failed snapshots and failed link creations + btrfs -q subvolume snapshot -r $SUBVOLUME $SNAPSHOT_PATH/$NAME + if [ -h $SNAPSHOT_PATH/latest ]; then + rm $SNAPSHOT_PATH/latest + fi + ln -sf $SNAPSHOT_PATH/$NAME $SNAPSHOT_PATH/latest + fi +done + +# prune old snapshots +SNAPSHOTS=$(ls -r $SNAPSHOT_PATH | grep $PREFIX) +i=0 +for SNAPSHOT in $SNAPSHOTS; do + if [ $i -ge $MAX_SNAPSHOTS ]; then + #TODO: handle failed snapshot deletions + btrfs -q subvolume delete $SNAPSHOT_PATH/$SNAPSHOT + fi + i=$((i+1)) +done + +# end script successfully +exit 0 diff --git a/clone-vmdk.sh b/clone-vmdk.sh new file mode 100755 index 0000000..aa0a310 --- /dev/null +++ b/clone-vmdk.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# simple script to clone a virtual machine (vmware) +# to another datastore/folder. + +# usage: ./clone-vm.sh +# source path must be a directory and contain a virtual machine (at least a single .vmdk file) +# destination path must a directory, preexist and be empty (to avoid overwriting another machine) + +# sources: +# https://serverfault.com/questions/372526/move-vmware-esxi-vm-to-new-datastore-preserve-thin-provisioning +# https://communities.vmware.com/thread/498408 + +echo; echo "**** Simple virtual machine cloning script ****"; echo +sleep 0.5; echo "Before you continue all snapshots need to be deleted" +echo "and all virtual disks (.vmdk files) need to be consolidated."; echo +echo "And please, for your own sake, make sure the VM is powered down!"; echo +echo "Do you want to continue? [Y]" +read a +if [ -z $a ] || [ $a == "Y" ] || [ $a == "y" ]; then + if [ $1 ] && [ $2 ]; then + if [ -d $1 ]; then + if [ -r $1 ]; then + if [ -n "$(ls -A $1)" ]; then + source=${1%/} + if [ -d $2 ]; then + if [ -w $2 ]; then + if [ -z "$(ls -A $2)" ]; then + destination=${2%/} + sleep 0.5; echo "INFO: Preflight checks good. Commencing cloning process." + for disk in $(find "$source" -maxdepth 1 -type f | grep ".vmdk" | grep -v "flat.vmdk"); do + if [ -n "${disk##*delta*}" ]; then + echo "ERROR: You little rebel did not remove all snapshots. Failsave exit!"; exit 1 + fi + #try the following to move a specific snapshot + #find . -maxdepth 1 -type f | grep "000030.vmdk" + sleep 0.5; echo "INFO: Cloning $disk to $destination" + vmkfstools -i $disk -d thin $destination/${disk##*/} + if [ $? -ne 0 ]; then + echo "ERROR: An error occured while cloning $disk to $destination." + fi + done + for file in $(find "$source" -maxdepth 1 -type f | grep -v ".vmdk"); do + sleep 0.5; echo "INFO: Copying $file to $destination" + cp "$file" "$destination" + if [ $? -ne 0 ]; then + echo "ERROR: An error occured while copying $file to $destination." + fi + done + else + sleep 0.5; echo "ERROR: Destination path is not empty ($2)."; exit 1 + fi + else + sleep 0.5; echo "ERROR: Destination path is not writeable ($2)."; exit 1 + fi + else + sleep 0.5; echo "ERROR: Destination path is not a directory ($2)."; exit 1 + fi + else + sleep 0.5; echo "ERROR: Source path empty ($1)."; exit 1 + fi + else + sleep 0.5; echo "ERROR: Source path is not readable ($1)."; exit 1 + fi + else + sleep 0.5; echo "ERROR: Source path is not a directory ($1)."; exit 1 + fi + else + sleep 0.5; echo "ERROR: Source and destination path must be given."; exit 1 + fi +else + sleep 0.5; echo "ERROR: Mission aborted by user." + exit 2 +fi diff --git a/odroid-fancontrol.sh b/odroid-fancontrol.sh new file mode 100755 index 0000000..50214e1 --- /dev/null +++ b/odroid-fancontrol.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# +# My Odroid fan control script +# (only tested with an Odroid HC4 running Manjaro) +# + +# Information (don't touch unless you're me) +NAME="odroid-fancontrol.sh" +AUTHOR="david@socialnerds.org" +VERSION="0.2.1" +LICENSE="MIT" +DESCRIPTION="$NAME (v$VERSION) controls the fan speed in an Odroid HC4 (and possibly others) based on temperature. It is written by $AUTHOR and published under the $LICENSE license." + +# Configuration +THRESHOLD=50000 +DISTANCE=1000 +INTERVAL=30 +STEPS=(120 160 210 255) +FAN="/sys/class/hwmon/hwmon2/pwm1" +LOGFILE="/var/log/hc4_fancontrol.log" + +# Get all temperature readings and return the highest value +function get_temp() { + local TEMPS=($(cat /sys/devices/virtual/thermal/thermal_zone*/temp)) + local RESULT=${TEMPS[0]}; + for TEMP in ${TEMPS[@]}; do + if [ $TEMP -gt $RESULT ]; then + RESULT=$TEMP + fi + done + echo $RESULT +} + +# Get current fan speed +function get_speed() { + local SPEED=$(cat $FAN) + echo $SPEED +} + +# Set new fan speed +function set_speed() { + local CURRENT_SPEED=$(get_speed) + local NEW_SPEED=$1 + if [ $CURRENT_SPEED -ne $NEW_SPEED ]; then + echo $NEW_SPEED > $FAN + if [ -n $LOGFILE ]; then + echo "$(date +%Y%m%d-%H%M%S): Temp[$(get_temp)], Speed[$(get_speed)]" >> $LOGFILE + fi + sleep 3 + fi +} + +# Set fan mode to manual +echo "disabled" | tee /sys/class/thermal/thermal_zone{0,1}/mode > /dev/null + +# Run loop +while true; do + TEMP=$(get_temp) + SPEED=$(get_speed) + NEW_THRESHOLD=$THRESHOLD + if [ $TEMP -gt $THRESHOLD ]; then + for STEP in ${STEPS[@]}; do + if [ $TEMP -gt $NEW_THRESHOLD ]; then + NEW_THRESHOLD=$((NEW_THRESHOLD + DISTANCE)) + if [ $SPEED -lt $STEP ]; then + set_speed $STEP + fi + fi + done + else + set_speed 0 + fi + sleep $INTERVAL +done diff --git a/request-certificate.sh b/request-certificate.sh new file mode 100755 index 0000000..1d80ebd --- /dev/null +++ b/request-certificate.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "error: pls supply at least one domain name" + exit 1 +fi + +NAME="$1" +DOMAINS="$*" +OPTIONS="--issue --dns dns_miab --server letsencrypt" +COMMAND="/usr/bin/acme.sh" +ACME_PATH="/srv/acme" + +for DOMAIN in $DOMAINS; do + OPTIONS="$OPTIONS -d $DOMAIN" +done + +# requesting certificate +$COMMAND $OPTIONS + +# installing certificate to $ACME_PATH +if [ $? -eq 0 ]; then + $COMMAND --install-cert -d $NAME --key-file $ACME_PATH/$NAME.key --fullchain-file $ACME_PATH/$NAME.crt --reloadcmd "systemctl restart nginx.service" +else + echo "error: an error occured while issuing certificate." + exit 1 +fi + diff --git a/switch-desktop.sh b/switch-desktop.sh new file mode 100755 index 0000000..51e0de3 --- /dev/null +++ b/switch-desktop.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# name: switch_desktop.sh +# version: 0.1 +# author: david@socialnerds.org +# description: switch to next, previous, specific desktop. +# you can also toggle between first and second desktop. +# +# usage: ./switch-desktop.sh next|prev||toggle + +num=$(wmctrl -d | grep "*" | awk '{print $1}') +lockfile="/tmp/switch_desktop.lock" + +if [ ! -f $lockfile ]; then + echo "creating lockfile [$lockfile]" + touch $lockfile + + if [[ "$1" =~ ^[0-9]+$ ]]; then + echo "switching to specific desktop [$1]" + wmctrl -s $1 + elif [ "$1" == "next" ]; then + echo "switching to next desktop [$next]" + next=$((num+1)) + wmctrl -s $next + elif [ "$1" == "prev" ]; then + if [ $num -ne 0 ]; then + echo "switching to previous desktop [$prev]" + prev=$((num-1)) + wmctrl -s $prev + fi + elif [ "$1" == "toggle" ]; then + if [ $num -eq 0 ]; then + echo "switching to second desktop" + wmctrl -s 1 + else + echo "switching back to first desktop" + wmctrl -s 0 + fi + fi + echo "waiting for 0.5 seconds" + sleep 0.5 + echo "cleaning up lockfile [$lockfile]" + rm $lockfile +fi diff --git a/watch-containers.sh b/watch-containers.sh new file mode 100755 index 0000000..56bf05c --- /dev/null +++ b/watch-containers.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# name: watch_containers.sh +# author: david@socialnerds.org +# version: 0.1 +# license: GPLv3 +# description: Checks if the running container count +# matches a number provided as $1 and optionally +# reports results to a healthchecks endpoint. + +# usage: ./watch_containers.sh + +# **** function definitions **** +function usage { + echo "usage: ./watch-containers.sh " +} + +function get_container_count { + local CNT=$(docker ps --format {{.Names}} | wc -l) + if is_int "$CNT"; then + echo $CNT + fi +} + +function is_int { + local INT_EXPR='^[0-9]+$' + if [[ $1 =~ $INT_EXPR ]]; then + return 0 + else + return 1 + fi +} + +function is_url { + local URL_EXPR='^https?://.+$' + if [[ $1 =~ $URL_EXPR ]]; then + return 0 + else + return 1 + fi +} + +# **** start **** + +#exit if no options +if [ -z "$1" ]; then + usage + exit 1 +fi + +#exit if $1 is no intager +if ! is_int "$1"; then + usage + exit 1 +fi + +#set expected running containers +NUM=$1 + +#get running container count +CNT=$(get_container_count) + +#set healthchecks url if not empty +URL="" +if [ -n "$2" ]; then + #exit if $2 is no valid url + if ! is_url "$2"; then + usage + exit 1 + fi + URL="$2" +fi + +MSG="Running containers: $CNT +Expected containers: $NUM" + +echo "$MSG" + +#report to healthchecks +if [ -n "$URL" ]; then + if [ $NUM -eq $CNT ]; then + curl -m 10 --retry 5 --data-raw "$MSG" "$URL" + else + curl -m 10 --retry 5 --data-raw "$MSG" "$URL/fail" + fi +fi + +# **** end **** +exit 0