#!/sbin/sh ########################################################################## # @(#) make_bundles $Revision: 10.11 $ # # (c)Copyright 1997 Hewlett-Packard Co., All Rights Reserved. # # make_bundles: # Create bundles in a depot that may not have them. For the purpose # such that make_config (which operates at the bundle level) can do # it's job. # export PATH=/usr/bin:/usr/sbin:/sbin unset LANG b_opt=false B_opt=false bun_name="" bun_title="" bun_category="" def_bun_rev="A.1.0" def_bun_arch="none" p_opt=false f_opt=false users_psf="" depot="" exit_val=0 sd_layout_opts="" usage="\ usage: make_bundles {-b|-B}[-n name [-t title][-c category][-r rev][-o psf] depot-path make_bundles [-b] [-p|-f] [-c category] [-o psf] depot-path -b => Package only products/filesets not currently in a bundle. -B => Package all products in the depot into one big bundle. -p => Create one bundle for every product in the depot. -f => Create one bundle for every fileset in the depot. -n name => Supply the name of bundle (defaults to depot basename). -t title => Supply the one-line title of the bundle. -c category => Supply the category for all bundles. -r revision => Use the given revision for the bundle created (default $def_bun_rev). -o psf => Only create a product specification file, don't modify depot. depot-path => Path to SD depot, must be on the local system. " set +o noclobber # ensure >file works set -u while getopts :bBn:t:c:o:r:pf opt do case "$opt" in b) b_opt=true;; B) B_opt=true;; n) bun_name="$OPTARG";; t) bun_title="$OPTARG";; c) bun_category="$OPTARG";; o) users_psf="$OPTARG";; r) def_bun_rev="$OPTARG";; p) p_opt=true;; f) f_opt=true;; "?") echo "Unrecognized option: \"-$OPTARG\"" >&2 echo "$usage" >&2 exit 1;; ":") echo "Argument missing to option: \"-$OPTARG\"" >&2 echo "$usage" >&2 exit 1;; esac done # Shift past recognized options ((OPTIND -= 1)) shift $OPTIND if [ $# -eq 0 ] ; then echo "A depot path is required." >&2 echo "$usage" >&2 exit 1 fi depot="$*" depot=${depot##*:} # strip off hostname if given if [ ! -d "$depot" ] ; then echo "Cannot access the depot: \"$depot\" - no such directory" exit 1 fi if swlist -l depot -s $depot 2>&1 | grep -q "No depot was found" then echo "Cannot access the depot: \"$depot\" using swlist." exit 1 fi if [ $b_opt = true ] ; then if [ $B_opt = true ] ; then echo "Cannot use both -b and -B" >&2 echo "$usage" >&2 exit 1 fi fi if [ $B_opt = true ] ; then if [ $p_opt = true -o $f_opt = true ] ; then echo "Cannot use both -B and -p/-f" >&2 echo "$usage" >&2 exit 1 fi fi if [ $p_opt = true ] ; then if [ $f_opt = true ] ; then echo "Cannot use both -p and -f" >&2 echo "$usage" >&2 exit 1 fi fi if [ $b_opt = false -a $B_opt = false -a $p_opt = false -a $f_opt = false ] then b_opt=true # default to ceate a bundle for each unbundled product. p_opt=true fi # # Determine if the -xlayout_version=?? swpackage option is needed in # order to preserve the current layout of the depot and not convert # it to a different version (FSDdt22606) # # SD tools that support the 1.0 layout_version support the 2.40 data # model... # if swpackage -V | fgrep -q "2.40" ; then # We know we have SD tools capable of handling 1.0 layout_version # depots (which came into use in HP-UX 11.00). Now use the fact # that only 1.0 layout depots have a create_time attribute. # Unfortunately we cannot just list the layotu_version attribute # because that always comes back as 1.0 when using 1.0 tools. ct=$(swlist -l depot -a create_time -s $depot | grep -v "^#" | \ awk '{print $2}') if [ -n "$ct" ] ; then sd_layout_opts="-xlayout_version=1.0" else sd_layout_opts="-xlayout_version=0.8" fi fi # Truncate the stdin to the given number of chars. trunc() { dd bs=1 count=$1 2>/dev/null } if [ "$bun_name" = "" ] ; then # Get a default bundle name - remove illegal characters bun_name=$(basename $depot | tr -cd "a-zA-Z0-9_" | trunc 16) fi if [ "$bun_title" = "" ] ; then bun_title="$(echo $depot | trunc 80)" fi ################################################################ # tmp files: # All are removed at script exit. # swtopkg=/var/tmp/fsl.$$ cur_buns=/var/tmp/cbn.$$ fstoign=/var/tmp/ign.$$ unbun=/var/tmp/unb.$$ psf=/var/tmp/psf.$$ prods=/var/tmp/prods.$$ prod_info=/var/tmp/pr_in.$$ do_cleanup() { rm -f $swtopkg $cur_buns $fstoign $psf $unbun $prods $prod_info exit $exit_val } trap do_cleanup EXIT ########################################################################## # Generate a list of filesets (full sw_spec) that are not contianed # in a bundle. # get_unbundled () { # Get the list of current bundles echo "Generating list of unbundled filesets..." >&2 swlist -l bundle -s $depot | awk '/^[^#]/ {print $1}' > $cur_buns if [ -s $cur_buns ] ; then # Get the list of filesets only in those bundles swlist -l fileset -f $cur_buns -s $depot -a software_spec | \ awk '/^[^#]/ {print $2}' | sort > $fstoign else # No bundles at all, make $fstoign empty > $fstoign fi # Now list all filesets and remove the ones in a bundle swlist -l fileset -s $depot -a software_spec \* | \ awk '/^[^#]/ {print $2}' | sort | comm -23 - $fstoign } ########################################################################## # Get the revision, architecture and title of the specified product # from $prod_info file. Write the three items to stdout. # get_prod_info() { while read pr s t ; do if [ "$pr" = "$1" ] ; then rev=${s##*r=} if [ "$rev" != "$s" ] ; then rev=${rev%%,*} else rev="$def_bun_rev" fi arch=${s##*a=} if [ "$arch" != "$s" ] ; then arch=${arch%%,*} else arch="$def_bun_arch" fi echo $rev $arch $t return fi done < $prod_info } ########################################################################## # Create multiple bundles, either one per product, or one per fileset # either of all items, or all unbundled items. # if [ $p_opt = true -o $f_opt = true ] ; then if [ $b_opt = true ] ; then get_unbundled > $unbun list_opts="-f $unbun" if [ ! -s $unbun ] ; then echo "All software in depot is already in a bundle." >&2 exit_val=2 exit 2 fi else list_opts="" # will list all fi echo "Generating swpackage PSF..." >&2 swlist -l fileset -s $depot -a software_spec -a title $list_opts | \ awk '/^[^#]/ {print $0}' > $swtopkg if [ ! -s $swtopkg ] ; then echo "Depot contains no software to be packaged." >&2 exit_val=1 exit 1 fi if [ $p_opt = true ] ; then # # Get product specific info (title) # awk -F. '{print $1}' < $swtopkg > $prods swlist -l product -s $depot -a software_spec -a title -f $prods | \ awk '/^[^#]/ {print $0}' > $prod_info fi cat > $psf << EOF1 ################################################################# # swpackage product specification file generated by make_bundles # on $(date). For depot: $depot # # To run swpackage to apply the bundle definitions to the # depot, use the command: # # swpackage -s ${users_psf:-$psf} $sd_layout_opts -xreinstall_files=true -d $depot # ################################################################# EOF1 last_prod="" while read rawtag spec title do cur_prod="${rawtag%%.*}" if [ $f_opt = true -o "$last_prod" != "$cur_prod" ] ; then if [ $p_opt = true ] ; then rawtag="$cur_prod" # use just bundle name, strip fileset title_prefix="($cur_prod)" get_prod_info $cur_prod | read bun_rev bun_arch title else title_prefix="(${rawtag##*.})" bun_rev=${spec##*r=} if [ "$bun_rev" != "$spec" ] ; then bun_rev=${bun_rev%%,*} else bun_rev="$def_bun_rev" fi bun_arch=${spec##*a=} if [ "$bun_arch" != "$spec" ] ; then bun_arch=${bun_arch%%,*} else bun_arch="$def_bun_arch" fi fi # Start a new bundle typeset -i instance=0 while : do # # Find a tag name that is unique, use an instance # number prefix to guarantee a unique one. Not # exactly pretty, but functional # if [ $instance -eq 0 ] ; then prefix="b_" else prefix="b${instance}_" fi tag=$(echo ${prefix}$rawtag | tr -cs "[a-z][A-Z][0-9][\012]" "[_*]" | trunc 16) if [ -f $psf ] && grep -q "^tag $tag\$" $psf then ((instance+=1)) else break; fi done echo "bundle" >> $psf echo "tag $tag" >> $psf echo "title $title_prefix $title" | trunc 80 >> $psf if [ "$bun_category" != "" ] ; then echo " category $bun_category" >> $psf fi if [ "$bun_rev" != "" ] ; then echo " revision $bun_rev" >> $psf fi if [ "$bun_arch" != "none" ] ; then echo " architecture $bun_arch" >> $psf fi fi # end starting a new bundle. # For 11.* and beyond the bundle contents should not specify # the fileset architecture attribute (fa=) because a bundle # could contain multiple architectures and SD must be allowed # to choose the right ones. Explicitly listing them removes # SD's ablity to pick just the ones that apply and it will fail # to load any. So strip off the fa=* attribute: spec=${spec%%,fa=*} echo " contents $spec" >> $psf last_prod=$cur_prod done < $swtopkg if [ "$users_psf" != "" ] ; then cp $psf $users_psf exit_val=$? exit $exit_val fi swpackage -s $psf $sd_layout_opts -xreinstall_files=true -d $depot exit_val=$? exit $exit_val fi ########################################################################## # # Create one bundle representing either the whole depot, or all unbundled # if [ $b_opt = true -o $B_opt = true ] ; then if [ $b_opt = true ] ; then get_unbundled > $swtopkg if [ ! -s $swtopkg ] ; then echo "All software in depot is already in a bundle." >&2 exit_val=2 exit 2 fi else # Get all filesets. swlist -l fileset -s $depot -a software_spec \* | \ awk '/^[^#]/ {print $2}' > $swtopkg fi cat > $psf << EOF2 ################################################################# # swpackage product specification file generated by make_bundles # on $(date). For depot: $depot # # To run swpackage to apply the bundle definitions to the # depot, use the command: # # swpackage -s ${users_psf:-$psf} $sd_layout_opts -xreinstall_files=true -d $depot # ################################################################# EOF2 echo "bundle" >> $psf echo "tag $bun_name" >> $psf echo "title $bun_title" >> $psf if [ "$bun_category" != "" ] ; then echo " category $bun_category" >> $psf fi if [ "$def_bun_rev" != "" ] ; then echo " revision $def_bun_rev" >> $psf fi num_a=$(grep "a=" $swtopkg |awk -F "a=" '{split($2, x, ","); print x[1]}'|\ sort -u | wc -l) # Pick the longest architecture string (best default). bun_arch=$(grep "a=" $swtopkg |awk -F "a=" 'BEGIN{long=""} {split($2, x, ","); if (length(x[1]) > length(long)) long=x[1] } END { print long}') if [ $num_a -gt 1 ] ; then echo "\ WARNING: Filesets in the depot have multiple architectures. Will use \"$bun_arch\" as the architecture for the bundle. If this is not correct, then use the -o option and manually edit the PSF created." >&2 fi if [ $num_a -gt 0 ] ; then echo " architecture $bun_arch" >> $psf fi for fs in $(cat $swtopkg) do # Remove the fa= attribute for the same reason as stated earlier fs=${fs%%,fa=*} echo " contents $fs" >> $psf done echo "end" >> $psf if [ "$users_psf" != "" ] ; then cp $psf $users_psf exit_val=$? exit $exit_val fi swpackage -s $psf $sd_layout_opts -xreinstall_files=true -d $depot exit_val=$? exit $exit_val fi # Not reached