#!/bin/bash #/** # checkrepo #@file checkrepo #@brief Generate repository information in a JSON file. #@warning This script uses "jq" command. #@version 1.1.0 - Initial version. #@author Ramón M. Gómez - ETSII Univ. Sevilla #@date 2017-09-27 #*/ ## # Global constants definition. PROG=$(basename "$(realpath "$0")") OPENGNSYS=/opt/opengnsys IMAGESDIR=$OPENGNSYS/images INFOFILE=$OPENGNSYS/etc/repoinfo.json # Auxiliar functions. # Metafunction to check if JSON result exists. function jq() { local OUTPUT OUTPUT=$($JQ "$@") || return $? [[ "$OUTPUT" = "null" ]] && return 1 echo "$OUTPUT" } # Create/edit JSON file about installed ogLive clients. function addToJson() { # Parameters and variables. local IMAGENAME="$1" IMAGETYPE="$2" DATA="$3" JSON i j n m OUNAME OUIND IMGIND local CLONATOR COMPRESSOR FSTYPE DATASIZE CLIENT IFS=":" read -r CLONATOR COMPRESSOR FSTYPE DATASIZE CLIENT <<<"$DATA" # Check if image is restricted to an OU (subdir). if [[ $IMAGENAME =~ / ]]; then OUNAME="${IMAGENAME%/*}" IMAGENAME="${IMAGENAME##*/}" fi # JSON-formatted new entry. JSON=$(cat << EOT | jq . { "name":"$IMAGENAME", "type":"${IMAGETYPE,,}", "clientname":"$CLIENT", "clonator":"${CLONATOR,,}", "compressor":"${COMPRESSOR,,}", "filesystem":"${FSTYPE^^}", "datasize":"$DATASIZE" } EOT ) # Check JSON file consistency. if [ "$(jq -c keys $INFOFILE 2>/dev/null)" == '["directory","images","ous"]' ]; then # Common image. if [ -z "$OUNAME" ]; then # Check if the image is defined into JSON file. n=$(jq ".images | length" $INFOFILE) for ((i=0; i $INFOFILE {"directory":"$IMAGESDIR","images":[$JSON],"ous":[]} EOT else cat << EOT | jq . > $INFOFILE {"directory":"$IMAGESDIR","images":[],"ous":[{"subdir":"$OUNAME","images":[$JSON]}]} EOT fi fi } # Show an error message. function raiseError() { case "$1" in usage) echo "$PROG: Usage error: Type \"$PROG help\"" >&2 exit 1 ;; notfound) echo "$PROG: Resource not found: $2" >&2 exit 2 ;; access) echo "$PROG: Access error: $2" >&2 exit 3 ;; *) echo "$PROG: Unknown error" >&2 exit 1 ;; esac } # Command functions. # Show help message. function help() { cat << EOT $PROG: maintain the repository information. Usage: $PROG EOT } # Check for file-based images to update the repository configuration file. function checkfiles() { local IMAGES IMG INFO DATA # File-stored images. IMAGES=$(find $IMAGESDIR -maxdepth 2 -type f \( -name "*.img" -o -name "*.dsk" \) -print) for IMG in $IMAGES; do # Skip locked images. [ -e "$IMG.lock" ] && continue # Retrieve image creation data and delete temporary file. INFO="$IMG.info" [ -e "$INFO" -a "$INFO" -ot "$IMG" ] && rm -f "$INFO" && echo "Warning: Deleted outdated file $INFO" [ -r "$INFO" ] && DATA=$(tr ':' ' ' < "$INFO") # Add data to configuration file (name, type and data) and remove image info file. IMG=${IMG#$IMAGESDIR/} addToJson "${IMG%.*}" "${IMG##*.}" "$DATA" && rm -f "$INFO" done } # Check for directory-based images to update the repository configuration file. function checkdirs() { local IMAGES IMG INFO DATA # Directory-based images. IMAGES=$(find $IMAGESDIR -maxdepth 3 -type f -name ogimg.info -print) for INFO in $IMAGES; do IMG="$(dirname "${INFO#$IMAGESDIR/}")" # Skip repository root directory and locked images. [ "$IMG" == "$IMAGESDIR" -o -e "$IMG.lock" ] && continue DATA=$(awk -F= '$1=="# fstype" {fs=$2} $1=="# sizedata" {sz=$2} END {printf "::%s:%s:",fs,sz}' "$INFO") # Add data to configuration file (name, type and data). addToJson "$IMG" "dir" "$DATA" done } # Check if images are removed to update the repository configuration file. function checkremoved() { local IMG TYPE OU i j n m [ ! -w "$INFOFILE" ] && raiseError access "$INFOFILE" # Check if global images are defined into JSON file. n=$(jq ".images | length" $INFOFILE) for ((i=0; i/dev/null) || raiseError notfound "Need to install \"jq\"." which sponge &>/dev/null || raiseError notfound "Need to install \"moreutils\"." checkfiles checkdirs checkremoved