Novell Cool Solutions

Creating a Monolithic Package Bundle in ZLM 7.x Using Mirrored YOU Patch Bundles from YaST Update Channel


December 4, 2009 11:01 am







A ZENworks 7.x Linux Management server allows you to mirror or download the YaST Online Update (YOU) patches from the YOU Update Server ( by using zlmmirror utility. These YOU Patches are mirrored as YOU Patch Bundles under ZLM and are applicable for only updating all the SLES9 and OES1 devices. ZLM allows you update these devices by either applying the individual YOU patch bundles or an equivalent monolithic update bundle created from all these patches in the channel. The Monolithic bundles contains only the latest version of the unique (NEVRA) packages from all the YOU patch bundles, thus filtering the duplicate packages of same or lower version from all these patch bundles.

Monolithic Update bundle vs YOU Patch bundle

In ZLM7.2 IR2 hot patch or later, the patching of SLES9 and OES1 devices by using single monolithic bundle is equivalent to using all the YOU Patch bundles in terms of device state after package installation.

The monolithic bundle deployment to managed devices is fast and consumes less network bandwidth as the bundle payload data is at least less than 50% for same packages. Monolithic bundle based deployment only downloads those packages to the device that are needed to resolve the dependencies while updating the device. But in case of patch bundles all the packages and even patch rpms are downloaded unconditionally to the agent before installing the required ones using SUSE’s online_update tool.

The ZLM server is overloaded longer for download request from multiple agents for these duplicate packages in case of Patch bundle but this is addressed in using monolithic bundle deployment. Also it reduces the load on devices during installing monolithic update bundle since the backend helpers does not run for each patch bundle install action. However installing monolithic bundle packages do not record the satisfiability of installed YOU patches but state of the devices in terms of installed packages is same. Monolithic bundle properties can be modified, however the mirrored YOU patch bundles are not editable to user, unless its copy is created on the Server


In ZLM7.2, the equivalent Monolithic update bundle does not exist or contains all the packages from all the mirrored YOU patch bundles. As the support for creating Monolithic update bundle feature added in ZLM7.2 at IR2 HP1 release time, the update bundle thus created will not contain the packages from the older YOU patches mirrored prior to that period. The alternate method would be to delete all the mirrored YOU Patch bundles from the ZLM server and re-download which incurs re-download of 8-10 GB of bundle data from YOU repository channel to the ZLM server, that can be avoided.

System Environment

The solution explained in this document is applicable for the ZLM7.2 Server which has YOU Patches mirrored from YaST Update Server “” and its equivalent monolithic bundle is not up-to-date. The utility allows you to create single monolithic bundle from all the existing mirrored YOU patch bundles present under a given folder on the ZLM Server, avoiding re-download of the equivalent monolithic bundle packages from the YOU repository channel.



  • ZLM server installed with Postgres as its backend database.
  • The perl and rpm-devel packages should be installed on the ZLM Server device.
  • Perl-RPM-1.51 module is required to be installed. To obtain this module refer to and download the Perl-RPM-1.51.tar.gz file and follow its README steps for installation
  • For better performance of zlman commands used in the script, It is recommended to increase the JVM heap memory for the zlman script as follows:
    ZLMAN_OPTS=”-Xms512m -Xmx512m”


  • The script creates Monolithic Package Bundle from all mirrored YOU patch bundles packages. Packages are added to bundle using ‘force-nevra’ mirror option and freshen flag as true.
  • The monolithic bundle can be created containing packages for a single target platform at a time eg. sles-9-i586.
  • Like the normal monolithic bundle in ZLM7, this bundle created would filter out the scripts and .patch.rpm from the YaST Patches and adds the full rpm packages.
  • Packages added to the bundle are logged in max-rpm-version-list.txt file created under the present directory.
  • Changing the name and location of the perl script is not allowed since it is invoked from the bash script
  • The User must provide the source-folder-path, version and bundle type and its folder path in zlman semantics only. Adding packages from all patch bundles to the monolithic bundle would consume time depending on the packages present in the patches, and system resources like RAM, Processor etc


  • The Bash script and the Perl script should be copied under the same path on the ZLM Server.
  • Configure .zlmanrc file under /root on the ZLM Server to skip interactive Username and Password during execution of zlman commands.
  • Run the bash script as root user on the ZLM7.2 Server or later having YOU Patch Bundle (patch-xxxxx) already mirrored to some folder.
These steps is not be needed on the installed ZLM7.3 Server which has configurable mirror option (-o) to locally delete previously mirrored YOU patch bundles which has got obsoleted in the channel now and it also allows to create monolithic bundles(per SP level) at the same time with latest packages. However, if YOU patches were downloaded before upgrading to ZLM7.3 Server, then may be used to directly create the single monolithic bundle from all these patches without actually re-downloading the monolithic update bundles for older SPs . But before running this script, the obsolete YOU patch bundles can be eliminated locally by updating the into the local patch folder with –o mirror option. The single update bundle thus created, would contain the packages from the mirrored patches of all the pre-released Service Packs on SLES9 or OES1.

An example scenario:

Assume there are 4 YOU patches released each containing package ‘clamav’ like patch-9910, patch-11351 , patch-11451, patch-12318, where each patch with higher number(xxxx) contains an update for ‘clamav’ over its lower patch. If the patch-9910 and patch-11351 were mirrored on the Server prior to monolithic bundle support in ZLM and patch-11451, patch-12318 was mirrored after the support, then monolithic bundle is created with only packages from the patch-11451 and patch-12318, while mirroring them from the YOU repository. If the older patches contains some other dependant package also, it will not be part of monolithic bundle unless it has some update released while mirroring post the monolithic bundle support.



sh -s [source-folder-path] -d [destination-folder-path] -b [bundle-name] -t [target]

source-folder-path: Bundle folder name containing YOU patch bundles with its path,
destination-folder-path: Target Bundle folder name with its path
bundle-name: Name of the Monolithic bundle to be created
target: Target OS platform


sh -s you-patches-folder -d you-update-folder -b Monolithic-update-bundle -t sles-9-i586

Bash Script:

   echo USAGE:
   echo $0 -s '<'source-folder-path'>'  -d '<'destination-folder-path'>'  -b '<'bundle-name'>'  -t '<'target'>'  -h 
   echo "For example : sh $0 -s Patches/SLES9-32  -d Updates/SLES9-32 -b SLES9-32-Monolithic-bundle  -t sles-9-i586 "
   exit 1          

if [ $# -ne 8 ]; then 

if [ $# -ne 0 ] ; then 
        while getopts :s:d:b:t:h option 
          case "$option" in
            s)  src_youpatchbundle_foldername_path="$OPTARG";;
            d)  bundle_folder_path="$OPTARG";;
            b)  package_bundle_name="$OPTARG";;
            t)  target="$OPTARG";;
            h)  usage;;
            ?)  usage

