| 1 | #!/bin/bash | 
|---|
| 2 |  | 
|---|
| 3 | #/** | 
|---|
| 4 | #@file    oglivecli | 
|---|
| 5 | #@brief   Command line tool to manage ogLive clients. | 
|---|
| 6 | #@usage   oglivecli Command [Options ...] | 
|---|
| 7 | #@param   Command: | 
|---|
| 8 | #@param     help                show this help | 
|---|
| 9 | #@param     version             show script version | 
|---|
| 10 | #@param     config [Parameter]  show configuration parameters | 
|---|
| 11 | #@param     check               check system consistency | 
|---|
| 12 | #@param     convert             convert old ogclient to new default ogLive client | 
|---|
| 13 | #@param     list                list installed ogLive clients | 
|---|
| 14 | #@param     show all            show JSON information about all installed ogLive clients | 
|---|
| 15 | #@param     show default        show JSON information about ogLive client marked as default | 
|---|
| 16 | #@param     show Index|Dir      show JSON information about an installed ogLive client | 
|---|
| 17 | #@param     search Index|Dir    show corresponding index or directory | 
|---|
| 18 | #@param     download            show a menu to download an ogLive ISO image from the OpenGnsys website | 
|---|
| 19 | #@param     download Iso        download an specific ogLive ISO image from the OpenGnsys website | 
|---|
| 20 | #@param     install Iso         install a new ogLive client from a downloaded ISO image | 
|---|
| 21 | #@param     uninstall Iso       remove ISO image and uninstall its ogLive client | 
|---|
| 22 | #@param     uninstall Index|Dir uninstall an ogLive client | 
|---|
| 23 | #@param     get-default         get index value for default ogLive client | 
|---|
| 24 | #@param     set-default Index   set default ogLive client | 
|---|
| 25 | #@param     rebuild             rebuild a lost configuration file | 
|---|
| 26 | #@param     assign Iso Index    assign an ISO file to a JSON entry | 
|---|
| 27 | #@param   Options: | 
|---|
| 28 | #@param     Index   a number, starting by 0 | 
|---|
| 29 | #@param     Dir     directory (relative to installation directory) | 
|---|
| 30 | #@param     Iso     ISO file name (relative to download URL or download directory) | 
|---|
| 31 | #@warning This script needs "jq" command. | 
|---|
| 32 | #@version 1.1.0 - Initial version. | 
|---|
| 33 | #@author  Ramón M. Gómez - ETSII Univ. Sevilla | 
|---|
| 34 | #@date    2016-12-05 | 
|---|
| 35 | #@version 1.1.1b - Use reduced directory names. | 
|---|
| 36 | #@author  Ramón M. Gómez - ETSII Univ. Sevilla | 
|---|
| 37 | #@date    2020-01-17 | 
|---|
| 38 | #*/ ## | 
|---|
| 39 |  | 
|---|
| 40 |  | 
|---|
| 41 | # Global constants definition. | 
|---|
| 42 | PROG=$(basename "$(realpath "$0")")                     # Program name. | 
|---|
| 43 | OPENGNSYS=/opt/opengnsys                                # OpenGnsys main directory. | 
|---|
| 44 | DOWNLOADDIR=$OPENGNSYS/lib                              # Directory to store ogLive images. | 
|---|
| 45 | DOWNLOADURL="https://ognproject.evlt.uma.es/trac/downloads"     # Download URL. | 
|---|
| 46 | TFTPDIR=$OPENGNSYS/tftpboot                             # TFTP directory. | 
|---|
| 47 | DEFOGLIVE="ogLive"                                      # Default ogLive directory. | 
|---|
| 48 | MINREL=20190601                                         # Mininum ogLive compatibility release. | 
|---|
| 49 | INFOFILE=$OPENGNSYS/etc/ogliveinfo.json                 # Configuration file. | 
|---|
| 50 |  | 
|---|
| 51 |  | 
|---|
| 52 | # Global and secondary functions. | 
|---|
| 53 |  | 
|---|
| 54 | source $OPENGNSYS/lib/ogfunctions.sh || exit 1 | 
|---|
| 55 |  | 
|---|
| 56 | # Create/edit JSON file about installed ogLive clients. | 
|---|
| 57 | function addToJson() { | 
|---|
| 58 | local i DATA OGLIVEDIST="$1" OGLIVEKRNL="$2" OGLIVEARCH="$3" OGLIVEREV="$4" | 
|---|
| 59 | local OGLIVEDIR=$(basename $5 2>/dev/null) OGLIVEISO=$(basename $6 2>/dev/null) | 
|---|
| 60 | # JSON data for installed ogLive. | 
|---|
| 61 | DATA=$(cat << EOT | jq . | 
|---|
| 62 | {"distribution":"$OGLIVEDIST","kernel":"$OGLIVEKRNL","architecture":"$OGLIVEARCH","revision":"$OGLIVEREV","directory":"$OGLIVEDIR","iso":"$OGLIVEISO"} | 
|---|
| 63 | EOT | 
|---|
| 64 | ) | 
|---|
| 65 | # Check JSON file consistency. | 
|---|
| 66 | if [ "$(jq -c keys $INFOFILE 2>/dev/null)" == '["default","oglive"]' ]; then | 
|---|
| 67 | # Check if ogLive is defined into JSON file. | 
|---|
| 68 | n=$(jq ".oglive | length" $INFOFILE) | 
|---|
| 69 | for ((i=0; i<n; i++)); do | 
|---|
| 70 | [ "$(jq ".check=$DATA | .check==.oglive[$i]" $INFOFILE)" == "true" ] && INDEX=$i | 
|---|
| 71 | done | 
|---|
| 72 | # Check if it needs to insert data. | 
|---|
| 73 | if [ -z "$INDEX" ]; then | 
|---|
| 74 | INDEX=$n | 
|---|
| 75 | jq ".oglive |= (. + [$DATA])" $INFOFILE | sponge $INFOFILE | 
|---|
| 76 | fi | 
|---|
| 77 | # Show JSON entry. | 
|---|
| 78 | jq ".oglive[$INDEX]" $INFOFILE | 
|---|
| 79 | else | 
|---|
| 80 | # Create new JSON file. | 
|---|
| 81 | cat << EOT | jq . | tee $INFOFILE | 
|---|
| 82 | {"oglive":[$DATA],"default":0} | 
|---|
| 83 | EOT | 
|---|
| 84 | fi | 
|---|
| 85 | } | 
|---|
| 86 |  | 
|---|
| 87 | # Command functions. | 
|---|
| 88 |  | 
|---|
| 89 | # Convert default ogclient to a new ogLive format. | 
|---|
| 90 | function convert() { | 
|---|
| 91 | local OGCLIENT=ogclient OLDINFOFILE=$OPENGNSYS/doc/veroglive.txt | 
|---|
| 92 | local OGLIVEKRNL OGLIVEDIR OGLIVEISO | 
|---|
| 93 | [ $# -ne 0 ] && raiseError usage | 
|---|
| 94 | [ ! -w $(dirname $INFOFILE) ] && raiseError access "Configuration file." | 
|---|
| 95 | [ -n "$(stat -c "%N" $TFTPDIR/ogclient | awk '$3~/'$DEFOGLIVE'/ {print}')" ] && raiseError access "ogLive is already converted." | 
|---|
| 96 | pushd $TFTPDIR >/dev/null || raiseError access "Installation directory." | 
|---|
| 97 | [ ! -f $OGCLIENT/ogvmlinuz ] && raiseError notfound "\"ogclient\"." | 
|---|
| 98 | # Add entry to JSON file using ogclient kernel version. | 
|---|
| 99 | OGLIVEKRNL=$(file -bkr $OGCLIENT/ogvmlinuz | awk '/Linux/ {for(i=1;i<=NF;i++) if($i~/version/) {v=$(i+1);sub(/-.*/,"",v);print v}}') | 
|---|
| 100 | OGLIVEDIR=$DEFOGLIVE-$OGLIVEKRNL | 
|---|
| 101 | [ -r $OLDINFOFILE ] && OGLIVEISO="$(head -1 $OLDINFOFILE)" | 
|---|
| 102 | addToJson "$(echo $OGLIVEISO|cut -f2 -d-)" "$OGLIVEKRNL" "i386" "${OGLIVEISO##*-}" "$OGLIVEDIR" "$OGLIVEISO.iso" | 
|---|
| 103 | # Rename directory, link to default and clean old files. | 
|---|
| 104 | mv -v $OGCLIENT $OGLIVEDIR | 
|---|
| 105 | ln -vfs $OGLIVEDIR $DEFOGLIVE | 
|---|
| 106 | rm -f $OGCLIENT | 
|---|
| 107 | ln -vfs $DEFOGLIVE $OGCLIENT | 
|---|
| 108 | mv -v $OGCLIENT.old $OGLIVEDIR.old 2>/dev/null | 
|---|
| 109 | rm -fv {ogvmlinuz,oginitrd.img}{,.sum} $OLDINFOFILE | 
|---|
| 110 | popd >/dev/null | 
|---|
| 111 | # Delete old config file. | 
|---|
| 112 | rm -f $OLDINFOFILE | 
|---|
| 113 | } | 
|---|
| 114 |  | 
|---|
| 115 | # Show script configuration parameters. | 
|---|
| 116 | function config() { | 
|---|
| 117 | local DATA | 
|---|
| 118 | DATA=$(cat << EOT | 
|---|
| 119 | [ | 
|---|
| 120 | { "param": "config-file", "description": "Configuration file", "value": "$INFOFILE" }, | 
|---|
| 121 | { "param": "download-url", "description": "ogLive download URL", "value": "$DOWNLOADURL" }, | 
|---|
| 122 | { "param": "download-dir", "description": "ogLive download directory", "value": "$DOWNLOADDIR" }, | 
|---|
| 123 | { "param": "install-dir", "description": "ogLive installation directory", "value": "$TFTPDIR" }, | 
|---|
| 124 | { "param": "default-name", "description": "Default ogLive name", "value": "$DEFOGLIVE" }, | 
|---|
| 125 | { "param": "min-release", "description": "Mainimum compatibility release", "value": "r$MINREL" } | 
|---|
| 126 | ]" | 
|---|
| 127 | EOT | 
|---|
| 128 | ) | 
|---|
| 129 | case $# in | 
|---|
| 130 | 0)  # Show all parameters. | 
|---|
| 131 | echo $DATA | jq -r '.[] | .description + " (" + .param+ ")," + .value' | column -ts, | 
|---|
| 132 | ;; | 
|---|
| 133 | 1)  # Show specified parameter. | 
|---|
| 134 | DATA=$(echo $DATA | jq -r ".[] | select(.param==\"$1\").value") | 
|---|
| 135 | [ "$DATA" ] || raiseError notfound "\"$1\"." | 
|---|
| 136 | echo "$DATA" | 
|---|
| 137 | ;; | 
|---|
| 138 | *)  # Usage error. | 
|---|
| 139 | raiseError usage | 
|---|
| 140 | ;; | 
|---|
| 141 | esac | 
|---|
| 142 | } | 
|---|
| 143 |  | 
|---|
| 144 | # Check consistency, showing configuration problems. | 
|---|
| 145 | function check() { | 
|---|
| 146 | local ERR=0 AUX INST DEF | 
|---|
| 147 | [ $# -ne 0 ] && raiseError usage | 
|---|
| 148 | # Check for old system that needs conversion. | 
|---|
| 149 | if [ -z "$(stat -c "%N" $TFTPDIR/ogclient | awk '$3~/'$DEFOGLIVE'/ {print}')" ]; then | 
|---|
| 150 | echo "This server uses old ogclient, please run \"$PROG convert\" to update." | 
|---|
| 151 | let ERR++ | 
|---|
| 152 | [ ! -f $INFOFILE ] && return $ERR | 
|---|
| 153 | fi | 
|---|
| 154 | # Check for other problems. | 
|---|
| 155 | [ ! -f $INFOFILE ] && echo "Configuration file does not exists: $INFOFILE" && let ERR++ | 
|---|
| 156 | [ -f $INFOFILE -a "$(jq -c keys $INFOFILE 2>/dev/null)" != "[\"default\",\"oglive\"]" ] && echo "Format error in configuration file: $INFOFILE" && let ERR++ | 
|---|
| 157 | [ ! -e $TFTPDIR ] && echo "TFTP directory does not exist: $TFTPDIR." && let ERR++ | 
|---|
| 158 | # Check for installed ogLive clients. | 
|---|
| 159 | INST=( $(find $TFTPDIR/ -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" | sort) ) | 
|---|
| 160 | [[ ${#INST[@]} -eq 0 ]] && echo "No ogLive clients are installed." && let ERR++ | 
|---|
| 161 | DEF=( $(jq -r .oglive[].directory $INFOFILE 2>/dev/null | sort) ) | 
|---|
| 162 | # Compare installed and defined ogLive clients. | 
|---|
| 163 | AUX=$(comm -23 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]})) | 
|---|
| 164 | [ -n "$AUX" ] && echo "Some ogLive are installed but not defined: ${AUX//$'\n'/, }" && let ERR++ | 
|---|
| 165 | AUX=$(comm -13 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]})) | 
|---|
| 166 | [ -n "$AUX" ] && echo "Some ogLive are defined but not installed: ${AUX//$'\n'/, }" && let ERR++ | 
|---|
| 167 | # Compare downloaded and defined ISO images. | 
|---|
| 168 | INST=( $(find $DOWNLOADDIR/ -type f -name "$DEFOGLIVE-*.iso" -printf "%f\n" | sort) ) | 
|---|
| 169 | DEF=( $(jq -r .oglive[].iso $INFOFILE 2>/dev/null | sort) ) | 
|---|
| 170 | AUX=$(comm -23 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]})) | 
|---|
| 171 | [ -n "$AUX" ] && echo "Some ISOs are downloaded but not defined: ${AUX//$'\n'/, }" && let ERR++ | 
|---|
| 172 | AUX=$(comm -13 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]})) | 
|---|
| 173 | [ -n "$AUX" ] && echo "Some ISOs are defined but not downloaded: ${AUX//$'\n'/, }" && let ERR++ | 
|---|
| 174 | # Check for new ISO files downloaded after installation. | 
|---|
| 175 | AUX=$(jq -r '.oglive[] as $og | $og.iso + ":" + $og.directory' $INFOFILE 2>/dev/null | \ | 
|---|
| 176 | while IFS=":" read -r DEF INST; do | 
|---|
| 177 | [ $DOWNLOADDIR/$DEF -nt $TFTPDIR/$INST ] && echo "$DEF" | 
|---|
| 178 | done) | 
|---|
| 179 | [ -n "$AUX" ] && echo "Some ISOs are downloaded after installation: ${AUX//$'\n'/, }" && let ERR++ | 
|---|
| 180 | AUX=$(jq -r '.oglive[] as $og | if ($og.revision[1:9] | tonumber) < '$MINREL' then $og.directory else "" end' $INFOFILE 2>/dev/null) | 
|---|
| 181 | [ -n "$AUX" ] && echo "Some installed ogLive aren't fully compatible: ${AUX//$'\n'/, }" && let ERR++ | 
|---|
| 182 | DEF=$(jq -r ".oglive[$(getdefault)].directory" $INFOFILE 2>/dev/null) | 
|---|
| 183 | INST=$(stat -c "%N" $TFTPDIR/$DEFOGLIVE | cut -f4 -d\') | 
|---|
| 184 | [ "$DEF" != "$INST" ] && echo "Default ogLive is not linked to right directory: $DEF <> $INST" && let ERR++ | 
|---|
| 185 | # Print result. | 
|---|
| 186 | [ $ERR -eq 0 ] && echo "OK!" || echo "Problems detected: $ERR" | 
|---|
| 187 | return $ERR | 
|---|
| 188 | } | 
|---|
| 189 |  | 
|---|
| 190 | # List installed ogLive clients. | 
|---|
| 191 | function list() { | 
|---|
| 192 | [ $# -ne 0 ] && raiseError usage | 
|---|
| 193 | [ ! -r $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 194 | # List all defined indexes, directories and check if missing. | 
|---|
| 195 | jq -r .oglive[].directory $INFOFILE | nl -v 0 | \ | 
|---|
| 196 | awk '{system("echo -n "$0"; test -d '$TFTPDIR'/"$2" || echo -n \" (missing)\"; echo")}' | column -t | 
|---|
| 197 | } | 
|---|
| 198 |  | 
|---|
| 199 | # Show information about an installed ogLive client. | 
|---|
| 200 | function show() { | 
|---|
| 201 | local INDEX | 
|---|
| 202 | [ $# -ne 1 ] && raiseError usage | 
|---|
| 203 | [ ! -r $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 204 | # Show JSON entries. | 
|---|
| 205 | case "$1" in | 
|---|
| 206 | default)    # Default index. | 
|---|
| 207 | INDEX="[$(jq -r .default $INFOFILE)]" ;; | 
|---|
| 208 | all)        # All intries. | 
|---|
| 209 | ;; | 
|---|
| 210 | [0-9]*)     # Index. | 
|---|
| 211 | INDEX="[$1]" ;; | 
|---|
| 212 | *)          # Directory. | 
|---|
| 213 | INDEX="[$(search "$1" 2>/dev/null)]" || raiseError notfound "Directory \"$1\"." | 
|---|
| 214 | ;; | 
|---|
| 215 | esac | 
|---|
| 216 | jq ".oglive$INDEX" $INFOFILE || raiseError notfound "Index \"$1\"." | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | # Show index or directory corresponding to searching parameter. | 
|---|
| 220 | function search() { | 
|---|
| 221 | [ $# -ne 1 ] && raiseError usage | 
|---|
| 222 | [ ! -r $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 223 | # Show corresponding index or directory. | 
|---|
| 224 | list | awk -v d="$1" '{if ($2==d) print $1; if ($1==d) print $2}' | grep . || raiseError notfound "Index/Directory \"$1\"." | 
|---|
| 225 | } | 
|---|
| 226 |  | 
|---|
| 227 | # Show a menu to select and download an ogLive ISO image from the OpenGnsys website. | 
|---|
| 228 | function download() { | 
|---|
| 229 | local OGLIVE NISOS i HTTPCODE TARGETFILE | 
|---|
| 230 | local ISOREL | 
|---|
| 231 | [ $# -gt 1 ] && raiseError usage | 
|---|
| 232 | [ ! -d $DOWNLOADDIR ] && raiseError notfound "Download directory." | 
|---|
| 233 | [ ! -w $DOWNLOADDIR ] && raiseError access "Download directory." | 
|---|
| 234 | # Check parameter. | 
|---|
| 235 | if [ -n "$1" ]; then | 
|---|
| 236 | # ogLive to download. | 
|---|
| 237 | OGLIVEFILE="$1" | 
|---|
| 238 | else | 
|---|
| 239 | # Show download menu. | 
|---|
| 240 | OGLIVE=( $(curl --insecure --silent $DOWNLOADURL | grep "$DEFOGLIVE.*iso") ) | 
|---|
| 241 | NISOS=${#OGLIVE[@]} | 
|---|
| 242 | echo "Available downloads (+ = installed, * = full compatibility):" | 
|---|
| 243 | for i in $(seq 1 $NISOS); do | 
|---|
| 244 | [ -e $DOWNLOADDIR/${OGLIVE[i-1]} ] && OGLIVE[i-1]="(+) ${OGLIVE[i-1]}" | 
|---|
| 245 | ISOREL=${OGLIVE[i-1]##*-r}; ISOREL=${ISOREL%%.*} | 
|---|
| 246 | [ $ISOREL -ge $MINREL ] && OGLIVE[i-1]="(*) ${OGLIVE[i-1]}" | 
|---|
| 247 | done | 
|---|
| 248 | select opt in "${OGLIVE[@]}"; do | 
|---|
| 249 | [ -n "$opt" ] && OGLIVEFILE=${opt##* } && break | 
|---|
| 250 | done | 
|---|
| 251 | fi | 
|---|
| 252 | # Get download size. | 
|---|
| 253 | SOURCELENGTH=$(curl --insecure --head --retry 5 --retry-delay 5 --max-time 30 $DOWNLOADURL/$OGLIVEFILE | awk -F: '/Content-Length:/ {print $2}') | 
|---|
| 254 | [ -n "$SOURCELENGTH" ] || raiseError download "$OGLIVEFILE" | 
|---|
| 255 | # Download ogLive. | 
|---|
| 256 | TARGETFILE=$DOWNLOADDIR/$OGLIVEFILE | 
|---|
| 257 | trap "rm -f $TARGETFILE" 1 2 3 6 9 15 | 
|---|
| 258 | curl --insecure --retry 5 --retry-delay 5 --max-time 30 $DOWNLOADURL/$OGLIVEFILE -o $TARGETFILE || raiseError download "\"$OGLIVEFILE\"." | 
|---|
| 259 | } | 
|---|
| 260 |  | 
|---|
| 261 | # Install an ogLive client from a previously downloaded ISO image. | 
|---|
| 262 | function install() { | 
|---|
| 263 | local OGLIVEFILE OGLIVEDIST OGLIVEREV OGLIVEKRNL OGLIVEDIR OGINITRD OGSQFS OGCLIENT=ogclient | 
|---|
| 264 | local COMPRESS SAMBAPASS TMPDIR RSYNCSERV RSYNCCLNT | 
|---|
| 265 | [ $# -ne 1 ] && raiseError usage | 
|---|
| 266 | OGLIVEFILE=$(realpath $DOWNLOADDIR/$1) | 
|---|
| 267 | # Only 1 file in pathname expansion. | 
|---|
| 268 | [ $(echo $OGLIVEFILE | wc -w) -gt 1 ] && raiseError usage | 
|---|
| 269 | [ ! -f $OGLIVEFILE ] && raiseError notfound "Downloaded file: \"$1\"." | 
|---|
| 270 | [ ! -r $OGLIVEFILE ] && raiseError access "Downloaded file: \"$1\"." | 
|---|
| 271 | [ ! -w $(dirname $INFOFILE) ] && raiseError access "Configuration directory." | 
|---|
| 272 | [ ! -w $TFTPDIR ] && raiseError access "Installation directory." | 
|---|
| 273 | [ -z "$(file -b $OGLIVEFILE | grep "ISO.*ogClient")" ] && raiseError access "File is not an ogLive ISO image." | 
|---|
| 274 | # Working directory: | 
|---|
| 275 | #   64-bit: ogLive-KernelVersion-rCodeRelease | 
|---|
| 276 | #   32-bit: ogLive-KernelVersion-i386-rCodeRelease | 
|---|
| 277 | OGLIVEDIST="$(echo $OGLIVEFILE|cut -f2 -d-)" | 
|---|
| 278 | OGLIVEREV="${OGLIVEFILE##*-}"; OGLIVEREV="${OGLIVEREV%%.*}" | 
|---|
| 279 | OGLIVEKRNL="$(echo $OGLIVEFILE|cut -f3- -d-)"; OGLIVEKRNL="${OGLIVEKRNL%-$OGLIVEREV.*}" | 
|---|
| 280 | OGLIVEARCH="$(echo $OGLIVEFILE|awk -F- '{print $(NF-1)}')" | 
|---|
| 281 | case "$OGLIVEARCH" in | 
|---|
| 282 | i386|amd64) # Get architecture. | 
|---|
| 283 | OGLIVEKRNL="${OGLIVEKRNL%-$OGLIVEARCH}" ;; | 
|---|
| 284 | *)          # 32-bit by default. | 
|---|
| 285 | OGLIVEARCH="i386" ;; | 
|---|
| 286 | esac | 
|---|
| 287 | OGLIVEDIR="$TFTPDIR/$DEFOGLIVE-${OGLIVEKRNL%%-*}-$OGLIVEARCH-$OGLIVEREV" | 
|---|
| 288 | OGLIVEDIR="${OGLIVEDIR/amd64-/}" | 
|---|
| 289 | # Get current or default Samba key. | 
|---|
| 290 | OGINITRD=$OGLIVEDIR/oginitrd.img | 
|---|
| 291 | [ ! -r $OGINITRD ] && OGINITRD=$TFTPDIR/$DEFOGLIVE/oginitrd.img | 
|---|
| 292 | if [ -r $OGINITRD ]; then | 
|---|
| 293 | COMPRESS=$(file -b "$OGINITRD" | awk '{print tolower($1);}') | 
|---|
| 294 | SAMBAPASS=$($COMPRESS -dc $OGINITRD | \ | 
|---|
| 295 | cpio -i --to-stdout scripts/ogfunctions 2>&1 | \ | 
|---|
| 296 | sed -n '/^[         ].*OPTIONS=/s/.*pass=\(\w*\).*/\1/p') | 
|---|
| 297 | fi | 
|---|
| 298 | # Make ogLive backup. | 
|---|
| 299 | rm -fr ${OGLIVEDIR}.old | 
|---|
| 300 | mv -fv $OGLIVEDIR ${OGLIVEDIR}.old 2>/dev/null | 
|---|
| 301 | # Mount ogLive ISO image, update its files and unmount it. | 
|---|
| 302 | TMPDIR=/tmp/${OGLIVEFILE%.iso} | 
|---|
| 303 | mkdir -p $OGLIVEDIR $TMPDIR | 
|---|
| 304 | trap "umount $TMPDIR; rm -fr $TMPDIR" 1 2 3 6 9 15 | 
|---|
| 305 | mount -o loop,ro $OGLIVEFILE $TMPDIR | 
|---|
| 306 | cp -va $TMPDIR/ogclient/* $OGLIVEDIR || raiseError access "Cannot copy files to ogLive directory." | 
|---|
| 307 | umount $TMPDIR | 
|---|
| 308 | # Link to default directory if it's the first ogLive. | 
|---|
| 309 | if [ ! -f $INFOFILE ]; then | 
|---|
| 310 | rm -f $TFTPDIR/$DEFOGLIVE $TFTPDIR/$OGCLIENT | 
|---|
| 311 | ln -vfs $(basename $OGLIVEDIR) $TFTPDIR/$DEFOGLIVE | 
|---|
| 312 | ln -vfs $DEFOGLIVE $TFTPDIR/$OGCLIENT | 
|---|
| 313 | fi | 
|---|
| 314 | # Recover or ask for a new Samba access key. | 
|---|
| 315 | if [ -n "$SAMBAPASS" ]; then | 
|---|
| 316 | echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | $OPENGNSYS/bin/setsmbpass "$(basename $OGLIVEDIR)" | 
|---|
| 317 | else | 
|---|
| 318 | $OPENGNSYS/bin/setsmbpass "$(basename $OGLIVEDIR)" | 
|---|
| 319 | fi | 
|---|
| 320 | # Set permissions. | 
|---|
| 321 | find -L $OGLIVEDIR -type d -exec chmod 755 {} \; | 
|---|
| 322 | find -L $OGLIVEDIR -type f -exec chmod 644 {} \; | 
|---|
| 323 | chown -R :opengnsys $OGLIVEDIR | 
|---|
| 324 | # Mount SquashFS and check Rsync version. | 
|---|
| 325 | OGSQFS=$OGLIVEDIR/ogclient.sqfs | 
|---|
| 326 | mount -o loop,ro $OGSQFS $TMPDIR | 
|---|
| 327 | # If Rsync server version > client version, link to compiled file. | 
|---|
| 328 | RSYNCSERV=$(rsync --version 2>/dev/null | awk '/protocol/ {print $6}') | 
|---|
| 329 | RSYNCCLNT=$(chroot $TMPDIR /usr/bin/rsync --version 2>/dev/null | awk '/protocol/ {print $6}') | 
|---|
| 330 | if [ -z "$RSYNCSERV" -o ${RSYNCSERV:-0} -gt ${RSYNCCLNT:-1} ]; then | 
|---|
| 331 | [ -e $OPENGNSYS/client/bin/rsync-$RSYNCSERV ] && mv -f $OPENGNSYS/client/bin/rsync-$RSYNCSERV $OPENGNSYS/client/bin/rsync | 
|---|
| 332 | else | 
|---|
| 333 | # Else, rename compiled file using Rsync protocol number. | 
|---|
| 334 | [ -e $OPENGNSYS/client/bin/rsync ] && mv -f $OPENGNSYS/client/bin/rsync $OPENGNSYS/client/bin/rsync-$($OPENGNSYS/client/bin/rsync --version 2>/dev/null | awk '/protocol/ {print $6}') | 
|---|
| 335 | fi | 
|---|
| 336 | # Unmount SquashFS. | 
|---|
| 337 | umount $TMPDIR | 
|---|
| 338 | rmdir $TMPDIR | 
|---|
| 339 | # Update JSON file. | 
|---|
| 340 | addToJson "$OGLIVEDIST" "$OGLIVEKRNL" "$OGLIVEARCH" "$OGLIVEREV" "$OGLIVEDIR" "$OGLIVEFILE" | 
|---|
| 341 | } | 
|---|
| 342 |  | 
|---|
| 343 | # Uninstall an ogLive client. | 
|---|
| 344 | function uninstall() { | 
|---|
| 345 | local ISO DIR INDEX DEFINDEX | 
|---|
| 346 | [ $# -ne 1 ] && raiseError usage | 
|---|
| 347 | [ ! -r $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 348 | [ ! -w $TFTPDIR ] && raiseError access "Installation directory." | 
|---|
| 349 | # Get index and directory for the entry. | 
|---|
| 350 | case "$1" in | 
|---|
| 351 | */*)    # Error (access to other directory). | 
|---|
| 352 | raiseError access "Cannot access outside installation directory." | 
|---|
| 353 | ;; | 
|---|
| 354 | *.iso)  # ISO file. | 
|---|
| 355 | ISO="$1" | 
|---|
| 356 | # Working directory (ogLive-Distribution-KernelVersion-CodeRevision). | 
|---|
| 357 | DIR="$(echo $ISO|cut -f1,3 -d-)-${ISO##*-}"; DIR=${DIR%.*} | 
|---|
| 358 | INDEX=$(search $DIR 2>/dev/null) | 
|---|
| 359 | ;; | 
|---|
| 360 | [0-9]*) # Index. | 
|---|
| 361 | INDEX=$1; DIR=$(search $INDEX 2>/dev/null) | 
|---|
| 362 | ;; | 
|---|
| 363 | *)      # Directory. | 
|---|
| 364 | DIR="$1"; INDEX=$(search $DIR 2>/dev/null) | 
|---|
| 365 | ;; | 
|---|
| 366 | esac | 
|---|
| 367 | DEFINDEX=$(getdefault) | 
|---|
| 368 | [[ $INDEX = $DEFINDEX ]] && raiseError access "Cannot uninstall default ogLive." | 
|---|
| 369 | # Remove files and delete index entry. | 
|---|
| 370 | rm -vfr ${ISO:+$DOWNLOADDIR/$ISO} ${DIR:+$TFTPDIR/$DIR}    ### Remove $TFTPDIR/$DIR.old ? | 
|---|
| 371 | if [ -n "$INDEX" ]; then | 
|---|
| 372 | jq "del(.oglive[$INDEX])" $INFOFILE | sponge $INFOFILE | 
|---|
| 373 | # Decrement default index if needed (removed < default). | 
|---|
| 374 | [[ $INDEX < $DEFINDEX ]] && jq ".default=$((DEFINDEX-1))" $INFOFILE | sponge $INFOFILE | 
|---|
| 375 | fi | 
|---|
| 376 | } | 
|---|
| 377 |  | 
|---|
| 378 | # Get default ogLive index. | 
|---|
| 379 | function getdefault() { | 
|---|
| 380 | [ $# -ne 0 ] && raiseError usage | 
|---|
| 381 | [ ! -r $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 382 | # Read default parameter. | 
|---|
| 383 | jq -r .default $INFOFILE || raiseError notfound "Undefined default index." | 
|---|
| 384 | } | 
|---|
| 385 |  | 
|---|
| 386 | # Set default ogLive index. | 
|---|
| 387 | function setdefault() { | 
|---|
| 388 | local INDEX OGLIVEDIR | 
|---|
| 389 | [ $# -ne 1 ] && raiseError usage | 
|---|
| 390 | [ ! -w $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 391 | INDEX=$1 | 
|---|
| 392 | # Check if index entry exists. | 
|---|
| 393 | jq ".oglive[$INDEX]" $INFOFILE || raiseError notfound "Index \"$INDEX\"." | 
|---|
| 394 | # Get ogLive directory. | 
|---|
| 395 | OGLIVEDIR=$(jq -r ".oglive[$INDEX].directory" $INFOFILE) || raiseError notfound "Directory for index \"$INDEX\"." | 
|---|
| 396 | # Update default parameter. | 
|---|
| 397 | jq ".default=$INDEX" $INFOFILE | sponge $INFOFILE | 
|---|
| 398 | # Link to default directory. | 
|---|
| 399 | rm -f $TFTPDIR/$DEFOGLIVE | 
|---|
| 400 | ln -vfs $(basename $OGLIVEDIR) $TFTPDIR/$DEFOGLIVE | 
|---|
| 401 | } | 
|---|
| 402 |  | 
|---|
| 403 | # Rebuild a lost configuration file. | 
|---|
| 404 | function rebuild() { | 
|---|
| 405 | local i INST NF DEF | 
|---|
| 406 | [ $# -ne 0 ] && raiseError usage | 
|---|
| 407 | [ -f $INFOFILE ] && raiseError access "Configuration file exists." | 
|---|
| 408 | INST=$(find $TFTPDIR/ -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" | sort) | 
|---|
| 409 | for i in $INST; do | 
|---|
| 410 | NF=$(echo $i | awk -F- '{print NF-1}') | 
|---|
| 411 | case $NF in | 
|---|
| 412 | 1)  addToJson "" "$(echo $i|cut -f2 -d-)" "i386" "" "$i" "" ;; | 
|---|
| 413 | 2)  eval addToJson $(echo $i | awk -F- '{printf "\"\" %s amd64 %s %s \"\"",$2,$3,$0}') ;; | 
|---|
| 414 | 3)  eval addToJson $(echo $i | awk -F- '{if ($3=="i386") printf "\"\" %s %s %s %s \"\"",$2,$3,$4,$0; else printf "%s %s i386 %s %s \"\"",$2,$3,$4,$0}') ;; | 
|---|
| 415 | 4)  eval addToJson $(echo $i | awk -F- '{printf "%s %s %s %s %s \"\"",$2,$3,$4,$5,$0}') ;; | 
|---|
| 416 | esac | 
|---|
| 417 | # Check for is default oglive. | 
|---|
| 418 | [ -n "$(stat -c "%N" $TFTPDIR/$DEFOGLIVE | awk '$3~/'$i'/ {print}')" ] && DEF="$i" | 
|---|
| 419 | done | 
|---|
| 420 | # Set default ogLive. | 
|---|
| 421 | [ -n "$DEF" ] && setdefault $(search $DEF) | 
|---|
| 422 | } | 
|---|
| 423 |  | 
|---|
| 424 | # Assign an ISO file to a JSON entry. | 
|---|
| 425 | function assign() { | 
|---|
| 426 | local ISOFILE DIR | 
|---|
| 427 | [ $# -ne 2 ] && raiseError usage | 
|---|
| 428 | [ ! -w $INFOFILE ] && raiseError access "Configuration file." | 
|---|
| 429 | # Check if ISO file and index directory exist. | 
|---|
| 430 | ISOFILE=$DOWNLOADFILE/$1 | 
|---|
| 431 | [ ! -f $DOWNLOADDIR/$ISOFILE ] && raiseError notfound "ISO file \"$1\"." | 
|---|
| 432 | DIR=$(search $2 2>/dev/null) | 
|---|
| 433 | [ ! -d $TFTPDIR/$DIR ] && raiseError notfound "Directory for index \"$2\"." | 
|---|
| 434 | # Assign ISO file to JSON entry. | 
|---|
| 435 | jq ".oglive[$2].iso=\"$1\"" $INFOFILE | sponge $INFOFILE && jq ".oglive[$2]" $INFOFILE | 
|---|
| 436 | } | 
|---|
| 437 |  | 
|---|
| 438 |  | 
|---|
| 439 | # Main progrram. | 
|---|
| 440 |  | 
|---|
| 441 | # Access control. | 
|---|
| 442 | [ -r $OPENGNSYS/www/controlacceso.php ] && ACCESS="web" | 
|---|
| 443 | [ "$USER" = "root" ] && ACCESS="root" | 
|---|
| 444 | [ -z "$ACCESS" ] && raiseError access "Need to be root." | 
|---|
| 445 | # Check dependencies. | 
|---|
| 446 | which sponge &>/dev/null || raiseError notfound "Need to install \"moreutils\"." | 
|---|
| 447 | # Commands control. | 
|---|
| 448 | shopt -s extglob | 
|---|
| 449 | case "$ACCESS" in | 
|---|
| 450 | root)   CMDS='+(help|version|convert|config|check|list|show|search|download|install|uninstall|get-default|set-default|rebuild|assign)' ;; | 
|---|
| 451 | web)    CMDS='+(list|show|search|get-default)' ;; | 
|---|
| 452 | esac | 
|---|
| 453 | case "$1" in | 
|---|
| 454 | $CMDS)  COMMAND="${1/-/}"; shift; $COMMAND "$@" ;; | 
|---|
| 455 | *)      raiseError usage ;; | 
|---|
| 456 | esac | 
|---|
| 457 |  | 
|---|
| 458 | exit $? | 
|---|
| 459 |  | 
|---|