On Wed, 2009-09-09 at 09:09 -0500, Tom Brown wrote:
> > I promised to post the script I adapted for cloning errata from RHN
> to
> > my Spacewalk server.  I'm sad to say that it's not a completed work
> at
> > this point, but does the basic things.  Some things that are missing
> > and/or are caveats:

Still caveats and changes.  Read on.

> > 1) Updating errata that affect another channel, should you add a
> channel
> > that might be affected by an existing errata.

This should work.  As of right now, you'll process errata from RHN one
RHN-channel at-a-time.  If you add a channel that has an erratum that
affects channels you had before... it should be trivial.  (See further
comments below).

> > 2) I've been a little lazy and have hard-coded my own RHN
> credentials in
> > the script, rather than asking the user for the info, passing it as
> an
> > argument, or reading it from a file.  I'll get around to it later.

I still haven't gotten around to it... I'm not sure I will.  It's
trivial to update the script with your data.

> > 3) I would avoid errata publishing for the time-being.  The
> > functionality exists in the script, but it's not right.  If you pull
> > down an errata that's for both RHEL 4 & 5 (for instance).. you'll
> end up
> > with RHEL 5 packages in your RHEL 4 channels.  I need to work this
> out.

Ok, I have come up with another method for dealing with automagic errata
publishing upon import. 

The problem, as I see it, is that the API has no way of "merging"
errata.  So, to effectively import errata from RHN and have it
meaningful for the appropriate channels, I've taken to breaking up each
erratum.  This avoids having packages meant for RHEL 5... "published"
into RHEL 4 channels.  For instance, if erratum RHSA:XXXX is relevant
for say both 64-bit RHEL 4 and RHEL 5, it will be broken up into
multiple individual errata.  The way I'm doing this on my system (and
it's configurable) is this:

RHEL 5 64-bit:  RHSA:XXXX:R5-64
RHEL 4 64-bit:  RHSA:XXXX:R4-64

Yes... this can potential create a ton of errata on your system, but to
ensure packages are automagically published to the appropriate channels,
this is the only method I could come up with quickly.  There may be a
way in the future to better handle this via the API, but right now, it
eludes me.

> > 4) This is my first attempt at anything with Python.. so it's
> probably
> > quite horrible.  I will be updating this as I develop more, not sure
> if
> > the Spacewalk maintainers want to add something like this to their
> list
> > of user-contributed scripts... but I'd be happy to maintain it
> there, if
> > so.

I continue to flounder.

> Hi Andy
> 
> Do you have any basic useage examples of this please?? eg
> 
> # python spw-clone-errata.py -l myuser -p mypass -c
> rhel-x86_64-server-5
> spw-clone-errata.py:31: DeprecationWarning: the sets module is
> deprecated
>   from sets import Set
> try: spw-clone-errata.py --help

First, I've removed the dependency on the old-n-busted "sets" module.

But, usage examples.  In the new script (attached), there are two
important maps that you as a user will need to configure, if you choose
to do this my way.

1)  Map RHN channel to Spacewalk (SPW) channel:  This map is simply a
python dictionary whose keys are the RHN channel labels and whose values
are YOUR SPW channel labels.  My SPW labels match almost identically the
RHN channels, so this was mostly meaningless for my setup, but I wanted
the user to be able to be more flexible.  What this does for you, is
when you give the script the variable [-c --src-channel], which is the
RHN channel from which you want to pull errata, the errata get mapped to
your SPW channel that corresponds.  For instance, in my setup:

        The RHN channel:  
        
        'rhel-x86_64-server-5' 
        
        is mapped to my SPW channel with the same label. Too easy. But,
        the RHN channel:
        
        'rhel-x86_64-as-4'
        
        is mapped to my SPW channel named:
        
        'rhel-x86_64-server-4'
        
2)  Map RHN channel to Errata suffix:  This map is another dictionary
whose keys are again the RHN channel labels and whose values are the
suffixes that I want added to the "advisory" value of each erratum.
This is as discussed above.  For instance:

        RHN channel:
        
        'rhel-x86_64-server-5'
        
        has this suffix mapped to it:
        
        'R5-64'
        
        Kinda straight-forward.  There may be many philosophical
        problems with this, but for now, until something in the API is
        changed (which I have no skill for), this is all I got.
        
So... usage case.  Let's discuss how I use Spacewalk with RHN.

1)  My goal is to have two sets of RHEL channels.  One set of "default"
channels which contain every package ever released in a given channel on
RHN, such as 'rhel-x86_64-server-5' .. The other set of channels are my
"production" channels to which I clone relevant errata (and therefore
package updates) from the "default" channels.  This gives me release
management control over packages via Spacewalk.  Servers are only
subscribed to "production" channels... as distros and kickstarts are
only based on "prod" channels.

2)  To do this, I am collecting the packages on my SPW server using
mrepo (quite handy) and using spacewalk-repo-sync to get them into my
channels.  This is all scheduled via cron.  (I need to work out some
notifications on nightly updates).  I'd like to find time to work on a
patch for the SPW devs that handles any local packages differently.  As
of now, I basically have package duplication on my system.  I pull the
packages from RHN into local yum repos on my SPW server and then sync
them into SPW, which copies them into the packages repository that SPW
uses... I'd like to fix it so that it handles anything pulled locally
(via file:// URLs) as links (sym or hard) rather than duplicating it.
Pie-in-the-sky.

3)  I'm just now finishing up development of this errata script, and I
should be ready to go.  To use this script, in my environment, I invoke
it like this:

# ./spw-clone-errata.py -s <server> -l <user> -p <pass> -c <RHN channel>
-u

Usage details:

# ./spw-clone-errata.py -h
usage: spw-clone-errata.py [options]

options:
  -h, --help            show this help message and exit
  -s SRC_SERVER, --spw-server=SRC_SERVER
                        Spacewalk Server (spacewalk.mydomain.org)
  -l LOGIN, --login=LOGIN
                        RHN Login
  -p PASSWD, --password=PASSWD
                        RHN password
  -c SRC_CHANNEL, --src-channel=SRC_CHANNEL
                        Source Channel Label: ie."rhel-x86_64-server-5"
  -b BDATE, --begin-date=BDATE
                        Beginning Date: ie. "19000101" (defaults to
                        "19000101")
  -e EDATE, --end-date=EDATE
                        Ending Date: ie. "19001231" (defaults to TODAY)
  -u, --publish         Publish Errata (into destination channels)
  -v, --verbose         
  -q, --quiet

-----

I've not quite completed the exact procedure for cloning these errata to
"production" channels... that's next.

Does this help at all?  New script is attached.

> thanks

Sure... hope this is helpful.
-- 
Andy Speagle

"THE Student" - UCATS
Wichita State University
#!/bin/env python
# Script that uses RHN API to clone RHN Errata to Satellite
# or Spacewalk server.
# Copyright (C) 2008  Red Hat
#
# Author: Andy Speagle (andy.spea...@wichita.edu)
#
# This script was written based on the "rhn-clone-errata.py"
# script written by:  Lars Jonsson (ljons...@redhat.com)
#
# (THANKS!)
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
#
# Version Information:
#
# 0.1 - 2009-09-01 - Andy Speagle
#
#	Initial release.  Lots of problems.  Oof.
#
# 0.2 - 2009-09-11 - Andy Speagle
#
#	Updated methodology for handling errata. Breaking up individual
#	errata appended with a channel identifier to better automate publishing
#	of errata.
#
#	Some code reworking.  I still suck at python.  Removed deprecated "sets"
#	module.

import xmlrpclib
from optparse import OptionParser
from time import time, localtime, strftime
import sys
import os
import re

class RHNServer:
    def __init__(self,servername,user,passwd): 
        self.rhnServerName = servername
        self.login = user
        self.password = passwd
        self.rhnUrl = 'https://'+self.rhnServerName+'/rpc/api'
        self.server = xmlrpclib.Server(self.rhnUrl)
        self.rhnSession = self.rhnLogin(self.login,self.password,0)

    def rhnLogin(self, login, password, retry): 
        try:
            rhnSession=self.server.auth.login(login,password)
        except  xmlrpclib.Fault, f:
	    if options.verbose:
		print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode==-20:
                self.rhnLogin(login,password,retry)
            else:
                print "Failed to login",f
                raise
	except xmlrpclib.ProtocolError, err:
	    if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
	    if retry > 3:
		raise
	    else:
		return self.rhnLogin(login,password, (retry + 1))
        return rhnSession

    def getErrataChannels(self,advisory,retry):
	channels = []
	try:
	    details = self.server.errata.applicableToChannels(self.rhnSession,advisory)
	except xmlrpclib.Fault, f:
            if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.server.errata.applicableToChannels(self.rhnSession,advisory)
	    elif f.faultCode == -208:
                if options.verbose:            
                    print "Errata %s Doesn't Exist on %s ..." % (advisory,self.rhnServerName)
                return []
	    else:
                raise
        except xmlrpclib.ProtocolError, err:
            if options.verbose:
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else:
                return self.getErrataChannels(advisory, (retry + 1))
	return channels

    def getErrataDetails(self,advisory,retry):
	details = []
	try:
	    details = self.server.errata.getDetails(self.rhnSession,advisory)
	except xmlrpclib.Fault, f:
	    if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
	    if f.faultCode == -20:
		self.rhnLogin(self.login,self.password)
		return self.server.errata.getDetails(self.rhnSession,advisory)
	    elif f.faultCode == -208:
		if options.verbose:            
                    print "Errata %s Doesn't Exist on %s ..." % (advisory,self.rhnServerName)
		return []
	    else:
		raise
        except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.getErrataDetails(advisory, (retry + 1))
	return details

    def getErrataKeywords(self,advisory,retry):
	keywords = []
	try:
	    keywords = self.server.errata.listKeywords(self.rhnSession,advisory)
	except xmlrpclib.Fault, f:
            if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
	    if f.faultCode == -20:
		self.rhnLogin(self.login,self.password)
		return self.server.errata.listKeywords(self.rhnSession,advisory)
            elif f.faultCode == -208:
                if options.verbose:            
                    print "Errata %s Doesn't Exist on %s ..." % (advisory,self.rhnServerName)
                return []
	    else:
		print "Error Getting Keywords : "+advisory
        except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.getErrataKeywords(advisory, (retry + 1))
	return keywords

    def getErrataBugs(self,advisory,retry):
	bugs = []
	try:
	    bugs = self.server.errata.bugzillaFixes(self.rhnSession,advisory)
	except xmlrpclib.Fault, f:
            if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
	    if f.faultCode == -20:
		self.rhnLogin(self.login,self.password)
		return self.server.errata.bugzillaFixes(self.rhnSession,advisory)
            elif f.faultCode == -208:
                if options.verbose:            
                    print "Errata %s Doesn't Exist on %s ..." % (advisory,self.rhnServerName)
                return []
	    else:
		print "Error Getting Bugs : "+advisory
        except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.getErrataBugs(advisory, (retry + 1))
	return bugs

    def getErrataCVEs(self,advisory,retry):
	cves=[]
	try:
	    cves = self.server.errata.listCves(self.rhnSession,advisory)
	except xmlrpclib.Fault, f:
            if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.server.errata.listCves(self.rhnSession,advisory)
            elif f.faultCode == -208:
                if options.verbose:            
                    print "Errata %s Doesn't Exist on %s ..." % (advisory,self.rhnServerName)
                return []
            else:
                print "Error Getting CVEs : %s" % advisory
        except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.getErrataCVEs(advisory, (retry + 1))
        return cves

    def getErrataPackages(self,advisory,retry):
	packages=[]
	try:
	    packages = self.server.errata.listPackages(self.rhnSession,advisory)
	except xmlrpclib.Fault, f:
            if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
		return self.server.errata.listPackages(self.rhnSession,advisory)
            elif f.faultCode == -208:
                if options.verbose:            
                    print "Errata %s Doesn't Exist on %s ..." % (advisory,self.rhnServerName)
                return []
	    else:
		print "Error Getting Packages : %s" % advisory
	except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.getErrataPackages(advisory, (retry + 1))
	return packages

    def listChannelErrata(self,dest_chan,dateStart,dateEnd,retry):
	out = []
	try:
	    out = self.server.channel.software.listErrata(self.rhnSession,dest_chan,dateStart,dateEnd)
	except xmlrpclib.Fault, f:
            if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
	    if f.faultCode == -20:
		self.rhnLogin(self.login,self.password)
		return self.server.channel.software.listErrata(self.rhnSession,dest_chan,dateStart,dateEnd)
	    else:
		raise
        except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.listChannelErrata(dest_chan,dateStart,dateEnd,(retry + 1))
	return out

    def findPackageChannels(self,pkgid,retry):
        channels=[]
        try:
            channels = self.server.packages.listProvidingChannels(self.rhnSession,pkgid)
        except xmlrpclib.Fault, f:
            if options.verbose:
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.server.packages.listProvidingChannels(self.rhnSession,pkgid)
            else:
                print "Error Finding Channels for Package : %s" % pkgid
        except xmlrpclib.ProtocolError, err:
            if options.verbose:
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else:
                return self.server.packages.findPackageChannels(pkgid, (retrun + 1))
        return channels

    def cloneErrata(self,dest_chan,errata,retry):
        out=[]
        try:
            print "Clone errata in progress, please be patient.."
            out = self.server.errata.clone(self.rhnSession,dest_chan,errata)
        except  xmlrpclib.Fault, f:
            print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.self.server.errata.clone(self.rhnSession,dest_chan,errata)
            else:
                raise
        except xmlrpclib.ProtocolError, err:
            print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.cloneErrata(dest_chan,errata, (retry + 1))
        return out

class SPWServer(RHNServer):

    def searchNVREA(self,name,version,release,epoch,archlabel,retry):
	package=[]
 	try:
	    package = self.server.packages.findByNvrea(self.rhnSession,name,version,release,epoch,archlabel)
	except xmlrpclib.Fault, f:
	    if options.verbose:            
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
		return self.server.packages.findByNvrea(self.rhnSession,name,version,release,archlabel)
	    else:
		print "Error Finding Package via NVREA : %s" % name
	except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.searchNVREA(name,version,release,epoch,archlabel, (retry + 1))
        return package

    def listChannelErrata(self,dest_chan,retry):
        out = []
        try:
            out = self.server.channel.software.listErrata(self.rhnSession,dest_chan)
        except xmlrpclib.Fault, f:
            if options.verbose:
                print "Fault Code: %d\tFault String: %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.server.channel.software.listErrata(self.rhnSession,dest_chan)
            else:
                raise
        except xmlrpclib.ProtocolError, err:
            if options.verbose:
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else:
                return self.listChannelErrata(dest_chan,(retry + 1))
        return out

    def errataPublish(self,name,channels,retry):
	errata=[]
	try:
	    errata = self.server.errata.publish(self.rhnSession,name,channels)
	except xmlrpclib.Fault, f:
            if options.verbose:
                print "Fault Code: %d - %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.server.errata.publish(self.rhnSession,name,channels)
	    elif f.faultCode == 2601:
                print "Errata Already Exists..."
                return []
            else:
                print "Error Creating Errata!"
                raise
        except xmlrpclib.ProtocolError, err:
            if options.verbose:
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else:
                return self.errataPublish(name,channels, (retry + 1))
	return errata

    def errataCreate(self,info,bugs,keywords,packages,publish,channels,retry):
	new_errata=[]
	try:
	    new_errata = self.server.errata.create(self.rhnSession,info,bugs,keywords,packages,publish,channels)
	except xmlrpclib.Fault, f:
	    if options.verbose:            
                print "Fault Code: %d - %s" % (f.faultCode,f.faultString)
            if f.faultCode == -20:
                self.rhnLogin(self.login,self.password)
                return self.server.errata.create(self.rhnSession,info,bugs,keywords,packages,publish,channels)
	    elif f.faultCode == 2601:
		print "Errata Already Exists..."
		return []
	    else:
                print "Error Creating Errata!"
		raise
	except xmlrpclib.ProtocolError, err:
            if options.verbose:            
                print "ProtocolError: %d - %s" % (err.errcode,err.errmsg)
            if retry > 3:
                raise
            else: 
                return self.errataCreate(info,bugs,keywords,packages,publish,channels, (retry + 1))
        return new_errata

def parse_args():
    parser = OptionParser()
    parser.add_option("-s", "--spw-server", type="string", dest="src_server",
            help="Spacewalk Server (spacewalk.mydomain.org)") 
    parser.add_option("-l", "--login", type="string", dest="login",
            help="RHN Login") 
    parser.add_option("-p", "--password", type="string", dest="passwd",
            help="RHN password") 
    parser.add_option("-c", "--src-channel", type="string", dest="src_channel",
            help="Source Channel Label: ie.\"rhel-x86_64-server-5\"") 
    parser.add_option("-b", "--begin-date", type="string", dest="bdate",
	    help="Beginning Date: ie. \"19000101\" (defaults to \"19000101\")")
    parser.add_option("-e", "--end-date", type="string", dest="edate",
	    help="Ending Date: ie. \"19001231\" (defaults to TODAY)")
    parser.add_option("-u", "--publish", action="store_true", dest="publish", default=False,
	    help="Publish Errata (into destination channels)")
    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False)
    parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False)

    (options,args) = parser.parse_args()
    return options 

def main():
    global chanMap
    global chanSuffixMap
    global RHNServer
    global RHNUser
    global RHNPass
    global options

    options = parse_args()

    if (options.src_server and options.login and options.passwd) is None:
        print "try: "+sys.argv[0]+" --help"
        sys.exit(2)

#   I don't reckon this should change anytime soon...
#
    svrRHN = 'rhn.redhat.com'

#   Ok, configure your RHN credentials here...
#
    userRHN = 'FIXME'
    passRHN = 'FIXME'

#   Here we setup our mappings from RHN to Local software channels.
#   Set these to what you have created for your SPW.
#   They are paired as:
#
#   RHNChannel: SPWChannel
#
    chanMap = {
		'rhel-x86_64-server-5':			'rhel-x86_64-server-5',
		'rhn-tools-rhel-x86_64-server-5':	'rhel-x86_64-server-rhntools-5',
		'rhel-x86_64-server-productivity-5':	'rhel-x86_64-server-productivity-5',
		'rhel-x86_64-server-supplementary-5':	'rhel-x86_64-server-supplementary-5',
		'rhel-x86_64-server-vt-5':		'rhel-x86_64-server-vt-5',
		'rhel-i386-server-5':			'rhel-i386-server-5',
		'rhn-tools-rhel-i386-server-5':		'rhel-i386-server-rhntools-5',
                'rhel-i386-server-productivity-5': 	'rhel-i386-server-productivity-5',
                'rhel-i386-server-supplementary-5':	'rhel-i386-server-supplementary-5',
                'rhel-i386-server-vt-5':		'rhel-i386-server-vt-5',
		'rhel-x86_64-as-4':			'rhel-x86_64-server-4',
		'rhel-x86_64-as-4-extras':		'rhel-x86_64-server-extras-4',
		'rhn-tools-rhel-4-as-x86_64':		'rhel-x86_64-server-rhntools-4',
		'rhel-i386-as-4':			'rhel-i386-server-4',
		'rhel-i386-as-4-extras':		'rhel-i386-server-extras-4',
		'rhn-tools-rhel-4-as-i386':		'rhel-i386-server-rhntools-4'
		};

#   Here we also setup mappings from RHN channels to errata suffixes.
#   Since we can't easily publish automagically, while ensuring that
#   the right packages go into the right channels, we're going to
#   split multi-channel affecting errata into individual errata
#   that are suffixed with something meaningful that identifies
#   each sub-errata per channel... blah blah... Of course, modify this
#   as you will.
#
#   RHNChannel: ErrataSuffix
#
    chanSuffixMap = {
		'rhel-x86_64-server-5':			'R5-64',
		'rhn-tools-rhel-x86_64-server-5':	'R5-64-T',
		'rhel-x86_64-server-productivity-5':	'R5-64-P',
		'rhel-x86_64-server-supplementary-5':	'R5-64-S',
		'rhel-x86_64-server-vt-5':		'R5-64-V',
		'rhel-i386-server-5':			'R5-32',
		'rhn-tools-rhel-i386-server-5':		'R5-32-T',
		'rhel-i386-server-productivity-5':	'R5-32-P',
		'rhel-i386-server-supplementary-5':	'R5-32-S',
		'rhel-i386-server-vt-5':		'R5-32-V',
		'rhel-x86_64-as-4':			'R4-64',
		'rhel-x86_64-as-4-extras':		'R4-64-E',
		'rhn-tools-rhel-4-as-x86_64':		'R4-64-T',
		'rhel-i386-as-4':			'R4-32',
		'rhel-i386-as-4-extras':		'R4-32-E',
		'rhn-tools-rhel-4-as-i386':		'R4-32-T'
		};

    if chanMap[options.src_channel] is None:
	print "Invalid Channel!"
	sys.exit(2)

    myRHN = RHNServer(svrRHN,userRHN,passRHN)
    mySPW = SPWServer(options.src_server,options.login,options.passwd)

    dateStart = options.bdate or '19000101'
    dateEnd = options.edate or strftime("%Y%m%d", localtime())

    for rhnErrata in myRHN.listChannelErrata(options.src_channel,dateStart,dateEnd,0):
	if not options.quiet:
            print rhnErrata['errata_advisory']

#   	Now, let's check if we already have this errata locally...
	spwErrataName = rhnErrata['errata_advisory']+':'+chanSuffixMap[options.src_channel]
	spwErrCheck = mySPW.getErrataDetails (spwErrataName,0)

	if not spwErrCheck:
#           Ok, so the errata doesn't already exists... let's get busy creating it.
	    spwErrSolution = "Before applying this update, make sure that all "+\
	        "previously-released errata relevant to your system have been applied."	

	    spwErrPackages = []
	    for pkg in myRHN.getErrataPackages(rhnErrata['errata_advisory'],0):
	        pkgFind = mySPW.searchNVREA(pkg['package_name'],\
					    pkg['package_version'],\
					    pkg['package_release'],\
					    '',\
					    pkg['package_arch_label'],\
					    0)

	        for pkgChan in pkg['providing_channels']:
		    if pkgChan != chanMap[options.src_channel]:
		        continue
		    else:
		        if not pkgFind:
			    print "Hmmm... Package Missing: %s" % pkg['package_name']
		        else:
			    spwErrPackages.append(pkgFind[0]['id'])
		            break

	    spwErrDetails = myRHN.getErrataDetails(rhnErrata['errata_advisory'],0)
            spwErrKeywords = myRHN.getErrataKeywords(rhnErrata['errata_advisory'],0)

	    spwErrBugs = []
            tmpBugs = myRHN.getErrataBugs(rhnErrata['errata_advisory'],0)

            for bug in tmpBugs:
                spwErrBugs.append({'id': int(bug), 'summary': tmpBugs[bug]})

	    if not options.quiet:
	        print "\t%s - %s" % (spwErrDetails['errata_issue_date'],spwErrDetails['errata_synopsis'])

	    spwErrObject = mySPW.errataCreate ({ 'synopsis': spwErrDetails['errata_synopsis'],\
					         'advisory_name': spwErrataName,\
					         'advisory_release': 1,\
					         'advisory_type': spwErrDetails['errata_type'],\
					         'product': 'RHEL',\
					         'topic': spwErrDetails['errata_topic'],\
					         'description': spwErrDetails['errata_description'],\
					         'references': spwErrDetails['errata_references'],\
					         'notes': spwErrDetails['errata_notes'],\
					         'solution': spwErrSolution },\
				     	         spwErrBugs,\
					         spwErrKeywords,\
					         spwErrPackages,\
					         options.publish,\
					         [chanMap[options.src_channel]],\
					         0)

	    print "\tErrata Created: %d" % spwErrObject['id']
        else:
            if not options.quiet:
                print "\tErrata already exists.  %s" % spwErrataName

if __name__ == "__main__":
    main()

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Spacewalk-list mailing list
Spacewalk-list@redhat.com
https://www.redhat.com/mailman/listinfo/spacewalk-list

Reply via email to