michael@428: ## michael@428: ## OpenPKG Software Stack Generation michael@428: ## Copyright (c) 2010-2012 OpenPKG GmbH michael@428: ## michael@428: ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208. michael@428: ## All rights reserved. Licenses which grant limited permission to use, michael@428: ## copy, modify and distribute this software are available from the michael@428: ## OpenPKG GmbH. michael@428: ## michael@428: ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED michael@428: ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF michael@428: ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. michael@428: ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR michael@428: ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@428: ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@428: ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF michael@428: ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND michael@428: ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, michael@428: ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT michael@428: ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF michael@428: ## SUCH DAMAGE. michael@428: ## michael@428: michael@428: # configuration michael@428: openpkg="${OPENPKG_PREFIX}/bin/openpkg" michael@428: curl="${OPENPKG_PREFIX}/bin/openpkg curl" michael@428: shtool="${OPENPKG_PREFIX}/lib/openpkg/shtool" michael@428: michael@428: ## michael@428: ## COMMAND LINE PARSING michael@428: ## michael@428: michael@428: str_usage="[-h|--help] [-v|--verbose ] [-o|--output ] [-D|--define = ...] [-u|--unversioned] [-q|--query] .stk" michael@428: arg_spec="1=" michael@428: opt_spec="h.v:o:D+u.q." michael@428: opt_alias="h:help,v:verbose,o:output,D:define,u:unversioned,q:query" michael@428: opt_h=no michael@428: opt_v=4 michael@428: opt_o="." michael@428: opt_D="" michael@428: opt_u=no michael@428: opt_q=no michael@428: michael@428: # parse argument specification string michael@428: eval `echo $arg_spec |\ michael@428: sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` michael@428: michael@428: # parse option specification string michael@428: eval `echo $opt_spec |\ michael@428: sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` michael@428: michael@428: # parse option alias string michael@428: eval `echo $opt_alias |\ michael@428: sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'` michael@428: michael@428: # interate over argument line michael@428: opt_PREV='' michael@428: while [ $# -gt 0 ]; do michael@428: # special option stops processing michael@428: if [ ".$1" = ".--" ]; then michael@428: shift michael@428: break michael@428: fi michael@428: michael@428: # determine option and argument michael@428: opt_ARG_OK=no michael@428: if [ ".$opt_PREV" != . ]; then michael@428: # merge previous seen option with argument michael@428: opt_OPT="$opt_PREV" michael@428: opt_ARG="$1" michael@428: opt_ARG_OK=yes michael@428: opt_PREV='' michael@428: else michael@428: # split argument into option and argument michael@428: case "$1" in michael@428: --[a-zA-Z0-9]*=*) michael@428: eval `echo "x$1" |\ michael@428: sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'` michael@428: opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` michael@428: eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" michael@428: ;; michael@428: --[a-zA-Z0-9]*) michael@428: opt_OPT=`echo "x$1" | cut -c4-` michael@428: opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` michael@428: eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" michael@428: opt_ARG='' michael@428: ;; michael@428: -[a-zA-Z0-9]*) michael@428: eval `echo "x$1" |\ michael@428: sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ michael@428: -e 's/";\(.*\)$/"; opt_ARG="\1"/'` michael@428: ;; michael@428: -[a-zA-Z0-9]) michael@428: opt_OPT=`echo "x$1" | cut -c3-` michael@428: opt_ARG='' michael@428: ;; michael@428: *) michael@428: break michael@428: ;; michael@428: esac michael@428: fi michael@428: michael@428: # eat up option michael@428: shift michael@428: michael@428: # determine whether option needs an argument michael@428: eval "opt_MODE=\$opt_MODE_${opt_OPT}" michael@428: if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then michael@428: if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then michael@428: opt_PREV="$opt_OPT" michael@428: continue michael@428: fi michael@428: fi michael@428: michael@428: # process option michael@428: case $opt_MODE in michael@428: '.' ) michael@428: # boolean option michael@428: eval "opt_${opt_OPT}=yes" michael@428: ;; michael@428: ':' ) michael@428: # option with argument (multiple occurances override) michael@428: eval "opt_${opt_OPT}=\"\$opt_ARG\"" michael@428: ;; michael@428: '+' ) michael@428: # option with argument (multiple occurances append) michael@428: eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" michael@428: ;; michael@428: * ) michael@428: echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2 michael@428: exit 1 michael@428: ;; michael@428: esac michael@428: done michael@428: if [ ".$opt_PREV" != . ]; then michael@428: echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2 michael@428: exit 1 michael@428: fi michael@428: michael@428: # process help option michael@428: if [ ".$opt_h" = .yes ]; then michael@428: echo "Usage: $0 $str_usage" michael@428: exit 0 michael@428: fi michael@428: michael@428: # complain about incorrect number of arguments michael@428: case $arg_MODE in michael@428: '=' ) michael@428: if [ $# -ne $arg_NUMS ]; then michael@428: echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 michael@428: exit 1 michael@428: fi michael@428: ;; michael@428: '+' ) michael@428: if [ $# -lt $arg_NUMS ]; then michael@428: echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 michael@428: exit 1 michael@428: fi michael@428: ;; michael@428: esac michael@428: michael@428: ## michael@428: ## HELPER FUNCTIONS michael@428: ## michael@428: michael@428: # helper function for graceful termination michael@428: die () { michael@428: echo "$0: ERROR: $*" michael@428: exit 1 michael@428: } michael@428: michael@428: # helper function for verbose messages michael@428: verbose () { michael@428: lvl="$1" michael@428: msg="$2" michael@428: if [ $opt_v -ge $lvl ]; then michael@428: case "$lvl" in michael@428: 1 ) str_prefix="**" ;; michael@428: 2 ) str_prefix="++" ;; michael@428: 3 ) str_prefix="--" ;; michael@428: 4 ) str_prefix=".." ;; michael@428: esac michael@428: echo "${str_prefix} ${msg}" michael@428: fi michael@428: } michael@428: michael@428: # expand macros michael@428: macro_expand () { michael@428: stk="$1" michael@428: michael@428: # load all options and their default values michael@428: options="" michael@428: for option in `sed <$stk \ michael@428: -e "1,/^%options/d" -e '/^%/,$d' \ michael@428: -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' \ michael@428: -e 's; *[^ ]*$;;'`; do michael@428: options="$options $option" michael@428: done michael@428: eval `sed <$stk \ michael@428: -e "1,/^%options/d" -e '/^%/,$d' \ michael@428: -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \ michael@428: -e 's:^\([^ ]*\) *\([^ ]*\)$:option_\1="\2";:'` michael@428: michael@428: # override options with defined values michael@428: for define in $opt_D; do michael@428: name=`echo "$define" | sed -e 's;=.*$;;'` michael@428: value=`echo "$define" | sed -e 's;^.*=;;'` michael@428: eval "exists=\"\${option_${name}}\"" michael@428: if [ ".$exists" = . ]; then michael@428: die "definition of not-existing option \"$name\"" michael@428: fi michael@428: eval "option_${name}=\"${value}\"" michael@428: done michael@428: michael@428: # expand macros michael@428: cmd="sed" michael@428: for name in $options; do michael@428: eval "value=\"\${option_${name}}\"" michael@428: cmd="$cmd -e 's;%{[?]$name:\\([^}]*\\)};\1;g'" michael@428: cmd="$cmd -e 's;%{![?]$name:\\([^}]*\\)};;g'" michael@428: cmd="$cmd -e 's;%{$name};$value;g'" michael@428: done michael@428: cmd="$cmd -e 's;%{[?][^:}]*:[^}]*};;g'" michael@428: cmd="$cmd -e 's;%{![?][^:}]*:\([^}]*\)};\1;g'" michael@428: eval "$cmd" michael@428: } michael@428: michael@428: # extract macro-expanded header michael@428: header () { michael@428: stk="$1" michael@428: hdr="$2" michael@428: exists=`egrep "^${hdr}" $stk` michael@428: if [ ".$exists" != . ]; then michael@428: egrep "^${hdr}:" $stk | \ michael@428: sed -e 's;^[^:]*: *;;' -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \ michael@428: macro_expand "$stk" michael@428: fi michael@428: } michael@428: michael@428: # extract macro-expanded section michael@428: section () { michael@428: stk="$1" michael@428: sec="$2" michael@428: exists=`egrep "^%${sec}" $stk` michael@428: if [ ".$exists" != . ]; then michael@428: sed <$stk \ michael@428: -e "1,/^%${sec}/d" -e '/^%/,$d' \ michael@428: -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \ michael@428: macro_expand "$stk" michael@428: fi michael@428: } michael@428: michael@428: ## michael@428: ## MAIN michael@428: ## michael@428: michael@428: # determine stack file michael@428: stk="$1" michael@428: shift michael@428: michael@428: # support stand-alone query operation michael@428: if [ ".$opt_q" = .yes ]; then michael@428: name=`header "$stk" "Name"` michael@428: summary=`header "$stk" "Summary"` michael@428: packager=`header "$stk" "Packager"` michael@428: version=`header "$stk" "Version"` michael@428: release=`header "$stk" "Release"` michael@428: echo "name=\"$name\";" michael@428: echo "summary=\"$summary\";" michael@428: echo "packager=\"$packager\";" michael@428: echo "version=\"$version\";" michael@428: echo "release=\"$release\";" michael@428: sed <$stk \ michael@428: -e "1,/^%options/d" -e '/^%/,$d' \ michael@428: -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \ michael@428: -e 's:^\([^ ]*\) *\([^ ]*\)$:\1="\2";:' michael@428: exit 0 michael@428: fi michael@428: michael@428: # determine temporary directory michael@428: tmpdir="${TMPDIR-/tmp}" michael@428: michael@428: # provide verbose header michael@428: verbose 1 "OpenPKG Software Stack Generation" michael@428: michael@428: # determine information michael@428: verbose 2 "determining software stack information" michael@428: name=`header "$stk" "Name"` michael@428: summary=`header "$stk" "Summary"` michael@428: packager=`header "$stk" "Packager"` michael@428: version=`header "$stk" "Version"` michael@428: release=`header "$stk" "Release"` michael@428: verbose 3 "Name: $name" michael@428: verbose 3 "Summary: $summary" michael@428: verbose 3 "Packager: $packager" michael@428: verbose 3 "Version: $version" michael@428: verbose 3 "Release: $release" michael@428: if [ ".$opt_u" = .yes ]; then michael@428: basename="$name" michael@428: else michael@428: basename="$name-$version-$release" michael@428: fi michael@428: michael@428: # determine URLs michael@428: verbose 2 "determining software stack packages" michael@428: repo=`section "$stk" "repository"` michael@428: verbose 3 "repository: [URL] $repo" michael@428: $openpkg build -r "$repo" -Z -u -K -B \ michael@428: `section "$stk" "packages"` | \ michael@428: egrep "openpkg curl" | \ michael@428: sed -e 's;^.* \([^ ]*\) || exit.*$;\1;' \ michael@428: -e '/\/openpkg-[0-9].*\.src\.rpm/{h;s/\.src\.rpm$/.src.sh/;p;x}' \ michael@428: >$tmpdir/url.txt michael@428: michael@428: # provide header michael@428: verbose 2 "assembling software stack sources" michael@428: michael@428: # download source packages michael@428: if [ ! -d "$opt_o/$basename.src.d" ]; then michael@428: verbose 3 "creating: [DIR] $opt_o/$basename.src.d" michael@428: $shtool mkdir -p -m 755 "$opt_o/$basename.src.d" michael@428: else michael@428: verbose 3 "reusing: [DIR] $opt_o/$basename.src.d" michael@428: fi michael@428: for url in `cat $tmpdir/url.txt`; do michael@428: url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'` michael@428: if [ ! -f "$opt_o/$basename.src.d/$url_file" ]; then michael@428: verbose 3 "downloading: [FILE] $opt_o/$basename.src.d/$url_file" michael@428: if [ $opt_v -ge 4 ]; then michael@428: $curl '-#' -L -k -o $opt_o/$basename.src.d/$url_file $url michael@428: else michael@428: $curl -s -L -k -o $opt_o/$basename.src.d/$url_file $url michael@428: fi michael@428: else michael@428: verbose 3 "reusing: [FILE] $opt_o/$basename.src.d/$url_file" michael@428: fi michael@428: done michael@428: for path in $opt_o/$basename.src.d/*.src.sh $opt_o/$basename.src.d/*.src.rpm; do michael@428: if [ ! -f "$path" ]; then michael@428: continue michael@428: fi michael@428: path_file=`echo $path | sed -e 's;^.*/\([^/]*\)$;\1;'` michael@428: found=no michael@428: for url in `cat $tmpdir/url.txt`; do michael@428: url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'` michael@428: if [ ".$url_file" = ".$path_file" ]; then michael@428: found=yes michael@428: break michael@428: fi michael@428: done michael@428: if [ ".$found" = .no ]; then michael@428: verbose 3 "removing: [FILE] $path" michael@428: rm -f "$path" michael@428: fi michael@428: done michael@428: rm -f $tmpdir/url.txt michael@428: michael@428: # generate XML/RDF index for SRPM packages michael@428: verbose 3 "generating: [FILE] $opt_o/$basename.src.d/00INDEX.rdf" michael@428: $openpkg index -r "OpenPKG/SRPM" \ michael@428: -o $opt_o/$basename.src.d/00INDEX.rdf \ michael@428: -i $opt_o/$basename.src.d michael@428: michael@428: # generate deployment utility michael@428: verbose 3 "generating: [FILE] $opt_o/$basename.sh"; \ michael@428: section "$stk" "framework" >$tmpdir/framework.txt michael@428: section "$stk" "prolog" >$tmpdir/prolog.txt michael@428: section "$stk" "epilog" >$tmpdir/epilog.txt michael@428: HAVE_PROLOG=no; if [ ".`cat $tmpdir/prolog.txt`" != . ]; then HAVE_PROLOG=yes; fi michael@428: HAVE_EPILOG=no; if [ ".`cat $tmpdir/epilog.txt`" != . ]; then HAVE_EPILOG=yes; fi michael@428: $openpkg build -r "$repo" -Z -u -K \ michael@428: `section "$stk" "packages"` | \ michael@428: grep -v "^#" | \ michael@428: grep -v "^echo" | \ michael@428: grep -v "^rm" | \ michael@428: egrep -v "^(if|fi)" | \ michael@428: grep -v "openpkg curl" | \ michael@428: grep -v "openpkg rpm -Uvh" | \ michael@428: sed -e 's;.*openpkg rpm ;;' \ michael@428: -e 's; || exit.*;;' \ michael@428: -e 's;--rebuild ;;' \ michael@428: -e 's;/.*/\([^/]*\.src\.rpm\);\1;' \ michael@428: -e 's;^\(.*\) \([^/]*\.src\.rpm\);\2 \1;' \ michael@428: -e "s;--define '\\([^ ]*\\) \\([^ ]*\\)';\\1=\\2;g" \ michael@428: -e 's;\.src\.rpm;;' \ michael@428: >$tmpdir/packages.txt michael@428: sed <$0 \ michael@428: -e '1,/^____/d' \ michael@428: -e "/^CFG_FRAMEWORK=\"/r $tmpdir/framework.txt" \ michael@428: -e "/^CFG_PACKAGES=\"/r $tmpdir/packages.txt" \ michael@428: -e "s;@HAVE_PROLOG@;$HAVE_PROLOG;" \ michael@428: -e "/%prolog/r $tmpdir/prolog.txt" \ michael@428: -e "s;@HAVE_EPILOG@;$HAVE_EPILOG;" \ michael@428: -e "/%epilog/r $tmpdir/epilog.txt" \ michael@428: -e "/^## SHTOOL ##/r $shtool" \ michael@428: -e "s;^\\(CFG_NAME=\"\\).*\\(\"\\);\\1$name\\2;" \ michael@428: -e "s;^\\(CFG_SUMMARY=\"\\).*\\(\"\\);\\1$summary\\2;" \ michael@428: -e "s;^\\(CFG_PACKAGER=\"\\).*\\(\"\\);\\1$packager\\2;" \ michael@428: -e "s;^\\(CFG_VERSION=\"\\).*\\(\"\\);\\1$version\\2;" \ michael@428: -e "s;^\\(CFG_RELEASE=\"\\).*\\(\"\\);\\1$release\\2;" \ michael@428: -e "s;^\\(CFG_UNVERSIONED=\"\\).*\\(\"\\);\\1$opt_u\\2;" \ michael@428: >$opt_o/$basename.sh michael@428: michael@428: # cleanup michael@428: rm -f $tmpdir/framework.txt michael@428: rm -f $tmpdir/packages.txt michael@428: rm -f $tmpdir/prolog.txt michael@428: rm -f $tmpdir/epilog.txt michael@428: michael@428: # exit gracefully michael@428: exit 0 michael@428: michael@428: ## michael@428: ## DEPLOYMENT SCRIPT michael@428: ## michael@428: michael@428: ______________________________________________________________________________ michael@428: #!/bin/sh michael@428: #![OpenPKG] michael@428: ## michael@428: ## OpenPKG Software Stack Deployment michael@428: ## Copyright (c) 2010-2012 OpenPKG GmbH michael@428: ## michael@428: ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208. michael@428: ## All rights reserved. Licenses which grant limited permission to use, michael@428: ## copy, modify and distribute this software are available from the michael@428: ## OpenPKG GmbH. michael@428: ## michael@428: ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED michael@428: ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF michael@428: ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. michael@428: ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR michael@428: ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@428: ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@428: ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF michael@428: ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND michael@428: ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, michael@428: ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT michael@428: ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF michael@428: ## SUCH DAMAGE. michael@428: ## michael@428: michael@428: ## michael@428: ## COMMAND LINE PARSING michael@428: ## michael@428: michael@428: str_usage="[-h|--help] [-v|--verbose ] [-c|--cleanup ] [-D|--define = ...] [-s|--srcdir ] [-o|--outdir ] [-t|--tmpdir ] [-S ]" michael@428: arg_spec="0=" michael@428: opt_spec="h.v:c:D+s:o:t:S:" michael@428: opt_alias="h:help,v:verbose,c:cleanup,D:define,s:srcdir,o:outdir,t:tmpdir,S:sudo" michael@428: opt_h=no michael@428: opt_v=3 michael@428: opt_c=1 michael@428: opt_D="" michael@428: opt_s="" michael@428: opt_o="" michael@428: opt_t="${TMPDIR-/tmp}" michael@428: opt_S="" michael@428: michael@428: # parse argument specification string michael@428: eval `echo $arg_spec |\ michael@428: sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` michael@428: michael@428: # parse option specification string michael@428: eval `echo $opt_spec |\ michael@428: sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` michael@428: michael@428: # parse option alias string michael@428: eval `echo $opt_alias |\ michael@428: sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'` michael@428: michael@428: # interate over argument line michael@428: opt_PREV='' michael@428: while [ $# -gt 0 ]; do michael@428: # special option stops processing michael@428: if [ ".$1" = ".--" ]; then michael@428: shift michael@428: break michael@428: fi michael@428: michael@428: # determine option and argument michael@428: opt_ARG_OK=no michael@428: if [ ".$opt_PREV" != . ]; then michael@428: # merge previous seen option with argument michael@428: opt_OPT="$opt_PREV" michael@428: opt_ARG="$1" michael@428: opt_ARG_OK=yes michael@428: opt_PREV='' michael@428: else michael@428: # split argument into option and argument michael@428: case "$1" in michael@428: --[a-zA-Z0-9]*=*) michael@428: eval `echo "x$1" |\ michael@428: sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'` michael@428: opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` michael@428: eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" michael@428: ;; michael@428: --[a-zA-Z0-9]*) michael@428: opt_OPT=`echo "x$1" | cut -c4-` michael@428: opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'` michael@428: eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}" michael@428: opt_ARG='' michael@428: ;; michael@428: -[a-zA-Z0-9]*) michael@428: eval `echo "x$1" |\ michael@428: sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ michael@428: -e 's/";\(.*\)$/"; opt_ARG="\1"/'` michael@428: ;; michael@428: -[a-zA-Z0-9]) michael@428: opt_OPT=`echo "x$1" | cut -c3-` michael@428: opt_ARG='' michael@428: ;; michael@428: *) michael@428: break michael@428: ;; michael@428: esac michael@428: fi michael@428: michael@428: # eat up option michael@428: shift michael@428: michael@428: # determine whether option needs an argument michael@428: eval "opt_MODE=\$opt_MODE_${opt_OPT}" michael@428: if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then michael@428: if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then michael@428: opt_PREV="$opt_OPT" michael@428: continue michael@428: fi michael@428: fi michael@428: michael@428: # process option michael@428: case $opt_MODE in michael@428: '.' ) michael@428: # boolean option michael@428: eval "opt_${opt_OPT}=yes" michael@428: ;; michael@428: ':' ) michael@428: # option with argument (multiple occurances override) michael@428: eval "opt_${opt_OPT}=\"\$opt_ARG\"" michael@428: ;; michael@428: '+' ) michael@428: # option with argument (multiple occurances append) michael@428: eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" michael@428: ;; michael@428: * ) michael@428: echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2 michael@428: exit 1 michael@428: ;; michael@428: esac michael@428: done michael@428: if [ ".$opt_PREV" != . ]; then michael@428: echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2 michael@428: exit 1 michael@428: fi michael@428: michael@428: # process help option michael@428: if [ ".$opt_h" = .yes ]; then michael@428: echo "Usage: $0 $str_usage" michael@428: exit 0 michael@428: fi michael@428: michael@428: # complain about incorrect number of arguments michael@428: case $arg_MODE in michael@428: '=' ) michael@428: if [ $# -ne $arg_NUMS ]; then michael@428: echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 michael@428: exit 1 michael@428: fi michael@428: ;; michael@428: '+' ) michael@428: if [ $# -lt $arg_NUMS ]; then michael@428: echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 michael@428: exit 1 michael@428: fi michael@428: ;; michael@428: esac michael@428: michael@428: # helper function for verbose messages michael@428: verbose () { michael@428: lvl="$1" michael@428: msg="$2" michael@428: if [ $opt_v -ge $lvl ]; then michael@428: case "$lvl" in michael@428: 1 ) str_prefix="**" ;; michael@428: 2 ) str_prefix="++" ;; michael@428: 3 ) str_prefix="--" ;; michael@428: 4 ) str_prefix=".." ;; michael@428: esac michael@428: echo "${str_prefix} ${msg}" michael@428: fi michael@428: } michael@428: michael@428: # helper function for graceful termination michael@428: die () { michael@428: echo "$0: ERROR: $*" michael@428: exit 1 michael@428: } michael@428: michael@428: ## michael@428: ## MAIN michael@428: ## michael@428: michael@428: # the stack information michael@428: CFG_NAME="" michael@428: CFG_SUMMARY="" michael@428: CFG_PACKAGER="" michael@428: CFG_VERSION="" michael@428: CFG_RELEASE="" michael@428: michael@428: # the required OpenPKG framework parameters michael@428: CFG_FRAMEWORK=" michael@428: " michael@428: michael@428: # the required OpenPKG packages michael@428: # (in topological order and with build options resolved) michael@428: CFG_PACKAGES=" michael@428: " michael@428: michael@428: # whether unversioned output directory should be used michael@428: CFG_UNVERSIONED="" michael@428: michael@428: # display information michael@428: verbose 1 "OpenPKG Software Stack Deployment" michael@428: verbose 2 "determining information" michael@428: michael@428: # parse OpenPKG framework parameters michael@428: params=" michael@428: prefix michael@428: user group michael@428: susr musr rusr nusr michael@428: sgrp mgrp rgrp ngrp michael@428: suid muid ruid nuid michael@428: sgid mgid rgid ngid michael@428: tag michael@428: " michael@428: for param in $params; do michael@428: eval "CF_$param=''" michael@428: done michael@428: for opt in $CFG_FRAMEWORK; do michael@428: case "$opt" in michael@428: --[a-zA-Z0-9-]*=* ) michael@428: name=`echo "$opt" | sed -e 's;^--\([^=]*\)=.*$;\1;'` michael@428: value=`echo "$opt" | sed -e 's;^--[^=]*=\(.*\)$;\1;'` michael@428: eval "CF_$name='$value'" michael@428: ;; michael@428: esac michael@428: done michael@428: for define in $opt_D; do michael@428: name=`echo "$define" | sed -e 's;=.*$;;'` michael@428: value=`echo "$define" | sed -e 's;^.*=;;'` michael@428: eval "CF_$name='$value'" michael@428: done michael@428: CFG_FRAMEWORK='' michael@428: for name in $params; do michael@428: eval "value=\"\$CF_$name\"" michael@428: if [ ".$value" != . ]; then michael@428: if [ ".$CFG_FRAMEWORK" = . ]; then michael@428: CFG_FRAMEWORK="--$name=$value" michael@428: else michael@428: CFG_FRAMEWORK="$CFG_FRAMEWORK --$name=$value" michael@428: fi michael@428: fi michael@428: done michael@428: if [ ".$CF_musr" = . ]; then CF_musr="$CF_user"; fi michael@428: if [ ".$CF_mgrp" = . ]; then CF_mgrp="$CF_group"; fi michael@428: if [ ".$CF_rusr" = . ]; then CF_rusr="$CF_user-r"; fi michael@428: if [ ".$CF_rgrp" = . ]; then CF_rgrp="$CF_group-r"; fi michael@428: if [ ".$CF_nusr" = . ]; then CF_nusr="$CF_user-n"; fi michael@428: if [ ".$CF_ngrp" = . ]; then CF_ngrp="$CF_group-n"; fi michael@428: verbose 3 "name: $CFG_NAME" michael@428: verbose 3 "summary: $CFG_SUMMARY" michael@428: verbose 3 "packager: $CFG_PACKAGER" michael@428: verbose 3 "version: $CFG_VERSION" michael@428: verbose 3 "release: $CFG_RELEASE" michael@428: michael@428: # determine target parameters michael@428: if [ ".$CF_prefix" = . ]; then michael@428: die "OpenPKG Framework parameter \"prefix\" required" michael@428: fi michael@428: prefix="$CF_prefix" michael@428: if [ ".$CF_tag" = . ]; then michael@428: die "OpenPKG Framework parameter \"tag\" required" michael@428: fi michael@428: tag="$CF_tag" michael@428: shtool="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.shtool.sh" michael@428: sed <$0 -e '1,/^## SHTOOL ##.*/d' >$shtool michael@428: platform=`sh $shtool platform -n -L -S "" -C "+" -F '%-%'` michael@428: verbose 3 "platform: $platform" michael@428: verbose 3 "tag: $tag" michael@428: verbose 3 "prefix: $prefix" michael@428: michael@428: # determine operation directories michael@428: srcdir="$opt_s" michael@428: if [ ".$srcdir" = . ]; then michael@428: srcdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.src.d" michael@428: fi michael@428: tmpdir="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.d" michael@428: if [ ! -d "$tmpdir" ]; then michael@428: ( umask 077 michael@428: rm -rf "$tmpdir" >/dev/null 2>&1 || true michael@428: sh $shtool mkdir -p -m 700 "$tmpdir" >/dev/null 2>&1 michael@428: if [ $? -ne 0 ]; then michael@428: die "failed to create temporary directory: \"$tmpdir\"" michael@428: fi michael@428: ) || exit $? michael@428: fi michael@428: outdir="$opt_o" michael@428: if [ ".$outdir" = . ]; then michael@428: if [ ".$CFG_UNVERSIONED" = .yes ]; then michael@428: outdir="$CFG_NAME.$platform-$tag.d" michael@428: else michael@428: outdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.$platform-$tag.d" michael@428: fi michael@428: fi michael@428: if [ ! -d "$outdir" ]; then michael@428: sh $shtool mkdir -p -m 755 "$outdir" >/dev/null 2>&1 michael@428: if [ $? -ne 0 ]; then michael@428: die "failed to create output directory: \"$outdir\"" michael@428: fi michael@428: fi michael@428: verbose 3 "srcdir: $srcdir" michael@428: verbose 3 "outdir: $outdir" michael@428: verbose 3 "tmpdir: $tmpdir" michael@428: michael@428: # execute prolog script michael@428: if [ ".@HAVE_PROLOG@" = .yes ]; then michael@428: verbose 2 "execute prolog script" michael@428: cat >$tmpdir/prolog.sh </dev/null` michael@428: if [ ".$check" != ".$pkg" ]; then michael@428: # upgrade (regular) michael@428: if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then michael@428: die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm" michael@428: fi michael@428: verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm" michael@428: rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi michael@428: $opt_S $prefix/bin/openpkg rpm $rpm_opt \ michael@428: $outdir/$pkg.$platform-$tag.rpm || \ michael@428: die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm" michael@428: else michael@428: # keep as-is michael@428: verbose 3 "KEEP AS-IS: $pkg @ $prefix" michael@428: fi michael@428: fi michael@428: else michael@428: # michael@428: # OpenPKG Packages michael@428: # michael@428: if [ ! -x "$prefix/bin/openpkg" ]; then michael@428: # usually will not happen because of correctly michael@428: # generated topologically correct package list michael@428: die "command \"$prefix/bin/openpkg\" has to exit for building a regular OpenPKG package" 1>&2 michael@428: fi michael@428: if [ ! -f $outdir/$pkg.$platform-$tag.rpm ]; then michael@428: # build (regular) michael@428: if [ ! -f "$srcdir/$pkg.src.rpm" ]; then michael@428: die "source RPM package not existing: $srcdir/$pkg.src.rpm" michael@428: fi michael@428: verbose 3 "BUILD: $srcdir/$pkg.src.rpm" michael@428: if [ ".$opts" != . ]; then michael@428: verbose 4 "options: $opts" michael@428: fi michael@428: rm -rf "$tmpdir/$pkg" >/dev/null 2>&1 || true michael@428: sh $shtool mkdir -p -m 755 "$tmpdir/$pkg" >/dev/null 2>&1 michael@428: cmd="$prefix/bin/openpkg --keep-privileges" michael@428: cmd="$cmd rpm --rebuild" michael@428: cmd="$cmd --define \"_specdir $tmpdir/$pkg\"" michael@428: cmd="$cmd --define \"_sourcedir $tmpdir/$pkg\"" michael@428: cmd="$cmd --define \"_builddir $tmpdir/$pkg\"" michael@428: cmd="$cmd --define \"_tmppath $tmpdir/$pkg\"" michael@428: cmd="$cmd --define \"_srcrpmdir $tmpdir/$pkg\"" michael@428: cmd="$cmd --define \"_rpmdir $outdir\"" michael@428: OIFS2="$IFS"; IFS="$DIFS" michael@428: for opt in $opts; do michael@428: opt_name=`echo "$opt" | sed -e 's;^\([^=]*\)=.*$;\1;'` michael@428: opt_value=`echo "$opt" | sed -e 's;^[^=]*=\(.*\)$;\1;'` michael@428: cmd="$cmd --define \"$opt_name $opt_value\"" michael@428: done michael@428: IFS="$OIFS2" michael@428: cmd="$cmd $srcdir/$pkg.src.rpm" michael@428: if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi michael@428: eval "$cmd" || \ michael@428: die "failed to build package \"$srcdir/$pkg.src.rpm\"" michael@428: fi michael@428: check=`$prefix/bin/openpkg rpm -q "$name" 2>/dev/null` michael@428: if [ ".$check" = ".package $name is not installed" ]; then michael@428: # install (regular) michael@428: if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then michael@428: die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm" michael@428: fi michael@428: verbose 3 "INSTALL: $outdir/$pkg.$platform-$tag.rpm" michael@428: rpm_opt="-i"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi michael@428: $opt_S $prefix/bin/openpkg rpm $rpm_opt \ michael@428: $outdir/$pkg.$platform-$tag.rpm || \ michael@428: die "failed to install package: $outdir/$pkg.$platform-$tag.rpm" michael@428: elif [ ".$check" != ".$pkg" ]; then michael@428: # upgrade (regular) michael@428: if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then michael@428: die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm" michael@428: fi michael@428: verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm" michael@428: rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi michael@428: $opt_S $prefix/bin/openpkg rpm $rpm_opt \ michael@428: $outdir/$pkg.$platform-$tag.rpm || \ michael@428: die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm" michael@428: else michael@428: # keep as-is michael@428: verbose 3 "KEEP AS-IS: $pkg @ $prefix" michael@428: fi michael@428: fi michael@428: done michael@428: IFS="$OIFS" michael@428: michael@428: # optionally remove residue packages from binary RPM package directory michael@428: if [ $opt_c -lt 3 ]; then michael@428: verbose 2 "cleanup target directory from residue packages" michael@428: for pkg in $outdir/*.sh $outdir/*.rpm; do michael@428: if [ ! -f "$pkg" ]; then michael@428: continue michael@428: fi michael@428: pkg_base=`echo "$pkg" | sed -e 's;^.*/\([^/][^/]*-[0-9][^/-]*-[0-9][0-9.]*\)\.[^/][^/]*$;\1;'` michael@428: erase=yes michael@428: for spec in $CFG_PACKAGES; do michael@428: spec_base=`echo "$spec" | sed -e 's;^\(.*-[^-][^-]*-[^-][^-]*\).*$;\1;'` michael@428: if [ ".$pkg_base" = ".$spec_base" ]; then michael@428: erase=no michael@428: break michael@428: fi michael@428: done michael@428: if [ ".$erase" = .yes ]; then michael@428: verbose 3 "REMOVE: $pkg" michael@428: rm -f "$pkg" michael@428: fi michael@428: done michael@428: fi michael@428: michael@428: # optionally remove residue packages from OpenPKG instance michael@428: if [ $opt_c -lt 3 ]; then michael@428: verbose 2 "cleanup OpenPKG instance from residue packages" michael@428: for pkg1 in `$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`; do michael@428: name1=`echo "$pkg1" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'` michael@428: erase=yes michael@428: for spec in $CFG_PACKAGES; do michael@428: name2=`echo "$spec" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*.*$;\1;'` michael@428: if [ ".$name1" = ".$name2" ]; then michael@428: erase=no michael@428: break michael@428: fi michael@428: done michael@428: if [ ".$erase" = .yes ]; then michael@428: verbose 3 "REMOVE: pkg1 @ $prefix" michael@428: $opt_S $prefix/bin/openpkg rpm -e "$pkg1" || \ michael@428: die "failed to erase residue package \"$pkg1\"" michael@428: fi michael@428: done michael@428: fi michael@428: michael@428: # execute epilog script michael@428: if [ ".@HAVE_EPILOG@" = .yes ]; then michael@428: verbose 2 "execute epilog script" michael@428: cat >$tmpdir/epilog.sh </dev/null 3>&1 || true michael@428: rm -rf $tmpdir >/dev/null 2>&1 || true michael@428: michael@428: exit 0 michael@428: michael@428: ## SHTOOL ################################################################### michael@428: