source: server/bin/oglivecli @ 90e3284

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since 90e3284 was b495a61, checked in by ramon <ramongomez@…>, 8 years ago

#768: Integrar script oglivecli en rama de desarrollo; corregir errata en comando set-default y añadir opciones para comando config.

git-svn-id: https://opengnsys.es/svn/branches/version1.1@5148 a21b9725-9963-47de-94b9-378ad31fedc9

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