[Spacewalk-list] rhn-clone-errata.py ProtocolError: 502 -Proxy Error
Jet Wilda
Jet.Wilda at fadv.com
Fri Nov 5 16:31:54 UTC 2010
Hi,
I'm using Spacewalk 1.1 with version 0.6 of the script pasted
below.
#!/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... at wichita.edu)
#
# This script was written based on the "rhn-clone-errata.py"
# script written by: Lars Jonsson (ljons... at 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.
#
# 0.3 - 2009-09-17 - Andy Speagle
#
# Fixed a rather glaring bug in the logic regarding relevant
channel
# for package selection. Ugh.
#
# 0.4 - 2009-10-01 - Andy Speagle
#
# Modified how the publish happens. Now it creates the errata and
THEN
# calls the separate errata.publish() function. I was having some
# intermittent time-outs doing the two together in the
errata.create()
# function.
#
# 0.5 - 2010-03-17 - Andy Speagle
#
# Moved servers, users and passwords to a config file of your
choice.
# Many config options changed as a result. Options on the command
line
# override config file options.
#
# Merged proxy support code from Colin Coe <colin.... at gmail.com>
(THANKS!)
#
# Modified some of the formatting for logfile output.
#
# I continue to suck at Python.
#
# 0.6 - 2010-03-18 - Andy Speagle
#
# Corrected a grievous bug in the new Proxy code.
#
# Moved Channel and ChannelSuffix maps to the config file.
import xmlrpclib, httplib
from optparse import OptionParser
from time import time, localtime, strftime
from datetime import datetime, timedelta
import sys
import os
import re
import ConfigParser
class ProxiedTransport(xmlrpclib.Transport):
def set_proxy(self, proxy):
self.proxy = options.proxy
def make_connection(self, host):
self.realhost = host
h = httplib.HTTP(self.proxy)
return h
def send_request(self, connection, handler, request_body):
connection.putrequest("POST", "http://%s%s"; % (self.realhost,
handler))
def send_host(self, connection, host):
connection.putheader("Host", self.realhost)
class RHNServer:
def __init__(self,servername,user,passwd):
self.rhnServerName = servername
self.login = user
self.password = passwd
self.rhnUrl = 'https://'+self.rhnServerName+'/rpc/api'
if options.proxy is None:
self.server = xmlrpclib.Server(self.rhnUrl)
else:
proxy = ProxiedTransport()
proxy.set_proxy(options.proxy);
self.server = xmlrpclib.Server(self.rhnUrl, transport=proxy)
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 or f.faultCode == -1:
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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,dateSt
art,dateEnd)
except xmlrpclib.Fault, f:
if options.verbose:
print "Fault Code: %d\tFault String: %s" %
(f.faultCode,f.faultString)
if f.faultCode == -20 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
return
self.server.channel.software.listErrata(self.rhnSession,dest_chan,dateSt
art,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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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,ep
och,archlabel)
except xmlrpclib.Fault, f:
if options.verbose:
print "Fault Code: %d\tFault String: %s" %
(f.faultCode,f.faultString)
if f.faultCode == -20 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
return
self.server.packages.findByNvrea(self.rhnSession,name,version,release,ar
chlabel)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
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,pu
blish,channels)
except xmlrpclib.Fault, f:
if options.verbose:
print "Fault Code: %d - %s" %
(f.faultCode,f.faultString)
if f.faultCode == -20 or f.faultCode == -1:
self.rhnLogin(self.login,self.password,0)
return
self.server.errata.create(self.rhnSession,info,bugs,keywords,packages,pu
blish,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="spw_server",
help="Spacewalk Server (spacewalk.mydomain.org)")
parser.add_option("-S", "--rhn-server", type="string",
dest="rhn_server",
help="RHN Server (rhn.redhat.com)")
parser.add_option("-u", "--spw-user", type="string",
dest="spw_user",
help="Spacewalk User")
parser.add_option("-p", "--spw-pass", type="string",
dest="spw_pass",
help="Spacewalk Password")
parser.add_option("-U", "--rhn-user", type="string",
dest="rhn_user",
help="RHN User")
parser.add_option("-P", "--rhn-pass", type="string",
dest="rhn_pass",
help="RHN Password")
parser.add_option("-f", "--config-file", type="string",
dest="cfg_file",
help="Config file for servers, users and passwords.")
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("-i", "--publish", action="store_true",
dest="publish", default=False,
help="Publish Errata (into destination channels)")
parser.add_option("-x", "--proxy", type="string", dest="proxy",
help="Proxy server and port to use (e.g.
proxy.company.com:3128)")
parser.add_option("-F", "--format-header", action="store_true",
dest="format", default=False,
help="Format header for logfiles")
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()
# Config File Format: It needs to be ConfigParser compliant:
#
# [Section]
# option=value
if (options.cfg_file):
config = ConfigParser.ConfigParser()
config.read (options.cfg_file)
if options.spw_server is None:
options.spw_server = config.get ('Spacewalk', 'spw_server')
if options.spw_user is None:
options.spw_user = config.get ('Spacewalk', 'spw_user')
if options.spw_pass is None:
options.spw_pass = config.get ('Spacewalk', 'spw_pass')
if options.rhn_server is None:
options.rhn_server = config.get ('RHN', 'rhn_server')
if options.rhn_user is None:
options.rhn_user = config.get ('RHN', 'rhn_user')
if options.rhn_pass is None:
options.rhn_pass = config.get ('RHN', 'rhn_pass')
# Here we setup our mappings from RHN to Spacewalk software
channels.
# These are read from the config file in this format:
#
# [ChanMap]
# RHNChannel = SPWChannel
#
# Example:
# rhn-tools-rhel-x86_64-server-5 = rhel-x86_64-server-rhntools-5
chanMap = {}
for chan in config.options('ChanMap'):
chanMap[chan] = config.get('ChanMap', chan)
# 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. I'm not sure if this will be required in the
future.
#
# [ChanSuffixMap]
# RHNChannel = ErrataSuffix
#
# Example:
# rhn-tools-rhel-x86_64-server-5 = R5-64-T
chanSuffixMap = {}
for chan in config.options('ChanSuffixMap'):
chanSuffixMap[chan] = config.get('ChanSuffixMap', chan)
if (options.spw_server and options.spw_user and options.spw_pass and
options.rhn_server and options.rhn_user and options.rhn_pass) is
None:
print "try: "+sys.argv[0]+" --help"
sys.exit(2)
if chanMap[options.src_channel] is None:
print "Invalid Channel!"
sys.exit(2)
myRHN = RHNServer(options.rhn_server, options.rhn_user,
options.rhn_pass)
mySPW = SPWServer(options.spw_server, options.spw_user,
options.spw_pass)
dateStart = options.bdate or '19000101'
dateToday = strftime("%Y%m%d", localtime())
dateEnd = options.edate or dateToday
if options.format:
print >>sys.stdout, "%s:CLONE:%s" % (dateToday,
options.src_channel)
print >>sys.stderr, "%s:CLONE:%s" % (dateToday,
options.src_channel)
for rhnErrata in
myRHN.listChannelErrata(options.src_channel,dateStart,dateEnd,0):
if not options.quiet and not options.format:
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 != options.src_channel:
continue
else:
if not pkgFind:
if options.format:
print >>sys.stderr, "%s:%s:Hmmm... "+\
"Package Missing: %s" % (dateToday,
rhnErrata['errata_advisory'], pkg['package_name'])
else:
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 and not options.format:
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,\
0,\
[chanMap[options.src_channel]],\
0)
if options.format:
print "%s#%d#Errata Created#" % (dateToday,
spwErrObject['id']),
else:
print "\tErrata Created: %d" % spwErrObject['id']
if options.publish:
spwPublish = mySPW.errataPublish (spwErrataName,
[chanMap[options.src_channel]], 0)
if options.format:
print "Errata Published"
else:
print "\tErrata Published!"
else:
if options.format:
print "Errata Not Published"
else:
print "\tErrata Not Published!"
else:
if options.format:
print "%s#%s#Errata Already Exists" % (dateToday,
spwErrataName)
elif not options.quiet:
print "\tErrata Already Exists. %s" % spwErrataName
continue
if __name__ == "__main__":
main()
Thanks,
~Jet
-----Original Message-----
From: spacewalk-list-bounces at redhat.com
[mailto:spacewalk-list-bounces at redhat.com] On Behalf Of Speagle, Andy
Sent: Friday, November 05, 2010 12:20 PM
> Hi,
>
> I found version 0.6 of rhn-clone-errata.py here http://www.mail-
> archive.com/spacewalk-devel at redhat.com/msg02017.html and it seems to
> work if I don't publish the errata. However if I publish the errata
it throws
> errors 'ProtocolError: 502 - Proxy Error' (3 or 4 of them) and then
dies, but the
> 1 errata eventually is published. If I run the script without
publishing it
> creates all the errata but they are not published. Any and all help
greatly
> appreciated.
>
> Thanks,
> ~Jet
Hi Jet,
With which version of Spacewalk are you using this script? I've only
tested it through v1.0. Also, please send me the version of the script
that you're using.
Thanks,
Andy Speagle
System & Storage Administrator
UCATS - Wichita State University
_______________________________________________
Spacewalk-list mailing list
Spacewalk-list at redhat.com
https://www.redhat.com/mailman/listinfo/spacewalk-list
More information about the Spacewalk-list
mailing list