summaryrefslogtreecommitdiffstats
path: root/repoman/bin/importimage
diff options
context:
space:
mode:
Diffstat (limited to 'repoman/bin/importimage')
-rwxr-xr-xrepoman/bin/importimage165
1 files changed, 165 insertions, 0 deletions
diff --git a/repoman/bin/importimage b/repoman/bin/importimage
new file mode 100755
index 00000000..3a5a7bf3
--- /dev/null
+++ b/repoman/bin/importimage
@@ -0,0 +1,165 @@
+#!/bin/bash
+#/**
+#@file importimage
+#@usage importimage [str_user] str_repo str_imagename
+#@brief Imports an image file from other repository
+#@param str_user username to access the remote repository (local user, by default)
+#@param str_repo repository IP address or hostaname
+#@param str_imagename image name to download
+#@warning Program will request the repository REST token.
+#@version 1.1.1 - Initial version
+#@author Ramón M. Gómez, ETSII Universidad de Sevilla
+#@date 2017-10-08
+#*/
+
+
+# Variables.
+PROG="$(basename "$0")"
+OPENGNSYS="/opt/opengnsys"
+REPODIR="$OPENGNSYS/images"
+SERVERCONF="$OPENGNSYS/etc/ogAdmServer.cfg"
+DEFAULTFILE="/etc/default/opengnsys"
+MYCNF=$(mktemp /tmp/.my.cnf.XXXXX)
+let BACKUP=0
+source $DEFAULTFILE
+
+# Functions.
+source $OPENGNSYS/lib/ogfunctions.sh
+
+
+# Main program.
+
+# Error control.
+[ "$USER" == "root" ] || raiseError access "Need to be root."
+[ "$RUN_OGADMREPO" == "yes" ] || raiseError access "This server is not defined as image repository."
+[ -w $REPODIR ] || raiseError access "Cannot write in local repository."
+case $# in
+ 2) USERNAME="$SUDO_USER"; REPO="$1"; IMAGE="$2" ;;
+ 3) USERNAME="$1"; REPO="$2"; IMAGE="$3" ;;
+ *) [ "$*" == "help" ] && help || raiseError usage
+esac
+source $SERVERCONF &>/dev/null
+[ "${REPO,,}" == "${HOSTNAME,,}" ] || [ "${REPO,,}" == "localhost" ] || [ "${REPO}" == "127.0.0.1" ] || [ "${REPO,,}" == "${IPlocal,,}}" ] && raiseError access "Cannot import from local repository."
+
+# Fetching image info from the repository.
+read -rp "Enter repository API token: " APITOKEN
+IMAGEINFO="$(curl -k -H "Authorization: $APITOKEN" "https://$REPO/opengnsys/rest/repository/image/$IMAGE" 2> /dev/null | jq -r .)"
+IMAGENAME="$(jq -r '.name' <<< "$IMAGEINFO" 2>/dev/null)"
+case "$IMAGEINFO" in
+ "") # Connection error.
+ raiseError access "Cannot connect to $REPO" ;;
+ "[]") # Image not found.
+ raiseError notfound "Image $IMAGE in remote repository $REPO" ;;
+ *) # Checking REST error.
+ MESSAGE="$(jq -r '.message' <<< "$IMAGEINFO" 2>/dev/null)"
+ [ -n "$MESSAGE" ] && raiseError access "$MESSAGE"
+esac
+IMAGETYPE="$(jq -r '.type' <<< "$IMAGEINFO" 2>/dev/null)"
+IMAGELOCKED="$(jq -r '.locked' <<< "$IMAGEINFO" 2>/dev/null)"
+[ "$IMAGELOCKED" == "true" ] && raiseError access "Image locked by remote repository."
+IMAGESIZE="$(jq -r '.size' <<< "$IMAGEINFO" 2>/dev/null)"
+[ -z "$IMAGESIZE" ] && raiseError access "Cannot retrieve image size"
+# Checking if local image exists.
+IMAGEPATH="$REPODIR/$IMAGENAME.$IMAGETYPE"
+if [ -e "$IMAGEPATH" ]; then
+ # Checking if local image is locked.
+ LOCKFILE="$IMAGEPATH.lock"
+ [ -f "$LOCKFILE" ] && raiseError access "Local image is locked, cannot write."
+ # Confirm image download.
+ read -rp "Image $IMAGENAME exists in the local repository. Do you want to continue? (y/N): " ANSWER
+ [ "${ANSWER,,}" = "y" ] || exit
+ BACKUP=1
+ REMOTEDATE=$(jq -r '.modified' <<< "$IMAGEINFO" 2>/dev/null)
+ LOCALDATE=$(stat -c "%y" "$IMAGEPATH" | cut -f1 -d.)
+ if [[ "$REMOTEDATE" < "$LOCALDATE" ]]; then
+ read -rp "Remote image seems older than the local one. Do you want to continue? (y/N): " ANSWER
+ [ "${ANSWER,,}" = "y" ] || exit
+ fi
+fi
+
+# Trapping signal to unlock image before exit.
+trap "rm -f $LOCKFILE $MYCNF" 1 2 3 6 9 15
+# Creating lock file.
+touch $LOCKFILE
+# Backing up local image.
+if [ $BACKUP -eq 1 ]; then
+ mv -vf "$IMAGEPATH" "$IMAGEPATH.ant" 2>/dev/null
+ mv -vf "$IMAGEPATH.torrent" "$IMAGEPATH.torrent.ant" 2>/dev/null
+ mv -vf "$IMAGEPATH.sum" "$IMAGEPATH.sum.ant" 2>/dev/null
+ mv -vf "$IMAGEPATH.full.sum" "$IMAGEPATH.full.sum.ant" 2>/dev/null
+fi
+# Downloading image file.
+[[ $IMAGEPATH =~ / ]] && mkdir -p "$(dirname "$IMAGEPATH")"
+scp "$USERNAME@$REPO:$IMAGEPATH" $REPODIR
+ERRCODE=$?
+if [ $ERRCODE -eq 0 ]; then
+ # Storing creation info.
+ jq -r '.clonator+":"+.compressor+":"+.filesystem+":"+(.datasize|tostring)+":"' <<<"$IMAGEINFO" > "$IMAGEPATH.info"
+ # Updating the database when the repo is also configured as Administration Server.
+ if [ "$RUN_OGADMREPO" == "yes" ]; then
+ # Creating credentials file.
+ cat << EOT > $MYCNF
+[client]
+user=$USUARIO
+password=$PASSWORD
+EOT
+ if [ $BACKUP -eq 1 ]; then
+ # If the image exists, increase its revision number.
+ mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \
+ "UPDATE imagenes
+ SET revision = revision + 1
+ WHERE nombreca='$IMAGE';" || \
+ echo "Warning: database cannot be updated."
+ else
+ # Obtaining defined Organizational Units.
+ while read -re DATA; do
+ OUS[${#OUS[@]}]="$DATA"
+ done <<<$(mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -Nse \
+ "SELECT idcentro, nombrecentro FROM centros;")
+ if [ ${#OUS[@]} -eq 1 ]; then
+ # Only 1 OU is defined.
+ let OUID="${OUS%% *}"
+ else
+ # Choose image OU.
+ echo "Choose Organization Unit:"
+ for ((i=0; i<${#OUS[@]}; i++)); do
+ echo " $i: ${OUS[i]#* }"
+ done
+ read -rp "Enter number (0 by default): " ANSWER
+ let OUID="${OUS[ANSWER]%% *}" 2>/dev/null || let OUID="${OUS[0]%% *}"
+ fi
+ # Creating a new image associated with an empty software profile.
+ mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \
+ "SET @repoid = (SELECT idrepositorio FROM repositorios
+ WHERE ip='$IPlocal' LIMIT 1),
+ @profname = '$IMAGE imported from $REPO';
+ INSERT INTO perfilessoft (descripcion, idcentro, grupoid)
+ SELECT @profname, '$OUID', 0 FROM DUAL
+ WHERE NOT EXISTS
+ (SELECT descripcion FROM perfilessoft
+ WHERE descripcion=@profname AND idcentro='$OUID')
+ LIMIT 1;
+ SET @profid = LAST_INSERT_ID();
+ INSERT INTO imagenes
+ (nombreca, revision, idperfilsoft, idcentro, comentarios, grupoid, idrepositorio, fechacreacion)
+ VALUES ('$IMAGE', 1, @profid, '$OUID', 'Image imported from repo $REPO', 0, @repoid, NOW());" || \
+ echo "Warning: database cannot be updated."
+ fi
+ fi
+ # Cheking image size.
+ DOWNLOADSIZE=$(stat -c "%s" "$IMAGEPATH")
+ [ $IMAGESIZE -ne $DOWNLOADSIZE ] && echo "Warning: image sizes differ: source=$IMAGESIZE, target=$DOWNLOADSIZE."
+else
+ # On download error, trying to recover backup.
+ raiseError download "$USERNAME@$REPO:$IMAGEPATH"
+ if [ $BACKUP -eq 1 ]; then
+ mv -vf "$IMAGEPATH.ant" "$IMAGEPATH" 2>/dev/null
+ mv -vf "$IMAGEPATH.torrent.ant" "$IMAGEPATH.torrent" 2>/dev/null
+ mv -vf "$IMAGEPATH.sum.ant" "$IMAGEPATH.sum" 2>/dev/null
+ mv -vf "$IMAGEPATH.full.sum.ant" "$IMAGEPATH.full.sum" 2>/dev/null
+ fi
+fi
+
+# Unlocking image and removing temporary file.
+rm -f $LOCKFILE $MYCNF
+