openpkg/stack.sh

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

     1 ##
     2 ##  OpenPKG Software Stack Generation
     3 ##  Copyright (c) 2010-2012 OpenPKG GmbH <http://openpkg.com/>
     4 ##
     5 ##  This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
     6 ##  All rights reserved. Licenses which grant limited permission to use,
     7 ##  copy, modify and distribute this software are available from the
     8 ##  OpenPKG GmbH.
     9 ##
    10 ##  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
    11 ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    12 ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    13 ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
    14 ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    15 ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    16 ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    17 ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    18 ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    19 ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    20 ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    21 ##  SUCH DAMAGE.
    22 ##
    24 #   configuration
    25 openpkg="${OPENPKG_PREFIX}/bin/openpkg"
    26 curl="${OPENPKG_PREFIX}/bin/openpkg curl"
    27 shtool="${OPENPKG_PREFIX}/lib/openpkg/shtool"
    29 ##
    30 ##  COMMAND LINE PARSING
    31 ##
    33 str_usage="[-h|--help] [-v|--verbose <level>] [-o|--output <dir>] [-D|--define <name>=<value> ...] [-u|--unversioned] [-q|--query] <name>.stk"
    34 arg_spec="1="
    35 opt_spec="h.v:o:D+u.q."
    36 opt_alias="h:help,v:verbose,o:output,D:define,u:unversioned,q:query"
    37 opt_h=no
    38 opt_v=4
    39 opt_o="."
    40 opt_D=""
    41 opt_u=no
    42 opt_q=no
    44 #   parse argument specification string
    45 eval `echo $arg_spec |\
    46       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
    48 #   parse option specification string
    49 eval `echo $opt_spec |\
    50       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
    52 #   parse option alias string
    53 eval `echo $opt_alias |\
    54       sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
    56 #   interate over argument line
    57 opt_PREV=''
    58 while [ $# -gt 0 ]; do
    59     #   special option stops processing
    60     if [ ".$1" = ".--" ]; then
    61         shift
    62         break
    63     fi
    65     #   determine option and argument
    66     opt_ARG_OK=no
    67     if [ ".$opt_PREV" != . ]; then
    68         #   merge previous seen option with argument
    69         opt_OPT="$opt_PREV"
    70         opt_ARG="$1"
    71         opt_ARG_OK=yes
    72         opt_PREV=''
    73     else
    74         #   split argument into option and argument
    75         case "$1" in
    76             --[a-zA-Z0-9]*=*)
    77                 eval `echo "x$1" |\
    78                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
    79                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
    80                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
    81                 ;;
    82             --[a-zA-Z0-9]*)
    83                 opt_OPT=`echo "x$1" | cut -c4-`
    84                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
    85                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
    86                 opt_ARG=''
    87                 ;;
    88             -[a-zA-Z0-9]*)
    89                 eval `echo "x$1" |\
    90                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
    91                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
    92                 ;;
    93             -[a-zA-Z0-9])
    94                 opt_OPT=`echo "x$1" | cut -c3-`
    95                 opt_ARG=''
    96                 ;;
    97             *)
    98                 break
    99                 ;;
   100         esac
   101     fi
   103     #   eat up option
   104     shift
   106     #   determine whether option needs an argument
   107     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
   108     if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
   109         if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
   110             opt_PREV="$opt_OPT"
   111             continue
   112         fi
   113     fi
   115     #   process option
   116     case $opt_MODE in
   117         '.' )
   118             #   boolean option
   119             eval "opt_${opt_OPT}=yes"
   120             ;;
   121         ':' )
   122             #   option with argument (multiple occurances override)
   123             eval "opt_${opt_OPT}=\"\$opt_ARG\""
   124             ;;
   125         '+' )
   126             #   option with argument (multiple occurances append)
   127             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
   128             ;;
   129         * )
   130             echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
   131             exit 1
   132             ;;
   133     esac
   134 done
   135 if [ ".$opt_PREV" != . ]; then
   136     echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
   137     exit 1
   138 fi
   140 #   process help option
   141 if [ ".$opt_h" = .yes ]; then
   142     echo "Usage: $0 $str_usage"
   143     exit 0
   144 fi
   146 #   complain about incorrect number of arguments
   147 case $arg_MODE in
   148     '=' )
   149         if [ $# -ne $arg_NUMS ]; then
   150             echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
   151             exit 1
   152         fi
   153         ;;
   154     '+' )
   155         if [ $# -lt $arg_NUMS ]; then
   156             echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
   157             exit 1
   158         fi
   159         ;;
   160 esac
   162 ##
   163 ##  HELPER FUNCTIONS
   164 ##
   166 #   helper function for graceful termination
   167 die () {
   168     echo "$0: ERROR: $*"
   169     exit 1
   170 }
   172 #   helper function for verbose messages
   173 verbose () {
   174     lvl="$1"
   175     msg="$2"
   176     if [ $opt_v -ge $lvl ]; then
   177         case "$lvl" in
   178             1 ) str_prefix="**" ;;
   179             2 ) str_prefix="++" ;;
   180             3 ) str_prefix="--" ;;
   181             4 ) str_prefix=".." ;;
   182         esac
   183         echo "${str_prefix} ${msg}"
   184     fi
   185 }
   187 #   expand macros
   188 macro_expand () {
   189     stk="$1"
   191     #   load all options and their default values
   192     options=""
   193     for option in `sed <$stk \
   194         -e "1,/^%options/d" -e '/^%/,$d' \
   195         -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' \
   196         -e 's; *[^ ]*$;;'`; do
   197         options="$options $option"
   198     done
   199     eval `sed <$stk \
   200         -e "1,/^%options/d" -e '/^%/,$d' \
   201         -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \
   202         -e 's:^\([^ ]*\) *\([^ ]*\)$:option_\1="\2";:'`
   204     #   override options with defined values
   205     for define in $opt_D; do
   206         name=`echo "$define" | sed -e 's;=.*$;;'`
   207         value=`echo "$define" | sed -e 's;^.*=;;'`
   208         eval "exists=\"\${option_${name}}\""
   209         if [ ".$exists" = . ]; then
   210             die "definition of not-existing option \"$name\""
   211         fi
   212         eval "option_${name}=\"${value}\""
   213     done
   215     #   expand macros
   216     cmd="sed"
   217     for name in $options; do
   218         eval "value=\"\${option_${name}}\""
   219         cmd="$cmd -e 's;%{[?]$name:\\([^}]*\\)};\1;g'"
   220         cmd="$cmd -e 's;%{![?]$name:\\([^}]*\\)};;g'"
   221         cmd="$cmd -e 's;%{$name};$value;g'"
   222     done
   223     cmd="$cmd -e 's;%{[?][^:}]*:[^}]*};;g'"
   224     cmd="$cmd -e 's;%{![?][^:}]*:\([^}]*\)};\1;g'"
   225     eval "$cmd"
   226 }
   228 #   extract macro-expanded header
   229 header () {
   230     stk="$1"
   231     hdr="$2"
   232     exists=`egrep "^${hdr}" $stk`
   233     if [ ".$exists" != . ]; then
   234         egrep "^${hdr}:" $stk | \
   235         sed -e 's;^[^:]*: *;;' -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \
   236         macro_expand "$stk"
   237     fi
   238 }
   240 #   extract macro-expanded section
   241 section () {
   242     stk="$1"
   243     sec="$2"
   244     exists=`egrep "^%${sec}" $stk`
   245     if [ ".$exists" != . ]; then
   246         sed <$stk \
   247             -e "1,/^%${sec}/d" -e '/^%/,$d' \
   248             -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \
   249         macro_expand "$stk"
   250     fi
   251 }
   253 ##
   254 ##  MAIN
   255 ##
   257 #   determine stack file
   258 stk="$1"
   259 shift
   261 #   support stand-alone query operation
   262 if [ ".$opt_q" = .yes ]; then
   263     name=`header "$stk" "Name"`
   264     summary=`header "$stk" "Summary"`
   265     packager=`header "$stk" "Packager"`
   266     version=`header "$stk" "Version"`
   267     release=`header "$stk" "Release"`
   268     echo "name=\"$name\";"
   269     echo "summary=\"$summary\";"
   270     echo "packager=\"$packager\";"
   271     echo "version=\"$version\";"
   272     echo "release=\"$release\";"
   273     sed <$stk \
   274         -e "1,/^%options/d" -e '/^%/,$d' \
   275         -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \
   276         -e 's:^\([^ ]*\) *\([^ ]*\)$:\1="\2";:'
   277     exit 0
   278 fi
   280 #   determine temporary directory
   281 tmpdir="${TMPDIR-/tmp}"
   283 #   provide verbose header
   284 verbose 1 "OpenPKG Software Stack Generation"
   286 #   determine information
   287 verbose 2 "determining software stack information"
   288 name=`header "$stk" "Name"`
   289 summary=`header "$stk" "Summary"`
   290 packager=`header "$stk" "Packager"`
   291 version=`header "$stk" "Version"`
   292 release=`header "$stk" "Release"`
   293 verbose 3 "Name:        $name"
   294 verbose 3 "Summary:     $summary"
   295 verbose 3 "Packager:    $packager"
   296 verbose 3 "Version:     $version"
   297 verbose 3 "Release:     $release"
   298 if [ ".$opt_u" = .yes ]; then
   299     basename="$name"
   300 else
   301     basename="$name-$version-$release"
   302 fi
   304 #   determine URLs
   305 verbose 2 "determining software stack packages"
   306 repo=`section "$stk" "repository"`
   307 verbose 3 "repository:  [URL]  $repo"
   308 $openpkg build -r "$repo" -Z -u -K -B \
   309     `section "$stk" "packages"` | \
   310     egrep "openpkg curl" | \
   311     sed -e 's;^.* \([^ ]*\) || exit.*$;\1;' \
   312         -e '/\/openpkg-[0-9].*\.src\.rpm/{h;s/\.src\.rpm$/.src.sh/;p;x}' \
   313     >$tmpdir/url.txt
   315 #   provide header
   316 verbose 2 "assembling software stack sources"
   318 #   download source packages
   319 if [ ! -d "$opt_o/$basename.src.d" ]; then
   320     verbose 3 "creating:    [DIR]  $opt_o/$basename.src.d"
   321     $shtool mkdir -p -m 755 "$opt_o/$basename.src.d"
   322 else
   323     verbose 3 "reusing:     [DIR]  $opt_o/$basename.src.d"
   324 fi
   325 for url in `cat $tmpdir/url.txt`; do
   326     url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'`
   327     if [ ! -f "$opt_o/$basename.src.d/$url_file" ]; then
   328         verbose 3 "downloading: [FILE] $opt_o/$basename.src.d/$url_file"
   329         if [ $opt_v -ge 4 ]; then
   330             $curl '-#' -L -k -o $opt_o/$basename.src.d/$url_file $url
   331         else
   332             $curl -s -L -k -o $opt_o/$basename.src.d/$url_file $url
   333         fi
   334     else
   335         verbose 3 "reusing:     [FILE] $opt_o/$basename.src.d/$url_file"
   336     fi
   337 done
   338 for path in $opt_o/$basename.src.d/*.src.sh $opt_o/$basename.src.d/*.src.rpm; do
   339     if [ ! -f "$path" ]; then
   340         continue
   341     fi
   342     path_file=`echo $path | sed -e 's;^.*/\([^/]*\)$;\1;'`
   343     found=no
   344     for url in `cat $tmpdir/url.txt`; do
   345         url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'`
   346         if [ ".$url_file" = ".$path_file" ]; then
   347             found=yes
   348             break
   349         fi
   350     done
   351     if [ ".$found" = .no ]; then
   352         verbose 3 "removing:    [FILE] $path"
   353         rm -f "$path"
   354     fi
   355 done
   356 rm -f $tmpdir/url.txt
   358 #   generate XML/RDF index for SRPM packages
   359 verbose 3 "generating:  [FILE] $opt_o/$basename.src.d/00INDEX.rdf"
   360 $openpkg index -r "OpenPKG/SRPM" \
   361     -o $opt_o/$basename.src.d/00INDEX.rdf \
   362     -i $opt_o/$basename.src.d
   364 #   generate deployment utility
   365 verbose 3 "generating:  [FILE] $opt_o/$basename.sh"; \
   366 section "$stk" "framework" >$tmpdir/framework.txt
   367 section "$stk" "prolog" >$tmpdir/prolog.txt
   368 section "$stk" "epilog" >$tmpdir/epilog.txt
   369 HAVE_PROLOG=no; if [ ".`cat $tmpdir/prolog.txt`" != . ]; then HAVE_PROLOG=yes; fi
   370 HAVE_EPILOG=no; if [ ".`cat $tmpdir/epilog.txt`" != . ]; then HAVE_EPILOG=yes; fi
   371 $openpkg build -r "$repo" -Z -u -K \
   372     `section "$stk" "packages"` | \
   373 grep -v "^#" | \
   374 grep -v "^echo" | \
   375 grep -v "^rm" | \
   376 egrep -v "^(if|fi)" | \
   377 grep -v "openpkg curl" | \
   378 grep -v "openpkg rpm -Uvh" | \
   379 sed -e 's;.*openpkg rpm ;;' \
   380     -e 's; || exit.*;;' \
   381     -e 's;--rebuild ;;' \
   382     -e 's;/.*/\([^/]*\.src\.rpm\);\1;' \
   383     -e 's;^\(.*\) \([^/]*\.src\.rpm\);\2 \1;' \
   384     -e "s;--define '\\([^ ]*\\) \\([^ ]*\\)';\\1=\\2;g" \
   385     -e 's;\.src\.rpm;;' \
   386     >$tmpdir/packages.txt
   387 sed <$0 \
   388     -e '1,/^____/d' \
   389     -e "/^CFG_FRAMEWORK=\"/r $tmpdir/framework.txt" \
   390     -e "/^CFG_PACKAGES=\"/r $tmpdir/packages.txt" \
   391     -e "s;@HAVE_PROLOG@;$HAVE_PROLOG;" \
   392     -e "/%prolog/r $tmpdir/prolog.txt" \
   393     -e "s;@HAVE_EPILOG@;$HAVE_EPILOG;" \
   394     -e "/%epilog/r $tmpdir/epilog.txt" \
   395     -e "/^## SHTOOL ##/r $shtool" \
   396     -e "s;^\\(CFG_NAME=\"\\).*\\(\"\\);\\1$name\\2;" \
   397     -e "s;^\\(CFG_SUMMARY=\"\\).*\\(\"\\);\\1$summary\\2;" \
   398     -e "s;^\\(CFG_PACKAGER=\"\\).*\\(\"\\);\\1$packager\\2;" \
   399     -e "s;^\\(CFG_VERSION=\"\\).*\\(\"\\);\\1$version\\2;" \
   400     -e "s;^\\(CFG_RELEASE=\"\\).*\\(\"\\);\\1$release\\2;" \
   401     -e "s;^\\(CFG_UNVERSIONED=\"\\).*\\(\"\\);\\1$opt_u\\2;" \
   402     >$opt_o/$basename.sh
   404 #   cleanup
   405 rm -f $tmpdir/framework.txt
   406 rm -f $tmpdir/packages.txt
   407 rm -f $tmpdir/prolog.txt
   408 rm -f $tmpdir/epilog.txt
   410 #   exit gracefully
   411 exit 0
   413 ##
   414 ##  DEPLOYMENT SCRIPT
   415 ##
   417 ______________________________________________________________________________
   418 #!/bin/sh
   419 #![OpenPKG]
   420 ##
   421 ##  OpenPKG Software Stack Deployment
   422 ##  Copyright (c) 2010-2012 OpenPKG GmbH <http://openpkg.com/>
   423 ##
   424 ##  This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
   425 ##  All rights reserved. Licenses which grant limited permission to use,
   426 ##  copy, modify and distribute this software are available from the
   427 ##  OpenPKG GmbH.
   428 ##
   429 ##  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
   430 ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   431 ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   432 ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
   433 ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   434 ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   435 ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   436 ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   437 ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   438 ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   439 ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   440 ##  SUCH DAMAGE.
   441 ##
   443 ##
   444 ##  COMMAND LINE PARSING
   445 ##
   447 str_usage="[-h|--help] [-v|--verbose <level>] [-c|--cleanup <level>] [-D|--define <name>=<value> ...] [-s|--srcdir <dir>] [-o|--outdir <dir>] [-t|--tmpdir <dir>] [-S <sudo>]"
   448 arg_spec="0="
   449 opt_spec="h.v:c:D+s:o:t:S:"
   450 opt_alias="h:help,v:verbose,c:cleanup,D:define,s:srcdir,o:outdir,t:tmpdir,S:sudo"
   451 opt_h=no
   452 opt_v=3
   453 opt_c=1
   454 opt_D=""
   455 opt_s=""
   456 opt_o=""
   457 opt_t="${TMPDIR-/tmp}"
   458 opt_S=""
   460 #   parse argument specification string
   461 eval `echo $arg_spec |\
   462       sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
   464 #   parse option specification string
   465 eval `echo $opt_spec |\
   466       sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
   468 #   parse option alias string
   469 eval `echo $opt_alias |\
   470       sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
   472 #   interate over argument line
   473 opt_PREV=''
   474 while [ $# -gt 0 ]; do
   475     #   special option stops processing
   476     if [ ".$1" = ".--" ]; then
   477         shift
   478         break
   479     fi
   481     #   determine option and argument
   482     opt_ARG_OK=no
   483     if [ ".$opt_PREV" != . ]; then
   484         #   merge previous seen option with argument
   485         opt_OPT="$opt_PREV"
   486         opt_ARG="$1"
   487         opt_ARG_OK=yes
   488         opt_PREV=''
   489     else
   490         #   split argument into option and argument
   491         case "$1" in
   492             --[a-zA-Z0-9]*=*)
   493                 eval `echo "x$1" |\
   494                       sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
   495                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
   496                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
   497                 ;;
   498             --[a-zA-Z0-9]*)
   499                 opt_OPT=`echo "x$1" | cut -c4-`
   500                 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
   501                 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
   502                 opt_ARG=''
   503                 ;;
   504             -[a-zA-Z0-9]*)
   505                 eval `echo "x$1" |\
   506                       sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
   507                           -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
   508                 ;;
   509             -[a-zA-Z0-9])
   510                 opt_OPT=`echo "x$1" | cut -c3-`
   511                 opt_ARG=''
   512                 ;;
   513             *)
   514                 break
   515                 ;;
   516         esac
   517     fi
   519     #   eat up option
   520     shift
   522     #   determine whether option needs an argument
   523     eval "opt_MODE=\$opt_MODE_${opt_OPT}"
   524     if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
   525         if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
   526             opt_PREV="$opt_OPT"
   527             continue
   528         fi
   529     fi
   531     #   process option
   532     case $opt_MODE in
   533         '.' )
   534             #   boolean option
   535             eval "opt_${opt_OPT}=yes"
   536             ;;
   537         ':' )
   538             #   option with argument (multiple occurances override)
   539             eval "opt_${opt_OPT}=\"\$opt_ARG\""
   540             ;;
   541         '+' )
   542             #   option with argument (multiple occurances append)
   543             eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
   544             ;;
   545         * )
   546             echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
   547             exit 1
   548             ;;
   549     esac
   550 done
   551 if [ ".$opt_PREV" != . ]; then
   552     echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
   553     exit 1
   554 fi
   556 #   process help option
   557 if [ ".$opt_h" = .yes ]; then
   558     echo "Usage: $0 $str_usage"
   559     exit 0
   560 fi
   562 #   complain about incorrect number of arguments
   563 case $arg_MODE in
   564     '=' )
   565         if [ $# -ne $arg_NUMS ]; then
   566             echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
   567             exit 1
   568         fi
   569         ;;
   570     '+' )
   571         if [ $# -lt $arg_NUMS ]; then
   572             echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
   573             exit 1
   574         fi
   575         ;;
   576 esac
   578 #   helper function for verbose messages
   579 verbose () {
   580     lvl="$1"
   581     msg="$2"
   582     if [ $opt_v -ge $lvl ]; then
   583         case "$lvl" in
   584             1 ) str_prefix="**" ;;
   585             2 ) str_prefix="++" ;;
   586             3 ) str_prefix="--" ;;
   587             4 ) str_prefix=".." ;;
   588         esac
   589         echo "${str_prefix} ${msg}"
   590     fi
   591 }
   593 #   helper function for graceful termination
   594 die () {
   595     echo "$0: ERROR: $*"
   596     exit 1
   597 }
   599 ##
   600 ##  MAIN
   601 ##
   603 #   the stack information
   604 CFG_NAME=""
   605 CFG_SUMMARY=""
   606 CFG_PACKAGER=""
   607 CFG_VERSION=""
   608 CFG_RELEASE=""
   610 #   the required OpenPKG framework parameters
   611 CFG_FRAMEWORK="
   612 "
   614 #   the required OpenPKG packages
   615 #   (in topological order and with build options resolved)
   616 CFG_PACKAGES="
   617 "
   619 #   whether unversioned output directory should be used
   620 CFG_UNVERSIONED=""
   622 #   display information
   623 verbose 1 "OpenPKG Software Stack Deployment"
   624 verbose 2 "determining information"
   626 #   parse OpenPKG framework parameters
   627 params="
   628     prefix
   629     user group
   630     susr musr rusr nusr
   631     sgrp mgrp rgrp ngrp
   632     suid muid ruid nuid
   633     sgid mgid rgid ngid
   634     tag
   635 "
   636 for param in $params; do
   637     eval "CF_$param=''"
   638 done
   639 for opt in $CFG_FRAMEWORK; do
   640     case "$opt" in
   641         --[a-zA-Z0-9-]*=* )
   642             name=`echo "$opt" | sed -e 's;^--\([^=]*\)=.*$;\1;'`
   643             value=`echo "$opt" | sed -e 's;^--[^=]*=\(.*\)$;\1;'`
   644             eval "CF_$name='$value'"
   645             ;;
   646     esac
   647 done
   648 for define in $opt_D; do
   649     name=`echo "$define" | sed -e 's;=.*$;;'`
   650     value=`echo "$define" | sed -e 's;^.*=;;'`
   651     eval "CF_$name='$value'"
   652 done
   653 CFG_FRAMEWORK=''
   654 for name in $params; do
   655     eval "value=\"\$CF_$name\""
   656     if [ ".$value" != . ]; then
   657         if [ ".$CFG_FRAMEWORK" = . ]; then
   658             CFG_FRAMEWORK="--$name=$value"
   659         else
   660             CFG_FRAMEWORK="$CFG_FRAMEWORK --$name=$value"
   661         fi
   662     fi
   663 done
   664 if [ ".$CF_musr" = . ]; then CF_musr="$CF_user";    fi
   665 if [ ".$CF_mgrp" = . ]; then CF_mgrp="$CF_group";   fi
   666 if [ ".$CF_rusr" = . ]; then CF_rusr="$CF_user-r";  fi
   667 if [ ".$CF_rgrp" = . ]; then CF_rgrp="$CF_group-r"; fi
   668 if [ ".$CF_nusr" = . ]; then CF_nusr="$CF_user-n";  fi
   669 if [ ".$CF_ngrp" = . ]; then CF_ngrp="$CF_group-n"; fi
   670 verbose 3 "name:     $CFG_NAME"
   671 verbose 3 "summary:  $CFG_SUMMARY"
   672 verbose 3 "packager: $CFG_PACKAGER"
   673 verbose 3 "version:  $CFG_VERSION"
   674 verbose 3 "release:  $CFG_RELEASE"
   676 #   determine target parameters
   677 if [ ".$CF_prefix" = . ]; then
   678     die "OpenPKG Framework parameter \"prefix\" required"
   679 fi
   680 prefix="$CF_prefix"
   681 if [ ".$CF_tag" = . ]; then
   682     die "OpenPKG Framework parameter \"tag\" required"
   683 fi
   684 tag="$CF_tag"
   685 shtool="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.shtool.sh"
   686 sed <$0 -e '1,/^## SHTOOL ##.*/d' >$shtool
   687 platform=`sh $shtool platform -n -L -S "" -C "+" -F '%<ap>-%<sp>'`
   688 verbose 3 "platform: $platform"
   689 verbose 3 "tag:      $tag"
   690 verbose 3 "prefix:   $prefix"
   692 #   determine operation directories
   693 srcdir="$opt_s"
   694 if [ ".$srcdir" = . ]; then
   695     srcdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.src.d"
   696 fi
   697 tmpdir="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.d"
   698 if [ ! -d "$tmpdir" ]; then
   699     (   umask 077
   700         rm -rf "$tmpdir" >/dev/null 2>&1 || true
   701         sh $shtool mkdir -p -m 700 "$tmpdir" >/dev/null 2>&1
   702         if [ $? -ne 0 ]; then
   703             die "failed to create temporary directory: \"$tmpdir\""
   704         fi
   705     ) || exit $?
   706 fi
   707 outdir="$opt_o"
   708 if [ ".$outdir" = . ]; then
   709     if [ ".$CFG_UNVERSIONED" = .yes ]; then
   710         outdir="$CFG_NAME.$platform-$tag.d"
   711     else
   712         outdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.$platform-$tag.d"
   713     fi
   714 fi
   715 if [ ! -d "$outdir" ]; then
   716     sh $shtool mkdir -p -m 755 "$outdir" >/dev/null 2>&1
   717     if [ $? -ne 0 ]; then
   718         die "failed to create output directory: \"$outdir\""
   719     fi
   720 fi
   721 verbose 3 "srcdir:   $srcdir"
   722 verbose 3 "outdir:   $outdir"
   723 verbose 3 "tmpdir:   $tmpdir"
   725 #   execute prolog script
   726 if [ ".@HAVE_PROLOG@" = .yes ]; then
   727     verbose 2 "execute prolog script"
   728     cat >$tmpdir/prolog.sh <<EOT
   729 #!/bin/sh
   730 #![OpenPKG]
   731 # %prolog
   732 EOT
   733     $opt_S sh $tmpdir/prolog.sh
   734     rm -f $tmpdir/prolog.sh
   735 fi
   737 if [ $opt_c -le 1 -a -x "$prefix/bin/openpkg" ]; then
   738     #   optionally fresh-up OpenPKG instance
   739     pkgs=`$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`
   740     if [ ".$pkgs" != . ]; then
   741         verbose 2 "uninstall already installed OpenPKG packages"
   742         for pkg in $pkgs; do
   743             verbose 3 "REMOVE: $pkg @ $prefix"
   744         done
   745         $opt_S $prefix/bin/openpkg rpm -e $pkgs || \
   746             die "failed to uninstall already installed OpenPKG packages"
   747     fi
   748 fi
   749 if [ $opt_c -le 0 -a -x "$prefix/bin/openpkg" ]; then
   750     #   optionally destroy OpenPKG instance
   751     verbose 2 "destroy existing OpenPKG framework"
   752     $opt_S $prefix/bin/openpkg rpm -e openpkg || \
   753         die "failed to destroy existing OpenPKG framework"
   754 fi
   756 #   check whether an already existing OpenPKG instance can be reused
   757 if [ -x "$prefix/bin/openpkg" ]; then
   758     verbose 2 "checking compatibility of existing OpenPKG framework"
   759     for name in $params; do
   760         case "$name" in
   761             user|group ) continue ;;
   762         esac
   763         eval "value_required=\"\$CF_$name\""
   764         if [ ".$value_required" != . ]; then
   765             value_existing=`$prefix/bin/openpkg rpm --eval "%{l_${name}}"`
   766             if [ ".$value_existing" != ".$value_required" ]; then
   767                 die "conflict on parameter \"$name\": value required: \"$value_required\", value existing: \"$value_existing\""
   768             fi
   769         fi
   770     done
   771 fi
   773 #   install or upgrade all packages
   774 verbose 2 "install or upgrade all OpenPKG packages"
   775 DIFS="$IFS"
   776 OIFS="$IFS"; IFS="
   777 "
   778 for spec in $CFG_PACKAGES; do
   779     #   determine information
   780     pkg=`echo "$spec"    | sed -e 's;^\([^ ]*\).*$;\1;'`
   781     opts=`echo "$spec"   | sed -e 's;^[^ ]*;;' -e 's;^ *;;'`
   782     name=`echo "$pkg"    | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'`
   783     version=`echo "$pkg" | sed -e 's;^.*-\([^-][^-]*\)-[^-][^-]*$;\1;'`
   784     release=`echo "$pkg" | sed -e 's;^.*-[^-][^-]*-\([^-][^-]*\)$;\1;'`
   786     if [ ".$name" = .openpkg ]; then
   787         #
   788         #   OpenPKG Framework
   789         #
   790         if [   ! -f "$outdir/$pkg.$platform-$tag.sh" \
   791             -o ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   792             #   build (bootstrap & regular)
   793             verbose 3 "BOOTSTRAP-BUILD: $srcdir/$pkg.src.sh"
   794             verbose 4 "options: $CFG_FRAMEWORK"
   795             if [ ! -f "$srcdir/$pkg.src.sh" ]; then
   796                 die "source shell package not existing: $srcdir/$pkg.src.sh"
   797             fi
   798             (   TMPDIR="$tmpdir"
   799                 srcdir="`cd $srcdir && pwd`"
   800                 cd "$outdir" || exit $?
   801                 cmd="sh \"$srcdir/$pkg.src.sh\" $CFG_FRAMEWORK"
   802                 if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
   803                 eval "$cmd" || \
   804                     die "failed to build package \"$srcdir/$pkg.src.sh\""
   805                 rm -f $pkg.src.rpm
   806             ) || exit $?
   807         fi
   808         if [ ! -x "$prefix/bin/openpkg" ]; then
   809             #   install (bootstrap)
   810             if [ ! -f "$outdir/$pkg.$platform-$tag.sh" ]; then
   811                 die "binary shell package not existing: $outdir/$pkg.$platform-$tag.sh"
   812             fi
   813             verbose 3 "BOOTSTRAP-INSTALL: $outdir/$pkg.$platform-$tag.sh"
   814             cmd="$opt_S sh \"$outdir/$pkg.$platform-$tag.sh\""
   815             if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
   816             eval "$cmd" || \
   817                 die "failed to install package \"$outdir/$pkg.$platform-$tag.sh\""
   818         else
   819             check=`$prefix/bin/openpkg rpm -q openpkg 2>/dev/null`
   820             if [ ".$check" != ".$pkg" ]; then
   821                 #   upgrade (regular)
   822                 if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   823                     die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
   824                 fi
   825                 verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm"
   826                 rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
   827                 $opt_S $prefix/bin/openpkg rpm $rpm_opt \
   828                     $outdir/$pkg.$platform-$tag.rpm || \
   829                     die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm"
   830             else
   831                 #   keep as-is
   832                 verbose 3 "KEEP AS-IS: $pkg @ $prefix"
   833             fi
   834         fi
   835     else
   836         #
   837         #   OpenPKG Packages
   838         #
   839         if [ ! -x "$prefix/bin/openpkg" ]; then
   840             #   usually will not happen because of correctly
   841             #   generated topologically correct package list
   842             die "command \"$prefix/bin/openpkg\" has to exit for building a regular OpenPKG package" 1>&2
   843         fi
   844         if [ ! -f $outdir/$pkg.$platform-$tag.rpm ]; then
   845             #    build (regular)
   846             if [ ! -f "$srcdir/$pkg.src.rpm" ]; then
   847                 die "source RPM package not existing: $srcdir/$pkg.src.rpm"
   848             fi
   849             verbose 3 "BUILD: $srcdir/$pkg.src.rpm"
   850             if [ ".$opts" != . ]; then
   851                 verbose 4 "options: $opts"
   852             fi
   853             rm -rf "$tmpdir/$pkg" >/dev/null 2>&1 || true
   854             sh $shtool mkdir -p -m 755 "$tmpdir/$pkg" >/dev/null 2>&1
   855             cmd="$prefix/bin/openpkg --keep-privileges"
   856             cmd="$cmd rpm --rebuild"
   857             cmd="$cmd --define \"_specdir   $tmpdir/$pkg\""
   858             cmd="$cmd --define \"_sourcedir $tmpdir/$pkg\""
   859             cmd="$cmd --define \"_builddir  $tmpdir/$pkg\""
   860             cmd="$cmd --define \"_tmppath   $tmpdir/$pkg\""
   861             cmd="$cmd --define \"_srcrpmdir $tmpdir/$pkg\""
   862             cmd="$cmd --define \"_rpmdir    $outdir\""
   863             OIFS2="$IFS"; IFS="$DIFS"
   864             for opt in $opts; do
   865                 opt_name=`echo "$opt" | sed -e 's;^\([^=]*\)=.*$;\1;'`
   866                 opt_value=`echo "$opt" | sed -e 's;^[^=]*=\(.*\)$;\1;'`
   867                 cmd="$cmd --define \"$opt_name $opt_value\""
   868             done
   869             IFS="$OIFS2"
   870             cmd="$cmd $srcdir/$pkg.src.rpm"
   871             if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
   872             eval "$cmd" || \
   873                 die "failed to build package \"$srcdir/$pkg.src.rpm\""
   874         fi
   875         check=`$prefix/bin/openpkg rpm -q "$name" 2>/dev/null`
   876         if [ ".$check" = ".package $name is not installed" ]; then
   877             #   install (regular)
   878             if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   879                 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
   880             fi
   881             verbose 3 "INSTALL: $outdir/$pkg.$platform-$tag.rpm"
   882             rpm_opt="-i"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
   883             $opt_S $prefix/bin/openpkg rpm $rpm_opt \
   884                 $outdir/$pkg.$platform-$tag.rpm || \
   885                 die "failed to install package: $outdir/$pkg.$platform-$tag.rpm"
   886         elif [ ".$check" != ".$pkg" ]; then
   887             #   upgrade (regular)
   888             if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
   889                 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
   890             fi
   891             verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm"
   892             rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
   893             $opt_S $prefix/bin/openpkg rpm $rpm_opt \
   894                 $outdir/$pkg.$platform-$tag.rpm || \
   895                 die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm"
   896         else
   897             #   keep as-is
   898             verbose 3 "KEEP AS-IS: $pkg @ $prefix"
   899         fi
   900     fi
   901 done
   902 IFS="$OIFS"
   904 #   optionally remove residue packages from binary RPM package directory
   905 if [ $opt_c -lt 3 ]; then
   906     verbose 2 "cleanup target directory from residue packages"
   907     for pkg in $outdir/*.sh $outdir/*.rpm; do
   908         if [ ! -f "$pkg" ]; then
   909             continue
   910         fi
   911         pkg_base=`echo "$pkg" | sed -e 's;^.*/\([^/][^/]*-[0-9][^/-]*-[0-9][0-9.]*\)\.[^/][^/]*$;\1;'`
   912         erase=yes
   913         for spec in $CFG_PACKAGES; do
   914             spec_base=`echo "$spec" | sed -e 's;^\(.*-[^-][^-]*-[^-][^-]*\).*$;\1;'`
   915             if [ ".$pkg_base" = ".$spec_base" ]; then
   916                 erase=no
   917                 break
   918             fi
   919         done
   920         if [ ".$erase" = .yes ]; then
   921             verbose 3 "REMOVE: $pkg"
   922             rm -f "$pkg"
   923         fi
   924     done
   925 fi
   927 #   optionally remove residue packages from OpenPKG instance
   928 if [ $opt_c -lt 3 ]; then
   929     verbose 2 "cleanup OpenPKG instance from residue packages"
   930     for pkg1 in `$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`; do
   931         name1=`echo "$pkg1" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'`
   932         erase=yes
   933         for spec in $CFG_PACKAGES; do
   934             name2=`echo "$spec" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*.*$;\1;'`
   935             if [ ".$name1" = ".$name2" ]; then
   936                 erase=no
   937                 break
   938             fi
   939         done
   940         if [ ".$erase" = .yes ]; then
   941             verbose 3 "REMOVE: pkg1 @ $prefix"
   942             $opt_S $prefix/bin/openpkg rpm -e "$pkg1" || \
   943                 die "failed to erase residue package \"$pkg1\""
   944         fi
   945     done
   946 fi
   948 #   execute epilog script
   949 if [ ".@HAVE_EPILOG@" = .yes ]; then
   950     verbose 2 "execute epilog script"
   951     cat >$tmpdir/epilog.sh <<EOT
   952 #!/bin/sh
   953 #![OpenPKG]
   954 # %epilog
   955 EOT
   956     $opt_S sh $tmpdir/epilog.sh
   957     rm -f $tmpdir/epilog.sh
   958 fi
   960 #   cleanup
   961 rm -f  $shtool >/dev/null 3>&1 || true
   962 rm -rf $tmpdir >/dev/null 2>&1 || true
   964 exit 0
   966 ## SHTOOL ###################################################################

mercurial