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

 
0 Likes

Contents:












Introduction



A ZENworks 7.x Linux Management server allows you to mirror or download the YaST Online Update (YOU) patches from the YOU Update Server (https://you.novell.com/update) 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




Problem


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 “you.novell.com” 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.




Solution










Prerequisites



  • 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 http://search.cpan.org/dist/Perl-RPM/ 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"




Instructions



  • The script Create_monolithic.sh 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 max_rpm_version.pl 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




Steps



  • The Bash script Create_monolithic.sh and the Perl script max_rpm_version.pl 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 Create_monolithic.sh as root user on the ZLM7.2 Server or later having YOU Patch Bundle (patch-xxxxx) already mirrored to some folder.



Note:
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.




Scripts



Usage:

sh Create_monolithic.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

Example:

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



Bash Script:




usage()
{

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
usage
fi

if [ $# -ne 0 ] ; then
while getopts :s:d:b:t:h option
do
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
esac
done
fi

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 b.name 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 max_rpm_version.pl 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
pkglist=""
count=0
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=$pkg-$ver-$rel.$arch.rpm
pkgname=`find /var/opt/novell/zenworks/pkg-repo/packages/ -iname $pkgname` #Searching packages to add in the ZLM repository
if [ "$pkglist" == "" ]; then
pkglist="$pkgname"
echo $target > /tmp/pkg-target
count=$((count 1))
else
pkglist="$pkglist $pkgname"
count=$((count 1))
fi
echo $pkglist > /tmp/pkg-names
done
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
fi
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: max_rpm_version.pl





#!/usr/bin/perl
require RPM;
import RPM vercmp;

%pkghash = {};
open(IP,@ARGV[0]) || die "Input file is not provided";
while()
{
if(/~[0-9]/)
{
next;
}
@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;
}
}
else
{
my @valarr = ($name, $ver, $rel, $arch);
$pkghash{$name."-".$arch} = \@valarr;
}
}
}
close(IP);

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;
}



Labels:

How To-Best Practice
Comment List
Related
Recommended