target_packagebundle_path=$bundle_folder_path/$package_bundle_name # Target packagebundle path and name
zlman bc $package_bundle_name $bundle_folder_path
zlman bl  $src_youpatchbundle_foldername_path  | grep  "patch-" |awk '{print $1}'  > you-bundles.txt 
sed s/^/\'/g you-bundles.txt >you-bundles.txt1
sed s/$/\'\,/g you-bundles.txt1 >you-bundles.txt2
bundlelist=`cat you-bundles.txt2`
finalbundlelist=$bundlelist"'dummy'"   #making changes to  handle extra comma operator 
start_time=`date '+%s'`
# Postgres : Get the unique nevra packages from  db for you patch bundles and specific  target 
psql  -d zenworks -U zenadmin -c " select distinct name,version,release,arch from zen_package where pkgid in (  select bp.pkgid from bundle_package bp , zen_bundle  b  where b.bndlid=bp.bndlid  and in ($finalbundlelist) ) and pkgmgr='managedrpm' and  osid=(select osid from os_targets where name='$target' ) " > you-packages.txt

# Check the db type and do the same query for oracle  
perl you-packages.txt > max-rpm-version-list.txt         # Generate max (ver-rel) package collections for duplicate packages
rm  -f you-packages.txt  you-bundles.txt1  you-bundles.txt2 you-bundles.txt   #Cleaning up  necessary temp files 
echo  "Package list for the Monolithic bundle is being generated from current Package Repository. Please Wait..."
grep [0-9] max-rpm-version-list.txt  | awk '{print $1, $2, $3, $4}' |
  while read  pkg ver rel arch; do
        pkgname=`find /var/opt/novell/zenworks/pkg-repo/packages/ -iname $pkgname`       #Searching packages to add in the ZLM repository
        if [ "$pkglist" ==  "" ]; then
                echo $target > /tmp/pkg-target
                pkglist="$pkglist $pkgname"
        echo $pkglist > /tmp/pkg-names
        target=`cat /tmp/pkg-target`
        pkglist=`cat /tmp/pkg-names`

        zlman bap --freshen=true --force-nevra $target_packagebundle_path  $target $pkglist    #Adding Packages to the bundles 

        if [ $? -ne 0 ];then
          echo "Error while adding packages to the monolithic bundle . Check log file zlman.log for more details "
          exit -1
        rm  -f /tmp/pkg-target   /tmp/pkg-names 

finish_time=`date '+%s'`
duration=`expr $finish_time - $start_time`

echo  "Created Monolithic Package bundle: $target_packagebundle_path with $count packages in $duration seconds"

Perl Script:

require RPM;
import RPM vercmp;

%pkghash = {};
open(IP,@ARGV[0]) || die "Input file is not provided";
    @cols = split('\|');
    $len = @cols;
    if($len >= 4)
        $name = trim($cols[0]);
        $ver = trim($cols[1]);
        $rel = trim($cols[2]);
        $arch = trim($cols[3]);
        if (exists($pkghash{$name."-".$arch}))
           $ename = $pkghash{$name."-".$arch}->[0];
           $ever = $pkghash{$name."-".$arch}->[1];
           $erel = $pkghash{$name."-".$arch}->[2];
           $earch = $pkghash{$name."-".$arch}->[3];

           $ret = vercmp($ever,$erel,$ver,$rel);
           if ($ret == -1)
               my @valarr = ($name, $ver, $rel, $arch);
               $pkghash{$name."-".$arch} = \@valarr;
            my @valarr = ($name, $ver, $rel, $arch);
            $pkghash{$name."-".$arch} = \@valarr;

while(($key, $value) = each(%pkghash))
   print "$value->[0]\t$value->[1]\t$value->[2]\t$value->[3]\n";

sub trim($)
	my $string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	return $string;

0 votes, average: 0.00 out of 50 votes, average: 0.00 out of 50 votes, average: 0.00 out of 50 votes, average: 0.00 out of 50 votes, average: 0.00 out of 5 (0 votes, average: 0.00 out of 5)
You need to be a registered member to rate this post.

Categories: Uncategorized


Disclaimer: This content is not supported by Novell. It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test it thoroughly before using it in a production environment.