Add letsencrypt status to dietpi-banner

Creating a software or image request, pls use GitHub

I have a modified diet-banner that shows the status of letsencrypt certificate expiration: enclosed.

Not sure if it is of use to others.

Code is below (with credits to previous inputs and developments):


#!/bin/bash
{
	#////////////////////////////////////
	# DietPi Banner Script
	#
	#////////////////////////////////////
	# Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com
	#
	#////////////////////////////////////
	#
	# Info:
	# - Location: /boot/dietpi/func/dietpi-banner
	# - Checks /run/dietpi/.update_available, /run/dietpi/.live_patches, /run/dietpi/.apt_updates, /run/dietpi/.dietpi_motd and /boot/dietpi/.prep_info
	#
	# Usage:
	# - dietpi-banner   = banner customisation menu
	# - dietpi-banner 0 = top section + LAN IP
	# - dietpi-banner 1 = clear terminal + top section + chosen entries + credits
	#////////////////////////////////////

	# Grab input
	[[ $1 == [01] ]] && INPUT=$1 || INPUT=2

	# Import DietPi-Globals --------------------------------------------------------------
	. /boot/dietpi/func/dietpi-globals
	# - Allow concurrent banner prints but a single menu call only
	if [[ $1 == 2 ]]
	then
		readonly G_PROGRAM_NAME='DietPi-Banner'
		G_CHECK_ROOT_USER # Required to store settings
		G_INIT
	fi
	# Import DietPi-Globals --------------------------------------------------------------

	#/////////////////////////////////////////////////////////////////////////////////////
	# Globals
	#/////////////////////////////////////////////////////////////////////////////////////
	readonly FP_SAVEFILE='/boot/dietpi/.dietpi-banner'
	readonly FP_CUSTOM='/boot/dietpi/.dietpi-banner_custom'

	aDESCRIPTION=(

		'Device model'
		'Uptime'
		'CPU temp'
		'FQDN/hostname'
		'NIS domainname'
		'LAN IP'
		'WAN IP'
		'Freespace (RootFS)'
		'Freespace (userdata)'
		'Weather (wttr.in)'
		'Custom banner entry'
		'Display DietPi useful commands?'
		'MOTD'
		'VPN status'
		'Large hostname'
		'Print credits'
		'Certificate Valid to'

	)

	# Set defaults: Disable CPU temp by default in VMs
	if (( $G_HW_MODEL == 20 ))
	then
		aENABLED=(1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1)
	else
		aENABLED=(1 1 1 0 0 1 0 0 0 0 0 1 1 0 0 1 1)
	fi

	COLOUR_RESET='\e[0m'
	aCOLOUR=(

		'\e[38;5;154m'	# DietPi green	| Lines, bullets and separators
		'\e[1m'		# Bold white	| Main descriptions
		'\e[90m'	# Grey		| Credits
		'\e[91m'	# Red		| Update notifications

	)

	# Load settings here, to have chosen ${aCOLOUR[0]} applied to below strings
	# shellcheck disable=SC1090
	[[ -f $FP_SAVEFILE ]] && . "$FP_SAVEFILE"

	GREEN_LINE=" ${aCOLOUR[0]}─────────────────────────────────────────────────────$COLOUR_RESET"
	GREEN_BULLET=" ${aCOLOUR[0]}-$COLOUR_RESET"
	GREEN_SEPARATOR="${aCOLOUR[0]}:$COLOUR_RESET"

	DIETPI_VERSION="$G_DIETPI_VERSION_CORE.$G_DIETPI_VERSION_SUB.$G_DIETPI_VERSION_RC"
	[[ $G_GITBRANCH == 'master' ]] || DIETPI_VERSION+=" ($G_GITBRANCH)"

	# DietPi update available?
	AVAILABLE_UPDATE= # value = version string
	Check_DietPi_Update(){

		[[ -f '/run/dietpi/.update_available' ]] || return 1
		AVAILABLE_UPDATE=$(</run/dietpi/.update_available)
		return 0

	}

	# New DietPi live patches available?
	LIVE_PATCHES=0
	Check_DietPi_Live_Patches(){

		[[ -f '/run/dietpi/.live_patches' ]] || return 1
		LIVE_PATCHES=1
		return 0

	}

	# APT updates available?
	PACKAGE_COUNT=0
	Check_APT_Updates(){

		[[ -f '/run/dietpi/.apt_updates' ]] || return 1
		PACKAGE_COUNT=$(</run/dietpi/.apt_updates)
		return 0

	}

	# Reboot required to finalise kernel upgrade?
	REBOOT_REQUIRED=0
	Check_Reboot()
	{
		G_CHECK_KERNEL && return 1
		REBOOT_REQUIRED=1
		return 0
	}

	Save(){

		# Custom entry description
		echo "aDESCRIPTION[10]='${aDESCRIPTION[10]}'"

		for i in "${!aDESCRIPTION[@]}"
		do
			echo "aENABLED[$i]=${aENABLED[$i]}"
		done

		for i in "${!aCOLOUR[@]}"
		do
			echo "aCOLOUR[$i]='${aCOLOUR[$i]}'"
		done

	}

	Print_Header(){

		# DietPi update available?
		if Check_DietPi_Update
		then
			local text_update_available_date="${aCOLOUR[3]}Update available"

		# New DietPi live patches available?
		elif Check_DietPi_Live_Patches
		then
			local text_update_available_date="${aCOLOUR[3]}New live patches available"

		# APT update available?
		elif Check_APT_Updates
		then
			local text_update_available_date="${aCOLOUR[3]}$PACKAGE_COUNT APT updates available"

		# Reboot required to finalise kernel upgrade?
		elif Check_Reboot
		then
			local text_update_available_date="${aCOLOUR[3]}Reboot required"
		else
			local locale=$(sed -n '/^[[:blank:]]*AUTO_SETUP_LOCALE=/{s/^[^=]*=//p;q}' /boot/dietpi.txt)
			local text_update_available_date=$(LC_ALL=${locale:-C.UTF-8} date '+%R - %a %x')
		fi

		echo -e "$GREEN_LINE
 ${aCOLOUR[1]}DietPi v$DIETPI_VERSION$COLOUR_RESET $GREEN_SEPARATOR $text_update_available_date$COLOUR_RESET
$GREEN_LINE"

	}

	Print_Local_Ip(){

		local iface=$(G_GET_NET -q iface)
		[[ $iface ]] || iface='NONE'
		local ip=$(G_GET_NET -q ip)
		[[ $ip ]] || ip='Use dietpi-config to setup a connection'
		[[ ${aENABLED[5]} == 1 ]] && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[5]} $GREEN_SEPARATOR $ip ($iface)"

	}

	Print_Credits(){

		echo -e " ${aCOLOUR[2]}DietPi Team     : https://github.com/MichaIng/DietPi#the-dietpi-project-team"

		[[ -f '/boot/dietpi/.prep_info' ]] && mawk 'NR==1 {sub(/^0$/,"DietPi Core Team");a=$0} NR==2 {print " Image by        : "a" (pre-image: "$0")"}' /boot/dietpi/.prep_info

		echo -e " Patreon Legends : Camry2731, Chris Gelatt
 Website         : https://dietpi.com/ | https://twitter.com/DietPi_
 Contribute      : https://dietpi.com/contribute.html
 Web Hosting by  : https://myvirtualserver.com$COLOUR_RESET\n"

	}

	Print_Updates(){
		# DietPi update available?
		if [[ $AVAILABLE_UPDATE ]]
		then
			echo -e " ${aCOLOUR[1]}dietpi-update$COLOUR_RESET   $GREEN_SEPARATOR ${aCOLOUR[3]}Run now to update DietPi from v$DIETPI_VERSION to v$AVAILABLE_UPDATE$COLOUR_RESET\n"

		# New DietPi live patches available?
		elif (( $LIVE_PATCHES ))
		then
			echo -e " ${aCOLOUR[1]}dietpi-update$COLOUR_RESET   $GREEN_SEPARATOR ${aCOLOUR[3]}Run now to check out new available DietPi live patches$COLOUR_RESET\n"

		# APT updates available?
		elif (( $PACKAGE_COUNT ))
		then
			echo -e " ${aCOLOUR[1]}apt upgrade$COLOUR_RESET     $GREEN_SEPARATOR ${aCOLOUR[3]}Run now to apply $PACKAGE_COUNT available APT package upgrades$COLOUR_RESET\n"

		# Reboot required to finalise kernel upgrade?
		elif (( $REBOOT_REQUIRED ))
		then
			echo -e " ${aCOLOUR[1]}reboot$COLOUR_RESET          $GREEN_SEPARATOR ${aCOLOUR[3]}A reboot is required to finalise a recent kernel upgrade$COLOUR_RESET\n"
		fi

	}

	Print_Useful_Commands(){

		echo -e " ${aCOLOUR[1]}dietpi-launcher$COLOUR_RESET $GREEN_SEPARATOR All the DietPi programs in one place
 ${aCOLOUR[1]}dietpi-config$COLOUR_RESET   $GREEN_SEPARATOR Feature rich configuration tool for your device
 ${aCOLOUR[1]}dietpi-software$COLOUR_RESET $GREEN_SEPARATOR Select optimised software for installation
 ${aCOLOUR[1]}htop$COLOUR_RESET            $GREEN_SEPARATOR Resource monitor
 ${aCOLOUR[1]}cpu$COLOUR_RESET             $GREEN_SEPARATOR Shows CPU information and stats\n"

	}

	Print_Banner(){

		G_TERM_CLEAR
		Print_Header

		# Large Format Hostname
		# shellcheck disable=SC1091
		(( ${aENABLED[14]} == 1 )) && . /boot/dietpi/func/dietpi-print_large "$(</etc/hostname)" && echo
		# Device model
		(( ${aENABLED[0]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[0]} $GREEN_SEPARATOR $G_HW_MODEL_NAME"
		# Uptime
		(( ${aENABLED[1]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[1]} $GREEN_SEPARATOR $(uptime -p 2>&1)"
		# CPU temp
		(( ${aENABLED[2]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[2]} $GREEN_SEPARATOR $(print_full_info=1 G_OBTAIN_CPU_TEMP 2>&1)"
		# Hostname
		(( ${aENABLED[3]} == 1 && ${aENABLED[14]} != 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[3]} $GREEN_SEPARATOR $(</etc/hostname)"
		# NIS/YP domainname
		(( ${aENABLED[4]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[4]} $GREEN_SEPARATOR $(hostname -y 2>&1)"
		# LAN IP [5]
		Print_Local_Ip
		# WAN IP + location info
		(( ${aENABLED[6]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[6]} $GREEN_SEPARATOR $(G_GET_WAN_IP 2>&1)"
		# DietPi-VPN connection status
		(( ${aENABLED[13]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[13]} $GREEN_SEPARATOR $(/boot/dietpi/dietpi-vpn status 2>&1)"
		# Freespace (RootFS)
		(( ${aENABLED[7]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[7]} $GREEN_SEPARATOR $(df -h --output=avail / | mawk 'NR==2 {print $1}' 2>&1)"
		# Freespace (DietPi userdata)
		(( ${aENABLED[8]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[8]} $GREEN_SEPARATOR $(df -h --output=avail /mnt/dietpi_userdata | mawk 'NR==2 {print $1}' 2>&1)"
		# Weather
		(( ${aENABLED[9]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[9]} $GREEN_SEPARATOR $(curl -sSfLm 3 'https://wttr.in/?format=4' 2>&1)"
                # Certificate
                (( ${aENABLED[16]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[16]} $GREEN_SEPARATOR $(openssl x509 --enddate --noout --in /etc/letsencrypt/live/domain.net/cert.pem | awk '/notAfter=/{print substr($2,1) "-" substr($1,10) "-" substr($4,1) " @ " substr($3,1)}' 2>&1)"
		# Custom
		(( ${aENABLED[10]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[10]} $GREEN_SEPARATOR $(bash "$FP_CUSTOM" 2>&1)"
		# MOTD
		if (( ${aENABLED[12]} == 1 ))
		then
			local motd fp_motd='/run/dietpi/.dietpi_motd'
			[[ -f $fp_motd ]] || curl -sSfLm 3 'https://dietpi.com/motd' -o "$fp_motd"
			# shellcheck disable=SC1090
			[[ -f $fp_motd ]] && . "$fp_motd" &> /dev/null && [[ $motd ]] && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[12]} $GREEN_SEPARATOR $motd"
		fi
		echo -e "$GREEN_LINE\n"

		(( ${aENABLED[15]} == 1 )) && Print_Credits
		Print_Updates
		(( ${aENABLED[11]} == 1 )) && Print_Useful_Commands

	}

	Menu_Main(){

		G_WHIP_CHECKLIST_ARRAY=()
		for i in "${!aDESCRIPTION[@]}"
		do
			local state='off'
			(( ${aENABLED[$i]:=0} == 1 )) && state='on'
			G_WHIP_CHECKLIST_ARRAY+=("$i" "${aDESCRIPTION[$i]}" "$state")
		done

		G_WHIP_CHECKLIST "Please (de)select options via spacebar to be shown in the $G_PROGRAM_NAME:" || return 0

		for i in "${!aDESCRIPTION[@]}"
		do
			aENABLED[$i]=0
		done

		for i in $G_WHIP_RETURNED_VALUE
		do
			aENABLED[$i]=1

			# Custom entry
			(( $i == 10 )) || continue

			[[ -f $FP_CUSTOM ]] && G_WHIP_DEFAULT_ITEM=$(<"$FP_CUSTOM") || G_WHIP_DEFAULT_ITEM="echo 'Hello World!'"
			G_WHIP_INPUTBOX 'You have chosen to show a custom entry in the banner.
Please enter the desired command here.\n
NB: It is executed as bash script, so it needs to be in bash compatible syntax.
    For multi-line or non-bash scripts, keep it separate and only add the script call here.' || continue

			echo "$G_WHIP_RETURNED_VALUE" > "$FP_CUSTOM"

			G_WHIP_DEFAULT_ITEM=${aDESCRIPTION[10]}
			G_WHIP_INPUTBOX 'Please enter a meaningful name to be shown in front of your custom command output:' && aDESCRIPTION[10]=$G_WHIP_RETURNED_VALUE
		done

		[[ -f $FP_CUSTOM ]] || aENABLED[10]=0

		Save > "$FP_SAVEFILE"

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main Loop
	#/////////////////////////////////////////////////////////////////////////////////////
	if (( $INPUT == 0 ))
	then
		Print_Header
		Print_Local_Ip

	elif (( $INPUT == 1 ))
	then
		Print_Banner

	elif (( $INPUT == 2 ))
	then
		Menu_Main
		Print_Banner
	fi

	#-----------------------------------------------------------------------------------
	exit 0
	#-----------------------------------------------------------------------------------
}
3 Likes

Thx for suggesting this. I removed domain information from your code. Hope that was OK.

@MichaIng maybe you can have a look. I guess some variable would be needed to specify the domain name.

Thanks for that - I just admit I overlooked that detail in the post. Thanks for the correction, and your interest in my post!!

We could just use the first match:

local certinfo='No certificate found'
for i in /etc/letsencrypt/live/*/cert.pem
do
	certinfo=$(openssl x509 --enddate --noout --in "$i" | mawk '/notAfter=/{print substr($2,1) "-" substr($1,10) "-" substr($4,1) " @ " substr($3,1)}' 2>&1)
	break
done
(( ${aENABLED[16]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[16]} $GREEN_SEPARATOR $certinfo"

that would be a quick win indeed. :+1:

That would be a quick win indeed!!

Thanks for the snippet of code.

I’ve modified my script to suit!!

MANY THANKS !!!

1 Like

We have to trap for those machines that don’t have letsencrypt installed, and so no /etc/letsencrypt directory. I have one Odroid with letsencrypt, and one without.

I changed the code slightly as follows:

            # Certificate
            local certinfo='No certificate found'
            local LETSENCRYPT=/etc/letsencrypt
            if [ -d "$LETSENCRYPT" ]; then
                    for i in $LETSENCRYPT/live/*/cert.pem
                    do
                            certinfo=$(openssl x509 --enddate --noout --in "$i" | mawk '/notAfter=/{print substr($2,1) "-" substr($1,10) "-" substr($4,1) " @ " substr($3,1)}' >
                            break
                    done
            fi
            (( ${aENABLED[16]} == 1 )) && echo -e "$GREEN_BULLET ${aCOLOUR[1]}${aDESCRIPTION[16]} $GREEN_SEPARATOR $certinfo"

This will now report a certificate if found, and if the option is enabled on machines without certificates, display β€œNo certificate found”.

Hope this helps.

G

1 Like

One hint, the banner file will be overwritten on each DietPi update :wink:

I know - That’s why I keep this as a separate dietpi-banner-new, with chmod +x.

I check for any changes in the β€˜new’ dietpi-banner on updates, and then cp dietpi-banner-new dietpi-banner.

That keeps β€œmy” version current.

If you like, you could create a pull request on GitHub to get your enhancement in.

4 Likes

As a newbie, I’m not sure how that works.

But happy to learn :wink:

G

You need a GitHub account, then you can edit the script here: DietPi/dietpi-banner at db683273c34f39b2d55e5927a5c9c9b5c1a0acd4 Β· MichaIng/DietPi Β· GitHub

This automatically creates a fork and new branch and offers you prominently to contribute the change via pull request :slightly_smiling_face:. Let us know if there are questions/issues with the process. It’s however nice when contributions are done that way, so that GitHub and the Git history contain correct attribution for the contributor instead of showing e.g. me just linking to this forum topic in the commit text or so :slightly_smiling_face:. And a GutHub activity/project contribution history may be valuable for yourself in the future, who knows? :wink:

let us know if you need assistance with GitHub stuf :wink:

I think I’ve managed to do it - edited dietpi-banner, pushed and forked.

I hope … :wink:

can you share the GitHub link?

I edited the banner, and comitted the change.

I think this is the link:

Still learning - different to my old days of programming in assembly or Fortran on a DEC pdp-11 :wink:

1 Like

Usually, would need to open a pull request (PR) now, to merge your changed into original DietPi DEV branch.

Can you check, please? My GitHub Desktop app seems to think that I’ve committed the changes.

Gary

yes you commit it to your own GitHub branch/account. Next step would be to open a Pull request from your GitHub branch to ours :wink: