backend/common/rhnRepository.py | 2
backend/satellite_tools/reposync.py | 4
backend/satellite_tools/satCerts.py | 2
backend/satellite_tools/satComputePkgHeaders.py | 2
backend/satellite_tools/satsync.py | 2
backend/satellite_tools/updatePackages.py | 2
backend/server/handlers/app/rhn_mpm.py | 2
backend/server/handlers/applet/applet.py | 2
backend/server/handlers/xmlrpc/up2date.py | 2
backend/server/handlers/xp/rhnlint.py | 2
backend/server/importlib/backend.py | 2
backend/server/importlib/packageUpload.py | 2
backend/server/rhnChannel.py | 2
backend/server/rhnPackageUpload.py | 2
backend/server/rhnServer/server_class.py | 2
backend/server/rhnServer/server_packages.py | 2
backend/setup.py | 17
backend/spacewalk-backend.spec | 28 +
backend/spacewalk/common/rhn_mpm.py | 283 ++++++++++++++
backend/spacewalk/common/rhn_rpm.py | 462 +++++++++++++++++++++++
client/rhel/rhnlib/rhn/common/rhn_mpm.py | 283 --------------
client/rhel/rhnlib/rhn/common/rhn_rpm.py | 462 -----------------------
client/rhel/rhnlib/setup.py.in | 2
client/tools/rhnpush/rhnpush.spec | 3
rel-eng/packages/spacewalk-backend | 2
spacewalk/certs-tools/spacewalk-certs-tools.spec | 2
26 files changed, 810 insertions(+), 768 deletions(-)
New commits:
commit 30efa10c87fd46087fb8e40031930ef3a5d4acab
Author: Michael Mraka <michael.mraka(a)redhat.com>
Date: Mon Dec 7 16:58:59 2009 +0100
Automatic commit of package [spacewalk-backend] release [0.8.3-1].
diff --git a/backend/spacewalk-backend.spec b/backend/spacewalk-backend.spec
index 9ec125a..666f2ad 100644
--- a/backend/spacewalk-backend.spec
+++ b/backend/spacewalk-backend.spec
@@ -8,7 +8,7 @@ Name: spacewalk-backend
Summary: Common programs needed to be installed on the Spacewalk servers/proxies
Group: Applications/Internet
License: GPLv2
-Version: 0.8.2
+Version: 0.8.3
Release: 1%{?dist}
URL:
https://fedorahosted.org/spacewalk
Source0:
https://fedorahosted.org/releases/s/p/spacewalk/%{name}-%{version}.tar.gz
@@ -598,6 +598,10 @@ rm -f %{rhnconf}/rhnSecret.py*
# $Id$
%changelog
+* Mon Dec 07 2009 Michael Mraka <michael.mraka(a)redhat.com> 0.8.3-1
+- moved code from rhnlib to spacewalk-backend-libs
+- 543509 - do not fail if machine has not uuid set (like qemu)
+
* Fri Dec 4 2009 Miroslav Suchý <msuchy(a)redhat.com> 0.8.2-1
- sha256 support
diff --git a/rel-eng/packages/spacewalk-backend b/rel-eng/packages/spacewalk-backend
index ce9e292..77b6c0e 100644
--- a/rel-eng/packages/spacewalk-backend
+++ b/rel-eng/packages/spacewalk-backend
@@ -1 +1 @@
-0.8.2-1 backend/
+0.8.3-1 backend/
commit 40ea2292cd2cc20ff4414998addbcb606e9f75ac
Author: Michael Mraka <michael.mraka(a)redhat.com>
Date: Mon Dec 7 16:57:43 2009 +0100
updated namespace of common/rhn_rpm
diff --git a/backend/common/rhnRepository.py b/backend/common/rhnRepository.py
index e112c1f..a52edda 100644
--- a/backend/common/rhnRepository.py
+++ b/backend/common/rhnRepository.py
@@ -21,7 +21,7 @@ import string
import cStringIO
from rhn import rpclib
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
# local imports
import rhnFlags
diff --git a/backend/satellite_tools/reposync.py b/backend/satellite_tools/reposync.py
index 7640fcd..8006b08 100644
--- a/backend/satellite_tools/reposync.py
+++ b/backend/satellite_tools/reposync.py
@@ -18,8 +18,8 @@ from optparse import OptionParser
from common import rhnLib
from server import rhnPackage, rhnSQL, rhnChannel, rhnPackageUpload
from common import CFG, initCFG, rhnLog, fetchTraceback
-from rhn.common import rhn_rpm
-from rhn.common.rhn_mpm import InvalidPackageError
+from spacewalk.common import rhn_rpm
+from spacewalk.common.rhn_mpm import InvalidPackageError
from server.importlib.importLib import IncompletePackage
from server.importlib.backendOracle import OracleBackend
from server.importlib.packageImport import ChannelPackageSubscription
diff --git a/backend/satellite_tools/satCerts.py b/backend/satellite_tools/satCerts.py
index daaf741..554023b 100644
--- a/backend/satellite_tools/satCerts.py
+++ b/backend/satellite_tools/satCerts.py
@@ -28,7 +28,7 @@ from server import rhnSQL
from server.rhnServer import satellite_cert
from common.rhnTB import fetchTraceback
from common.rhnConfig import RHNOptions
-from rhn.common.rhn_rpm import getInstalledHeader
+from spacewalk.common.rhn_rpm import getInstalledHeader
#
# RHN certificate section
diff --git a/backend/satellite_tools/satComputePkgHeaders.py
b/backend/satellite_tools/satComputePkgHeaders.py
index 54d1ff7..7751a2d 100644
--- a/backend/satellite_tools/satComputePkgHeaders.py
+++ b/backend/satellite_tools/satComputePkgHeaders.py
@@ -55,7 +55,7 @@ sys.modules["_apache"] = sys.modules["__main__"]
from server import rhnSQL
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
options_table = [
Option("-v", "--verbose", action="count",
diff --git a/backend/satellite_tools/satsync.py b/backend/satellite_tools/satsync.py
index 106468d..4e5112a 100644
--- a/backend/satellite_tools/satsync.py
+++ b/backend/satellite_tools/satsync.py
@@ -31,7 +31,7 @@ from optparse import Option, OptionParser
# __rhn imports__
from common import CFG, initCFG, initLOG, Traceback, rhnMail, \
rhnLib, rhnFlags
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from server import rhnSQL
from server.rhnSQL import SQLError, SQLSchemaError, SQLConnectError
diff --git a/backend/satellite_tools/updatePackages.py
b/backend/satellite_tools/updatePackages.py
index be6c0a5..af57b3f 100644
--- a/backend/satellite_tools/updatePackages.py
+++ b/backend/satellite_tools/updatePackages.py
@@ -26,7 +26,7 @@ sys.path.append('/usr/share/rhn')
from optparse import Option, OptionParser
from common import rhnLib, rhnLog, initLOG, CFG, initCFG
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from server.rhnLib import parseRPMFilename
from server import rhnSQL
from server.rhnServer import server_packages
diff --git a/backend/server/handlers/app/rhn_mpm.py
b/backend/server/handlers/app/rhn_mpm.py
index d1a2859..63d75ea 100644
--- a/backend/server/handlers/app/rhn_mpm.py
+++ b/backend/server/handlers/app/rhn_mpm.py
@@ -63,7 +63,7 @@ def load_rpm(stream, seekable=1):
# Hmm, maybe an rpm
try:
- from rhn.common import rhn_rpm
+ from spacewalk.common import rhn_rpm
except ImportError:
raise InvalidPackageError
diff --git a/backend/server/handlers/applet/applet.py
b/backend/server/handlers/applet/applet.py
index 956ae2f..a485eb3 100644
--- a/backend/server/handlers/applet/applet.py
+++ b/backend/server/handlers/applet/applet.py
@@ -21,7 +21,7 @@ import random
# common modules imports
from common import rhnCache, rhnFlags, log_debug, CFG, rhnFault
from common.rhnTranslate import _
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
# server modules imports
from server import rhnChannel, rhnSQL, rhnHandler, rhnLib
diff --git a/backend/server/handlers/xmlrpc/up2date.py
b/backend/server/handlers/xmlrpc/up2date.py
index 5f09b87..dae8fd6 100644
--- a/backend/server/handlers/xmlrpc/up2date.py
+++ b/backend/server/handlers/xmlrpc/up2date.py
@@ -26,7 +26,7 @@ from types import ListType, TupleType, StringType, IntType
# common module imports
from common import CFG, rhnFlags, rhnFault, log_debug, log_error
from common.rhnTranslate import _
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
# local module imports
from server.rhnLib import computeSignature
diff --git a/backend/server/handlers/xp/rhnlint.py
b/backend/server/handlers/xp/rhnlint.py
index 236da62..b20ff1c 100644
--- a/backend/server/handlers/xp/rhnlint.py
+++ b/backend/server/handlers/xp/rhnlint.py
@@ -19,7 +19,7 @@ import time
import string
from common import RPC_Base, log_debug
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from server import rhnSQL
diff --git a/backend/server/importlib/backend.py b/backend/server/importlib/backend.py
index c3e1b58..1975a86 100644
--- a/backend/server/importlib/backend.py
+++ b/backend/server/importlib/backend.py
@@ -23,7 +23,7 @@ import re
import sys
from common import rhnFault, CFG
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from server import rhnSQL, rhnChannel, taskomatic
from importLib import Diff, Package, IncompletePackage, Erratum, \
AlreadyUploadedError, InvalidPackageError, TransactionError, \
diff --git a/backend/server/importlib/packageUpload.py
b/backend/server/importlib/packageUpload.py
index 1accd58..61c8b5b 100644
--- a/backend/server/importlib/packageUpload.py
+++ b/backend/server/importlib/packageUpload.py
@@ -18,7 +18,7 @@
#
from common import rhnFault, log_debug
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from server import rhnChannel, taskomatic, rhnSQL
from server.importlib.headerSource import createPackage
diff --git a/backend/server/rhnChannel.py b/backend/server/rhnChannel.py
index e8d875f..e38d3ea 100644
--- a/backend/server/rhnChannel.py
+++ b/backend/server/rhnChannel.py
@@ -25,7 +25,7 @@ from types import IntType, ListType, DictType
from common import log_debug, log_error, rhnFault, rhnException, rhnCache, rhnFlags, CFG
from common.rhnTranslate import _
from common.rhnLib import startswith
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from rhnServer import server_lib
from rhnDependency import MakeEvrError
diff --git a/backend/server/rhnPackageUpload.py b/backend/server/rhnPackageUpload.py
index 6161a54..547bbf4 100644
--- a/backend/server/rhnPackageUpload.py
+++ b/backend/server/rhnPackageUpload.py
@@ -19,7 +19,7 @@ import os
import tempfile
from common import CFG, log_debug, rhnFault, rhn_mpm, rhnLib, UserDictCase
-from rhn.common.rhn_rpm import get_header_byte_range
+from spacewalk.common.rhn_rpm import get_header_byte_range
from server import rhnSQL
from server.importlib import importLib, userAuth, mpmSource, backendOracle, \
diff --git a/backend/server/rhnServer/server_class.py
b/backend/server/rhnServer/server_class.py
index dead358..3083b1a 100644
--- a/backend/server/rhnServer/server_class.py
+++ b/backend/server/rhnServer/server_class.py
@@ -23,7 +23,7 @@ import string
from common import rhnException, rhnFault, log_debug, log_error, CFG
from common import rhnFlags
from common.rhnTranslate import _
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
# from the server stuff...
from server import rhnChannel, rhnUser, rhnSQL, rhnLib, rhnAction, \
diff --git a/backend/server/rhnServer/server_packages.py
b/backend/server/rhnServer/server_packages.py
index 2e71f64..327a342 100644
--- a/backend/server/rhnServer/server_packages.py
+++ b/backend/server/rhnServer/server_packages.py
@@ -23,7 +23,7 @@ import time
from types import DictType, TupleType
from common import log_debug, rhnFault
-from rhn.common import rhn_rpm
+from spacewalk.common import rhn_rpm
from server import rhnSQL, rhnLib
from server_lib import snapshot_server, check_entitlement
commit 68c4f75bc0f3cec80c6066f5a6bc0dc4ef6d0d28
Author: Michael Mraka <michael.mraka(a)redhat.com>
Date: Mon Dec 7 16:56:21 2009 +0100
create setup.py to properly setup & install things from backend/spacewalk
diff --git a/backend/setup.py b/backend/setup.py
new file mode 100644
index 0000000..ecb8896
--- /dev/null
+++ b/backend/setup.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+#
+# setup of spacewalk-backend-libs
+#
+
+from distutils.core import setup
+import os
+
+setup(name = os.environ["PYTHON_MODULE_NAME"],
+ version = os.environ["PYTHON_MODULE_VERSION"],
+ description = "Python libraries for the Spacewalk project",
+ long_description = """A collection of python modules used by the
+Spacewalk (
http://spacewalk.redhat.com) software.""",
+ url = 'http://spacewalk.redhat.com',
+ packages = ["spacewalk/common"],
+ license = "GPL",
+ )
diff --git a/backend/spacewalk-backend.spec b/backend/spacewalk-backend.spec
index 4a81558..9ec125a 100644
--- a/backend/spacewalk-backend.spec
+++ b/backend/spacewalk-backend.spec
@@ -2,6 +2,7 @@
%define rhnconf %{_sysconfdir}/rhn
%define httpdconf %{rhnconf}/satellite-httpd/conf
%define apacheconfd %{_sysconfdir}/httpd/conf.d
+%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from
distutils.sysconfig import get_python_lib; print get_python_lib()")}
Name: spacewalk-backend
Summary: Common programs needed to be installed on the Spacewalk servers/proxies
@@ -237,12 +238,18 @@ XXX To be determined if the proper location is under backend
%build
make -f Makefile.backend all
+export PYTHON_MODULE_NAME=%{name}
+export PYTHON_MODULE_VERSION=%{version}
+%{__python} setup.py build
%install
rm -rf $RPM_BUILD_ROOT
install -d $RPM_BUILD_ROOT/%{rhnroot}
make -f Makefile.backend install PREFIX=$RPM_BUILD_ROOT ROOT=%{rhnroot} \
MANDIR=%{_mandir}
+export PYTHON_MODULE_NAME=%{name}
+export PYTHON_MODULE_VERSION=%{version}
+%{__python} setup.py install -O1 --root $RPM_BUILD_ROOT --prefix=%{_prefix}
%clean
rm -rf $RPM_BUILD_ROOT
@@ -455,8 +462,8 @@ rm -f %{rhnconf}/rhnSecret.py*
%files libs
%defattr(-,root,root)
-%dir %{rhnroot}/spacewalk/
-
+%{python_sitelib}/spacewalk/
+%{python_sitelib}/spacewalk*egg-info
%files config-files-common
%defattr(-,root,root)
commit 370ca2d811ffc369839325cc1e9f0ff9fe839915
Author: Michael Mraka <michael.mraka(a)redhat.com>
Date: Mon Dec 7 16:50:25 2009 +0100
moved code from rhnlib to spacewalk-backend-libs
well, one more move of rhn_rpm/rhn_mpm -
this code is shared between server and tools so it's better to put
them into some spacewalk driven repo/package instead of
rhnlib which is part of RHEL/Fedora
diff --git a/backend/spacewalk-backend.spec b/backend/spacewalk-backend.spec
index 0fbf099..4a81558 100644
--- a/backend/spacewalk-backend.spec
+++ b/backend/spacewalk-backend.spec
@@ -16,7 +16,8 @@ BuildArch: noarch
Requires: python, rpm-python
# /etc/rhn is provided by spacewalk-proxy-common or by spacewalk-config
Requires: /etc/rhn
-Requires: rhnlib >= 2.5.16
+Requires: rhnlib >= 1.8
+Requires: %{name}-libs = %{version}-%{release}
BuildRequires: /usr/bin/msgfmt
BuildRequires: /usr/bin/docbook2man
BuildRequires: docbook-utils
@@ -139,6 +140,13 @@ receivers and get them enabled automatically.
This package contains listener for the Server XML dumper.
+%package libs
+Summary: Spacewalk server and client tools libraries
+Group: Applications/Internet
+
+%description libs
+Libraries required by both Spacewalk server and Spacewalk client tools.
+
%package config-files-common
Summary: Common files for the Configuration Management project
Group: Applications/Internet
@@ -445,6 +453,11 @@ rm -f %{rhnconf}/rhnSecret.py*
%attr(640,root,apache) %{rhnconf}/default/rhn_server_satexport_internal.conf
+%files libs
+%defattr(-,root,root)
+%dir %{rhnroot}/spacewalk/
+
+
%files config-files-common
%defattr(-,root,root)
%{rhnroot}/server/configFilesHandler.py*
diff --git a/backend/spacewalk/common/rhn_mpm.py b/backend/spacewalk/common/rhn_mpm.py
new file mode 100644
index 0000000..0d339d8
--- /dev/null
+++ b/backend/spacewalk/common/rhn_mpm.py
@@ -0,0 +1,283 @@
+#
+# Copyright (c) 2008 Red Hat, Inc.
+#
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+#
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# Red Hat trademarks are not licensed under GPLv2. No permission is
+# granted to use or replicate Red Hat trademarks that are incorporated
+# in this software or its documentation.
+#
+
+import os
+import gzip
+import cStringIO
+import tempfile
+from rhn.rpclib import xmlrpclib
+
+import struct
+
+from types import ListType, TupleType, DictType
+
+def labelCompare(l1, l2):
+ try:
+ import rhn_rpm
+ except ImportError:
+ # rhn_rpm not avalable; return a dummy comparison function
+ return -1
+ return rhn_rpm.labelCompare(l1, l2)
+
+def get_package_header(filename=None, file=None, fd=None):
+ return load(filename=filename, file=file, fd=fd)[0]
+
+# Loads an MPM and returns its header and its payload
+def load(filename=None, file=None, fd=None):
+ if (filename is None and file is None and fd is None):
+ raise ValueError, "No parameters passed"
+
+ if filename is not None:
+ f = open(filename)
+ elif file is not None:
+ f = file
+ else: # fd is not None
+ f = os.fdopen(os.dup(fd), "r")
+
+ f.seek(0, 0)
+
+ p = MPM_Package()
+ try:
+ p.load(f)
+ except InvalidPackageError, e:
+ try:
+ return load_rpm(f)
+ except InvalidPackageError:
+ raise e
+
+ return p.header, p.payload_stream
+
+def load_rpm(stream):
+ # Hmm, maybe an rpm
+
+ try:
+ import rhn_rpm
+ except ImportError:
+ raise InvalidPackageError
+
+ # Dup the file descriptor, we don't want it to get closed before we read
+ # the payload
+ newfd = os.dup(stream.fileno())
+ stream = os.fdopen(newfd, "r")
+
+ stream.flush()
+ stream.seek(0, 0)
+
+ try:
+ header = rhn_rpm.get_package_header(file=stream)
+ except rhn_rpm.InvalidPackageError, e:
+ raise apply(InvalidPackageError, e.args)
+ except rhn_rpm.error, e:
+ raise InvalidPackageError(e)
+ stream.seek(0, 0)
+
+ return header, stream
+
+class MPM_Header:
+ "Wrapper class for an mpm header - we need to store a flag is_source"
+ def __init__(self, hdr):
+ self.hdr = hdr
+ self.is_source = hdr.get('is_source')
+ self.packaging = 'mpm'
+ self.signatures = []
+
+ def __getitem__(self, name):
+ return self.hdr.get(name)
+
+ def __setitem__(self, name, item):
+ self.hdr[name] = item
+
+ def __delitem__(self, name):
+ del self.hdr[name]
+
+ def __getattr__(self, name):
+ return getattr(self.hdr, name)
+
+ def is_signed(self):
+ return 0
+
+class InvalidPackageError(Exception):
+ pass
+
+MPM_HEADER_COMPRESSED_GZIP = 1
+MPM_PAYLOAD_COMPRESSED_GZIP = 1
+
+class MPM_Package:
+ _lead_format = '!16sB3s4L92s'
+ _magic = 'mpmpackage012345'
+ def __init__(self):
+ self.header = None
+ self.payload_stream = None
+ self.header_flags = MPM_HEADER_COMPRESSED_GZIP
+ self.payload_flags = 0
+ assert(len(self._magic) == 16)
+ self._buffer_size = 16384
+
+ def _read_lead(self, stream):
+ # Lead has the following format:
+ # 16 bytes magic
+ # 1 bytes version
+ # 3 bytes unused
+ # 4 bytes header flags
+ # 4 bytes payload flags
+ # 4 bytes header length
+ # 4 bytes payload length
+ # 92 bytes padding to 128 bytes
+ lead = self._read_bytes(stream, 128)
+ if len(lead) != 128:
+ raise InvalidPackageError()
+
+ arr = struct.unpack(self._lead_format, lead)
+ return arr
+
+ def load(self, input_stream):
+ # Clean up
+ self.__init__()
+ arr = self._read_lead(input_stream)
+ magic = arr[0]
+ if magic != self._magic:
+ raise InvalidPackageError()
+ header_len, payload_len = int(arr[5]), int(arr[6])
+ header_flags, payload_flags = arr[3], arr[4]
+ file_size = 128 + header_len + payload_len
+ input_stream.seek(file_size)
+ if file_size != input_stream.tell():
+ raise InvalidPackageError()
+ # Read the header
+ input_stream.seek(128, 0)
+ header_data = self._read_bytes(input_stream, header_len)
+ payload_stream = tempfile.TemporaryFile()
+ self.stream_copy(input_stream, payload_stream)
+
+ self._read_header(header_data, header_flags)
+ self._read_payload(payload_stream, payload_flags)
+
+ def _read_bytes(self, stream, amt):
+ ret = ""
+ while amt:
+ buf = stream.read(min(amt, self._buffer_size))
+ if not buf:
+ return ret
+ ret = ret + buf
+ amt = amt - len(buf)
+ return ret
+
+ def _read_header(self, header_data, header_flags):
+ if header_flags & MPM_HEADER_COMPRESSED_GZIP:
+ t = cStringIO.StringIO(header_data)
+ g = gzip.GzipFile(None, "r", 0, t)
+ header_data = g.read()
+ g.close()
+ t.close()
+
+ try:
+ params, foo = xmlrpclib.loads(header_data)
+ except:
+ # XXX
+ raise
+
+ self.header = MPM_Header(params[0])
+
+ def _read_payload(self, payload_stream, payload_flags):
+ payload_stream.seek(0, 0)
+ if payload_flags & MPM_PAYLOAD_COMPRESSED_GZIP:
+ g = gzip.GzipFile(None, "r", 0, payload_stream)
+ t = tempfile.TemporaryFile()
+ self.stream_copy(g, t)
+ g.close()
+ payload_stream = t
+
+ self.payload_stream = payload_stream
+
+ def write(self, output_stream):
+ if self.header is None:
+ raise Exception()
+
+ header_stream, header_size = self._encode_header()
+ payload_stream, payload_size = self._encode_payload()
+
+ lead_arr = (self._magic, 1, "\0" * 3, self.header_flags,
+ self.payload_flags, header_size, payload_size, '\0' * 92)
+ # lead
+ lead = apply(struct.pack, (self._lead_format, ) + lead_arr)
+ output_stream.write(lead)
+ self.stream_copy(header_stream, output_stream)
+ self.stream_copy(payload_stream, output_stream)
+
+ def add_header_flag(self, flag):
+ self.header_flags = self.header_flags | flag
+
+ def add_payload_flag(self, flag):
+ self.payload_flags = self.payload_flags | flag
+
+ def reset_header_flags(self):
+ self.header_flags = 0
+
+ def reset_payload_flags(self):
+ self.payload_flags = 0
+
+ def _encode_header(self):
+ assert(self.header is not None)
+ stream = tempfile.TemporaryFile()
+ data = xmlrpclib.dumps((_replace_null(self.header), ))
+ if self.header_flags & MPM_HEADER_COMPRESSED_GZIP:
+ f = gzip.GzipFile(None, "wb", 9, stream)
+ f.write(data)
+ f.close()
+ else:
+ stream.write(data)
+ stream.flush()
+ stream.seek(0, 2)
+ size = stream.tell()
+ stream.seek(0, 0)
+ return stream, size
+
+ def _encode_payload(self):
+ assert(self.payload_stream is not None)
+ stream = tempfile.TemporaryFile()
+ if self.payload_flags & MPM_PAYLOAD_COMPRESSED_GZIP:
+ f = gzip.GzipFile(None, "wb", 9, stream)
+ self.stream_copy(self.payload_stream, f)
+ f.close()
+ else:
+ stream = self.payload_stream
+ stream.flush()
+ stream.seek(0, 2)
+ size = stream.tell()
+ stream.seek(0, 0)
+ return stream, size
+
+ def stream_copy(self, source, dest):
+ "Copies data from the source stream to the destination stream"
+ while 1:
+ buf = source.read(self._buffer_size)
+ if not buf:
+ break
+ dest.write(buf)
+
+
+def _replace_null(obj):
+ if obj is None:
+ return ''
+ if isinstance(obj, ListType):
+ return map(_replace_null, obj)
+ if isinstance(obj, TupleType):
+ return tuple(_replace_null(list(obj)))
+ if hasattr(obj, 'items'):
+ dict = {}
+ for k, v in obj.items():
+ dict[_replace_null(k)] = _replace_null(v)
+ return dict
+ return obj
diff --git a/backend/spacewalk/common/rhn_rpm.py b/backend/spacewalk/common/rhn_rpm.py
new file mode 100644
index 0000000..349388a
--- /dev/null
+++ b/backend/spacewalk/common/rhn_rpm.py
@@ -0,0 +1,462 @@
+#
+# Copyright (c) 2008 Red Hat, Inc.
+#
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+#
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# Red Hat trademarks are not licensed under GPLv2. No permission is
+# granted to use or replicate Red Hat trademarks that are incorporated
+# in this software or its documentation.
+#
+
+import os
+import sys
+import rpm
+import struct
+
+import exceptions
+if not hasattr(exceptions, 'StopIteration'):
+ # Presumably python 1.5.2
+ class StopIteration(Exception):
+ pass
+
+# Expose a bunch of useful constants from rpm
+error = rpm.error
+for sym, val in rpm.__dict__.items():
+ if sym[:3] == 'RPM':
+ # A constant, probably - import it into our namespace
+ globals()[sym] = val
+del sym, val
+
+# need this for rpm-pyhon < 4.6 (e.g. on RHEL5)
+rpm.RPMTAG_FILEDIGESTALGO = 5011
+
+# these values are taken from /usr/include/rpm/rpmpgp.h
+# PGPHASHALGO_MD5 = 1, /*!< MD5 */
+# PGPHASHALGO_SHA1 = 2, /*!< SHA1 */
+# PGPHASHALGO_RIPEMD160 = 3, /*!< RIPEMD160 */
+# PGPHASHALGO_MD2 = 5, /*!< MD2 */
+# PGPHASHALGO_TIGER192 = 6, /*!< TIGER192 */
+# PGPHASHALGO_HAVAL_5_160 = 7, /*!< HAVAL-5-160 */
+# PGPHASHALGO_SHA256 = 8, /*!< SHA256 */
+# PGPHASHALGO_SHA384 = 9, /*!< SHA384 */
+# PGPHASHALGO_SHA512 = 10, /*!< SHA512 */
+PGPHASHALGO = {
+ 1: 'md5',
+ 2: 'sha1',
+ 3: 'ripemd160',
+ 5: 'md2',
+ 6: 'tiger192',
+ 7: 'haval-5-160',
+ 8: 'sha256',
+ 9: 'sha384',
+ 10: 'sha512',
+}
+
+
+class InvalidPackageError(Exception):
+ pass
+
+# wrapper/proxy class for rpm.Transaction so we can
+# instrument it, etc easily
+class RPMTransaction:
+ read_only = 0
+ def __init__(self):
+ if hasattr(rpm, 'opendb'):
+ db = getattr(rpm, 'opendb')(not self.read_only)
+ self.ts = rpm.TransactionSet('/', db)
+ else:
+ self.ts = rpm.TransactionSet()
+ self.tsflags = []
+ # For rpm 4.0.4
+ self._flags = 0
+ self._prob_filter = 0
+
+ def __getattr__(self, attr):
+ return getattr(self.ts, attr)
+
+ def getMethod(self, method):
+ # in theory, we can override this with
+ # profile/etc info
+ return getattr(self.ts, method)
+
+ # push/pop methods so we don't lose the previous
+ # set value, and we can potentially debug a bit
+ # easier
+ def pushVSFlags(self, flags):
+ self.tsflags.append(flags)
+ if hasattr(self.ts, 'setVSFlags'):
+ f = getattr(self.ts, 'setVSFlags')
+ f(self.tsflags[-1])
+
+ def popVSFlags(self):
+ del self.tsflags[-1]
+ if hasattr(self.ts, 'setVSFlags'):
+ f = getattr(self.ts, 'setVSFlags')
+ f(self.tsflags[-1])
+
+ def addInstall(self, arg1, arg2, mode):
+ """Install a package"""
+ hdr = arg1.hdr
+ if hasattr(self.ts, 'addInstall'):
+ f = getattr(self.ts, 'addInstall')
+ return f(hdr, arg2, mode)
+ return self.ts.add(hdr, arg2, mode)
+
+ def addErase(self, arg1):
+ """Erase a package"""
+ hdr = arg1.hdr
+ if hasattr(self.ts, 'addErase'):
+ f = getattr(self.ts, 'addErase')
+ return f(hdr)
+ return self.ts.add(hdr, hdr, "e")
+
+ def check(self):
+ """Check dependencies"""
+ if hasattr(self.ts, 'check'):
+ f = getattr(self.ts, 'check')
+ else:
+ f = getattr(self.ts, 'depcheck')
+ return f()
+
+ def setFlags(self, flag):
+ """Set transaction flags"""
+ if hasattr(rpm, 'headerFromPackage'):
+ # Old style rpm
+ old_flags = self._flags
+ self._flags = flag
+ return old_flags
+ return self.ts.setFlags(flag)
+
+ def setProbFilter(self, flag):
+ """Set problem flags"""
+ if hasattr(rpm, 'headerFromPackage'):
+ # Old style rpm
+ old_flags = self._prob_filter
+ self._prob_filter = flag
+ return old_flags
+ return self.ts.setProbFilter(flag)
+
+ def run(self, callback, user_data):
+ if hasattr(rpm, 'headerFromPackage'):
+ # Old style rpm
+ return self.ts.run(self._flags, self._prob_filter, callback,
+ user_data)
+ return self.ts.run(callback, user_data)
+
+
+
+
+class SharedStateTransaction:
+ _shared_state = {}
+
+ def __init__(self):
+ self.__dict__ = self._shared_state
+
+class RPMReadOnlyTransaction(SharedStateTransaction, RPMTransaction):
+ read_only = 1
+ def __init__(self):
+ SharedStateTransaction.__init__(self)
+ if not hasattr(self, 'ts'):
+ RPMTransaction.__init__(self)
+ # FIXME: replace with macro defination
+ self.pushVSFlags(8)
+
+class RPM_Header:
+ "Wrapper class for an rpm header - we need to store a flag is_source"
+ def __init__(self, hdr, is_source=None):
+ self.hdr = hdr
+ self.is_source = is_source
+ self.packaging = 'rpm'
+ self.signatures = []
+ self._extract_signatures()
+
+ def __getitem__(self, name):
+ return self.hdr[name]
+
+ def __getattr__(self, name):
+ return getattr(self.hdr, name)
+
+ def checksum_type(self):
+ if self.hdr[rpm.RPMTAG_FILEDIGESTALGO] \
+ and PGPHASHALGO.has_key(self.hdr[rpm.RPMTAG_FILEDIGESTALGO]):
+ checksum_type = PGPHASHALGO[self.hdr[rpm.RPMTAG_FILEDIGESTALGO]]
+ else:
+ checksum_type = 'md5'
+ return checksum_type
+
+ def is_signed(self):
+ if hasattr(rpm, "RPMTAG_DSAHEADER"):
+ dsaheader = self.hdr["dsaheader"]
+ else:
+ dsaheader = 0
+ if self.hdr["siggpg"] or self.hdr["sigpgp"] or dsaheader:
+ return 1
+ return 0
+
+ def _extract_signatures(self):
+ header_tags = [
+ [rpm.RPMTAG_DSAHEADER, "dsa"],
+ [rpm.RPMTAG_RSAHEADER, "rsa"],
+ [rpm.RPMTAG_SIGGPG, "gpg"],
+ [rpm.RPMTAG_SIGPGP, 'pgp'],
+ ]
+ for ht, sig_type in header_tags:
+ ret = self.hdr[ht]
+ if not ret or len(ret) < 17:
+ continue
+ # Get the key id - hopefully we get it right
+ key_id = ret[9:17]
+ key_id_len = len(key_id)
+ format = "%dB" % key_id_len
+ t = struct.unpack(format, key_id)
+ format = "%02x" * key_id_len
+ key_id = format % t
+ self.signatures.append({
+ 'signature_type' : sig_type,
+ 'key_id' : key_id,
+ 'signature' : ret,
+ })
+
+def get_header_byte_range(package_file):
+ """
+ Return the start and end bytes of the rpm header object.
+
+ For details of the rpm file format, see:
+
http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html
+ """
+
+ lead_size = 96
+
+ # Move past the rpm lead
+ package_file.seek(lead_size)
+
+ sig_size = get_header_struct_size(package_file)
+
+ # Now we can find the start of the actual header.
+ header_start = lead_size + sig_size
+
+ package_file.seek(header_start)
+
+ header_size = get_header_struct_size(package_file)
+
+ header_end = header_start + header_size
+
+ return (header_start, header_end)
+
+def get_header_struct_size(package_file):
+ """
+ Compute the size in bytes of the rpm header struct starting at the current
+ position in package_file.
+ """
+ # Move past the header preamble
+ package_file.seek(8, 1)
+
+ # Read the number of index entries
+ header_index = package_file.read(4)
+ (header_index_value, ) = struct.unpack('>I', header_index)
+
+ # Read the the size of the header data store
+ header_store = package_file.read(4)
+ (header_store_value, ) = struct.unpack('>I', header_store)
+
+ # The total size of the header. Each index entry is 16 bytes long.
+ header_size = 8 + 4 + 4 + header_index_value * 16 + header_store_value
+
+ # Headers end on an 8-byte boundary. Round out the extra data.
+ round_out = header_size % 8
+ if round_out != 0:
+ header_size = header_size + (8 - round_out)
+
+ return header_size
+
+# Loads the package header from a file / stream / file descriptor
+# Raises rpm.error if an error is found, or InvalidPacageError if package is
+# busted
+# XXX Deal with exceptions better
+def get_package_header(filename=None, file=None, fd=None):
+ if (filename is None and file is None and fd is None):
+ raise ValueError, "No parameters passed"
+
+ if filename is not None:
+ f = open(filename)
+ elif file is not None:
+ f = file
+ f.seek(0, 0)
+ else: # fd is not None
+ f = None
+
+ if f is None:
+ os.lseek(fd, 0, 0)
+ file_desc = fd
+ else:
+ file_desc = f.fileno()
+
+ if hasattr(rpm, 'headerFromPackage'):
+ hdr, is_source = rpm.headerFromPackage(file_desc)
+ if hdr is None:
+ raise InvalidPackageError
+ else:
+ if hasattr(rpm, 'readHeaderFromFD'):
+ header_start, header_end = \
+ get_header_byte_range(os.fdopen(os.dup(file_desc)))
+ os.lseek(file_desc, header_start, 0)
+ hdr, offset = rpm.readHeaderFromFD(file_desc)
+ else:
+ # RHEL-4 and older, do the old way
+ ts = RPMReadOnlyTransaction()
+ nomd5 = getattr(rpm, 'RPMVSF_NOMD5')
+ needpayload = getattr(rpm, 'RPMVSF_NEEDPAYLOAD')
+ ts.pushVSFlags(~(nomd5 | needpayload))
+ hdr = RPMReadOnlyTransaction().hdrFromFdno(file_desc)
+ ts.popVSFlags()
+ if hdr is None:
+ raise InvalidPackageError
+ is_source = hdr[getattr(rpm, 'RPMTAG_SOURCEPACKAGE')]
+
+ return RPM_Header(hdr, is_source)
+
+class MatchIterator:
+ def __init__(self, tag_name=None, value=None):
+ # Query by name, by default
+ if not tag_name:
+ tag_name = "name"
+
+ if hasattr(rpm, "headerFromPackage"):
+ # rpm 4.0.4 or earlier
+ self.db = rpm.opendb()
+ method = self.db.match
+ else:
+ # rpm 4.1 or later
+ self.ts = rpm.TransactionSet()
+ self.ts.setVSFlags(8)
+ method = self.ts.dbMatch
+
+ if value:
+ self.mi = method(tag_name, value)
+ else:
+ self.mi = method(tag_name)
+
+ def pattern(self, tag_name, mode, pattern):
+ self.mi.pattern(tag_name, mode, pattern)
+
+ def next(self):
+ try:
+ hdr = self.mi.next()
+ except StopIteration:
+ hdr = None
+
+ if hdr is None:
+ return None
+ if hasattr(rpm, "headerFromPackage"):
+ is_source = not hdr[rpm.RPMTAG_SOURCERPM]
+ else:
+ is_source = hdr[getattr(rpm, 'RPMTAG_SOURCEPACKAGE')]
+ return RPM_Header(hdr, is_source)
+
+
+def headerLoad(data):
+ hdr = rpm.headerLoad(data)
+ if hasattr(rpm, "headerFromPackage"):
+ is_source = not hdr[rpm.RPMTAG_SOURCERPM]
+ else:
+ is_source = hdr[getattr(rpm, 'RPMTAG_SOURCEPACKAGE')]
+ return RPM_Header(hdr, is_source)
+
+def labelCompare(t1, t2):
+ return rpm.labelCompare(t1, t2)
+
+def nvre_compare(t1, t2):
+ def build_evr(p):
+ evr = [p[3], p[1], p[2]]
+ evr = map(str, evr)
+ if evr[0] == "":
+ evr[0] = None
+ return evr
+ if t1[0] != t2[0]:
+ raise ValueError("You should only compare packages with the same
name")
+ evr1, evr2 = (build_evr(t1), build_evr(t2))
+ return rpm.labelCompare(evr1, evr2)
+
+
+def hdrLabelCompare(hdr1, hdr2):
+ """ take two RPMs or headers and compare them for order
"""
+
+ if hdr1['name'] == hdr2['name']:
+ hdr1 = [hdr1['epoch'] or None, hdr1['version'],
hdr1['release']]
+ hdr2 = [hdr2['epoch'] or None, hdr2['version'],
hdr2['release']]
+ if hdr1[0]:
+ hdr1[0] = str(hdr1[0])
+ if hdr2[0]:
+ hdr2[0] = str(hdr2[0])
+ return rpm.labelCompare(hdr1, hdr2)
+ elif hdr1['name'] < hdr2['name']:
+ return -1
+ return 1
+
+
+def rpmLabelCompare(rpmFilename1, rpmFilename2):
+ """ take two RPMs and compare them for order """
+ return hdrLabelCompare(get_package_header(rpmFilename1),
+ get_package_header(rpmFilename2))
+
+
+def sortHeaders(hdrs):
+ """ Sorts a list of RPM headers (or RPMs).
+ Assertion: they *must* exist.
+ """
+
+ assert isinstance(hdrs, type([]))
+
+ sorted = hdrs[:]
+ sorted.sort(hdrLabelCompare)
+ return sorted
+
+
+def sortRPMs(rpms):
+ """ Sorts a list of RPM files. They *must* exist. """
+
+ assert isinstance(rpms, type([]))
+
+ # We don't want to use rpmLabelCompare as a sorting mechanism, it would
+ # extract the rpm header for each comparison.
+ # Build a list of (header, rpm)
+ helper = map(lambda x: (get_package_header(x), x), rpms)
+
+ # Sort the list using the headers as a comparison
+ helper.sort(lambda x, y: hdrLabelCompare(x[0], y[0]))
+
+ # Extract the rpm names now
+ return map(lambda x: x[1], helper)
+
+
+def getInstalledHeader(rpmName):
+ """ quieries the RPM DB for a header matching rpmName.
"""
+
+ mi = MatchIterator("name")
+ mi.pattern("name", rpm.RPMMIRE_STRCMP, rpmName)
+ return mi.next()
+
+
+if __name__ == '__main__':
+ mi = MatchIterator("name")
+ mi.pattern("name", rpm.RPMMIRE_GLOB, "*ker*")
+ while 1:
+ h = mi.next()
+ if not h:
+ break
+ print h['name']
+ sys.exit(1)
+ hdr = get_package_header(filename="/tmp/python-1.5.2-42.72.i386.rpm")
+ print dir(hdr)
+ # Sources
+ hdr = get_package_header(filename="/tmp/python-1.5.2-42.72.src.rpm")
+ hdr2 = headerLoad(hdr.unload())
+ print hdr2
+ print len(hdr2.keys())
+
+
diff --git a/client/rhel/rhnlib/rhn/common/rhn_mpm.py
b/client/rhel/rhnlib/rhn/common/rhn_mpm.py
deleted file mode 100644
index 0d339d8..0000000
--- a/client/rhel/rhnlib/rhn/common/rhn_mpm.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#
-# Copyright (c) 2008 Red Hat, Inc.
-#
-# This software is licensed to you under the GNU General Public License,
-# version 2 (GPLv2). There is NO WARRANTY for this software, express or
-# implied, including the implied warranties of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
-# along with this software; if not, see
-#
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
-#
-# Red Hat trademarks are not licensed under GPLv2. No permission is
-# granted to use or replicate Red Hat trademarks that are incorporated
-# in this software or its documentation.
-#
-
-import os
-import gzip
-import cStringIO
-import tempfile
-from rhn.rpclib import xmlrpclib
-
-import struct
-
-from types import ListType, TupleType, DictType
-
-def labelCompare(l1, l2):
- try:
- import rhn_rpm
- except ImportError:
- # rhn_rpm not avalable; return a dummy comparison function
- return -1
- return rhn_rpm.labelCompare(l1, l2)
-
-def get_package_header(filename=None, file=None, fd=None):
- return load(filename=filename, file=file, fd=fd)[0]
-
-# Loads an MPM and returns its header and its payload
-def load(filename=None, file=None, fd=None):
- if (filename is None and file is None and fd is None):
- raise ValueError, "No parameters passed"
-
- if filename is not None:
- f = open(filename)
- elif file is not None:
- f = file
- else: # fd is not None
- f = os.fdopen(os.dup(fd), "r")
-
- f.seek(0, 0)
-
- p = MPM_Package()
- try:
- p.load(f)
- except InvalidPackageError, e:
- try:
- return load_rpm(f)
- except InvalidPackageError:
- raise e
-
- return p.header, p.payload_stream
-
-def load_rpm(stream):
- # Hmm, maybe an rpm
-
- try:
- import rhn_rpm
- except ImportError:
- raise InvalidPackageError
-
- # Dup the file descriptor, we don't want it to get closed before we read
- # the payload
- newfd = os.dup(stream.fileno())
- stream = os.fdopen(newfd, "r")
-
- stream.flush()
- stream.seek(0, 0)
-
- try:
- header = rhn_rpm.get_package_header(file=stream)
- except rhn_rpm.InvalidPackageError, e:
- raise apply(InvalidPackageError, e.args)
- except rhn_rpm.error, e:
- raise InvalidPackageError(e)
- stream.seek(0, 0)
-
- return header, stream
-
-class MPM_Header:
- "Wrapper class for an mpm header - we need to store a flag is_source"
- def __init__(self, hdr):
- self.hdr = hdr
- self.is_source = hdr.get('is_source')
- self.packaging = 'mpm'
- self.signatures = []
-
- def __getitem__(self, name):
- return self.hdr.get(name)
-
- def __setitem__(self, name, item):
- self.hdr[name] = item
-
- def __delitem__(self, name):
- del self.hdr[name]
-
- def __getattr__(self, name):
- return getattr(self.hdr, name)
-
- def is_signed(self):
- return 0
-
-class InvalidPackageError(Exception):
- pass
-
-MPM_HEADER_COMPRESSED_GZIP = 1
-MPM_PAYLOAD_COMPRESSED_GZIP = 1
-
-class MPM_Package:
- _lead_format = '!16sB3s4L92s'
- _magic = 'mpmpackage012345'
- def __init__(self):
- self.header = None
- self.payload_stream = None
- self.header_flags = MPM_HEADER_COMPRESSED_GZIP
- self.payload_flags = 0
- assert(len(self._magic) == 16)
- self._buffer_size = 16384
-
- def _read_lead(self, stream):
- # Lead has the following format:
- # 16 bytes magic
- # 1 bytes version
- # 3 bytes unused
- # 4 bytes header flags
- # 4 bytes payload flags
- # 4 bytes header length
- # 4 bytes payload length
- # 92 bytes padding to 128 bytes
- lead = self._read_bytes(stream, 128)
- if len(lead) != 128:
- raise InvalidPackageError()
-
- arr = struct.unpack(self._lead_format, lead)
- return arr
-
- def load(self, input_stream):
- # Clean up
- self.__init__()
- arr = self._read_lead(input_stream)
- magic = arr[0]
- if magic != self._magic:
- raise InvalidPackageError()
- header_len, payload_len = int(arr[5]), int(arr[6])
- header_flags, payload_flags = arr[3], arr[4]
- file_size = 128 + header_len + payload_len
- input_stream.seek(file_size)
- if file_size != input_stream.tell():
- raise InvalidPackageError()
- # Read the header
- input_stream.seek(128, 0)
- header_data = self._read_bytes(input_stream, header_len)
- payload_stream = tempfile.TemporaryFile()
- self.stream_copy(input_stream, payload_stream)
-
- self._read_header(header_data, header_flags)
- self._read_payload(payload_stream, payload_flags)
-
- def _read_bytes(self, stream, amt):
- ret = ""
- while amt:
- buf = stream.read(min(amt, self._buffer_size))
- if not buf:
- return ret
- ret = ret + buf
- amt = amt - len(buf)
- return ret
-
- def _read_header(self, header_data, header_flags):
- if header_flags & MPM_HEADER_COMPRESSED_GZIP:
- t = cStringIO.StringIO(header_data)
- g = gzip.GzipFile(None, "r", 0, t)
- header_data = g.read()
- g.close()
- t.close()
-
- try:
- params, foo = xmlrpclib.loads(header_data)
- except:
- # XXX
- raise
-
- self.header = MPM_Header(params[0])
-
- def _read_payload(self, payload_stream, payload_flags):
- payload_stream.seek(0, 0)
- if payload_flags & MPM_PAYLOAD_COMPRESSED_GZIP:
- g = gzip.GzipFile(None, "r", 0, payload_stream)
- t = tempfile.TemporaryFile()
- self.stream_copy(g, t)
- g.close()
- payload_stream = t
-
- self.payload_stream = payload_stream
-
- def write(self, output_stream):
- if self.header is None:
- raise Exception()
-
- header_stream, header_size = self._encode_header()
- payload_stream, payload_size = self._encode_payload()
-
- lead_arr = (self._magic, 1, "\0" * 3, self.header_flags,
- self.payload_flags, header_size, payload_size, '\0' * 92)
- # lead
- lead = apply(struct.pack, (self._lead_format, ) + lead_arr)
- output_stream.write(lead)
- self.stream_copy(header_stream, output_stream)
- self.stream_copy(payload_stream, output_stream)
-
- def add_header_flag(self, flag):
- self.header_flags = self.header_flags | flag
-
- def add_payload_flag(self, flag):
- self.payload_flags = self.payload_flags | flag
-
- def reset_header_flags(self):
- self.header_flags = 0
-
- def reset_payload_flags(self):
- self.payload_flags = 0
-
- def _encode_header(self):
- assert(self.header is not None)
- stream = tempfile.TemporaryFile()
- data = xmlrpclib.dumps((_replace_null(self.header), ))
- if self.header_flags & MPM_HEADER_COMPRESSED_GZIP:
- f = gzip.GzipFile(None, "wb", 9, stream)
- f.write(data)
- f.close()
- else:
- stream.write(data)
- stream.flush()
- stream.seek(0, 2)
- size = stream.tell()
- stream.seek(0, 0)
- return stream, size
-
- def _encode_payload(self):
- assert(self.payload_stream is not None)
- stream = tempfile.TemporaryFile()
- if self.payload_flags & MPM_PAYLOAD_COMPRESSED_GZIP:
- f = gzip.GzipFile(None, "wb", 9, stream)
- self.stream_copy(self.payload_stream, f)
- f.close()
- else:
- stream = self.payload_stream
- stream.flush()
- stream.seek(0, 2)
- size = stream.tell()
- stream.seek(0, 0)
- return stream, size
-
- def stream_copy(self, source, dest):
- "Copies data from the source stream to the destination stream"
- while 1:
- buf = source.read(self._buffer_size)
- if not buf:
- break
- dest.write(buf)
-
-
-def _replace_null(obj):
- if obj is None:
- return ''
- if isinstance(obj, ListType):
- return map(_replace_null, obj)
- if isinstance(obj, TupleType):
- return tuple(_replace_null(list(obj)))
- if hasattr(obj, 'items'):
- dict = {}
- for k, v in obj.items():
- dict[_replace_null(k)] = _replace_null(v)
- return dict
- return obj
diff --git a/client/rhel/rhnlib/rhn/common/rhn_rpm.py
b/client/rhel/rhnlib/rhn/common/rhn_rpm.py
deleted file mode 100644
index 349388a..0000000
--- a/client/rhel/rhnlib/rhn/common/rhn_rpm.py
+++ /dev/null
@@ -1,462 +0,0 @@
-#
-# Copyright (c) 2008 Red Hat, Inc.
-#
-# This software is licensed to you under the GNU General Public License,
-# version 2 (GPLv2). There is NO WARRANTY for this software, express or
-# implied, including the implied warranties of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
-# along with this software; if not, see
-#
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
-#
-# Red Hat trademarks are not licensed under GPLv2. No permission is
-# granted to use or replicate Red Hat trademarks that are incorporated
-# in this software or its documentation.
-#
-
-import os
-import sys
-import rpm
-import struct
-
-import exceptions
-if not hasattr(exceptions, 'StopIteration'):
- # Presumably python 1.5.2
- class StopIteration(Exception):
- pass
-
-# Expose a bunch of useful constants from rpm
-error = rpm.error
-for sym, val in rpm.__dict__.items():
- if sym[:3] == 'RPM':
- # A constant, probably - import it into our namespace
- globals()[sym] = val
-del sym, val
-
-# need this for rpm-pyhon < 4.6 (e.g. on RHEL5)
-rpm.RPMTAG_FILEDIGESTALGO = 5011
-
-# these values are taken from /usr/include/rpm/rpmpgp.h
-# PGPHASHALGO_MD5 = 1, /*!< MD5 */
-# PGPHASHALGO_SHA1 = 2, /*!< SHA1 */
-# PGPHASHALGO_RIPEMD160 = 3, /*!< RIPEMD160 */
-# PGPHASHALGO_MD2 = 5, /*!< MD2 */
-# PGPHASHALGO_TIGER192 = 6, /*!< TIGER192 */
-# PGPHASHALGO_HAVAL_5_160 = 7, /*!< HAVAL-5-160 */
-# PGPHASHALGO_SHA256 = 8, /*!< SHA256 */
-# PGPHASHALGO_SHA384 = 9, /*!< SHA384 */
-# PGPHASHALGO_SHA512 = 10, /*!< SHA512 */
-PGPHASHALGO = {
- 1: 'md5',
- 2: 'sha1',
- 3: 'ripemd160',
- 5: 'md2',
- 6: 'tiger192',
- 7: 'haval-5-160',
- 8: 'sha256',
- 9: 'sha384',
- 10: 'sha512',
-}
-
-
-class InvalidPackageError(Exception):
- pass
-
-# wrapper/proxy class for rpm.Transaction so we can
-# instrument it, etc easily
-class RPMTransaction:
- read_only = 0
- def __init__(self):
- if hasattr(rpm, 'opendb'):
- db = getattr(rpm, 'opendb')(not self.read_only)
- self.ts = rpm.TransactionSet('/', db)
- else:
- self.ts = rpm.TransactionSet()
- self.tsflags = []
- # For rpm 4.0.4
- self._flags = 0
- self._prob_filter = 0
-
- def __getattr__(self, attr):
- return getattr(self.ts, attr)
-
- def getMethod(self, method):
- # in theory, we can override this with
- # profile/etc info
- return getattr(self.ts, method)
-
- # push/pop methods so we don't lose the previous
- # set value, and we can potentially debug a bit
- # easier
- def pushVSFlags(self, flags):
- self.tsflags.append(flags)
- if hasattr(self.ts, 'setVSFlags'):
- f = getattr(self.ts, 'setVSFlags')
- f(self.tsflags[-1])
-
- def popVSFlags(self):
- del self.tsflags[-1]
- if hasattr(self.ts, 'setVSFlags'):
- f = getattr(self.ts, 'setVSFlags')
- f(self.tsflags[-1])
-
- def addInstall(self, arg1, arg2, mode):
- """Install a package"""
- hdr = arg1.hdr
- if hasattr(self.ts, 'addInstall'):
- f = getattr(self.ts, 'addInstall')
- return f(hdr, arg2, mode)
- return self.ts.add(hdr, arg2, mode)
-
- def addErase(self, arg1):
- """Erase a package"""
- hdr = arg1.hdr
- if hasattr(self.ts, 'addErase'):
- f = getattr(self.ts, 'addErase')
- return f(hdr)
- return self.ts.add(hdr, hdr, "e")
-
- def check(self):
- """Check dependencies"""
- if hasattr(self.ts, 'check'):
- f = getattr(self.ts, 'check')
- else:
- f = getattr(self.ts, 'depcheck')
- return f()
-
- def setFlags(self, flag):
- """Set transaction flags"""
- if hasattr(rpm, 'headerFromPackage'):
- # Old style rpm
- old_flags = self._flags
- self._flags = flag
- return old_flags
- return self.ts.setFlags(flag)
-
- def setProbFilter(self, flag):
- """Set problem flags"""
- if hasattr(rpm, 'headerFromPackage'):
- # Old style rpm
- old_flags = self._prob_filter
- self._prob_filter = flag
- return old_flags
- return self.ts.setProbFilter(flag)
-
- def run(self, callback, user_data):
- if hasattr(rpm, 'headerFromPackage'):
- # Old style rpm
- return self.ts.run(self._flags, self._prob_filter, callback,
- user_data)
- return self.ts.run(callback, user_data)
-
-
-
-
-class SharedStateTransaction:
- _shared_state = {}
-
- def __init__(self):
- self.__dict__ = self._shared_state
-
-class RPMReadOnlyTransaction(SharedStateTransaction, RPMTransaction):
- read_only = 1
- def __init__(self):
- SharedStateTransaction.__init__(self)
- if not hasattr(self, 'ts'):
- RPMTransaction.__init__(self)
- # FIXME: replace with macro defination
- self.pushVSFlags(8)
-
-class RPM_Header:
- "Wrapper class for an rpm header - we need to store a flag is_source"
- def __init__(self, hdr, is_source=None):
- self.hdr = hdr
- self.is_source = is_source
- self.packaging = 'rpm'
- self.signatures = []
- self._extract_signatures()
-
- def __getitem__(self, name):
- return self.hdr[name]
-
- def __getattr__(self, name):
- return getattr(self.hdr, name)
-
- def checksum_type(self):
- if self.hdr[rpm.RPMTAG_FILEDIGESTALGO] \
- and PGPHASHALGO.has_key(self.hdr[rpm.RPMTAG_FILEDIGESTALGO]):
- checksum_type = PGPHASHALGO[self.hdr[rpm.RPMTAG_FILEDIGESTALGO]]
- else:
- checksum_type = 'md5'
- return checksum_type
-
- def is_signed(self):
- if hasattr(rpm, "RPMTAG_DSAHEADER"):
- dsaheader = self.hdr["dsaheader"]
- else:
- dsaheader = 0
- if self.hdr["siggpg"] or self.hdr["sigpgp"] or dsaheader:
- return 1
- return 0
-
- def _extract_signatures(self):
- header_tags = [
- [rpm.RPMTAG_DSAHEADER, "dsa"],
- [rpm.RPMTAG_RSAHEADER, "rsa"],
- [rpm.RPMTAG_SIGGPG, "gpg"],
- [rpm.RPMTAG_SIGPGP, 'pgp'],
- ]
- for ht, sig_type in header_tags:
- ret = self.hdr[ht]
- if not ret or len(ret) < 17:
- continue
- # Get the key id - hopefully we get it right
- key_id = ret[9:17]
- key_id_len = len(key_id)
- format = "%dB" % key_id_len
- t = struct.unpack(format, key_id)
- format = "%02x" * key_id_len
- key_id = format % t
- self.signatures.append({
- 'signature_type' : sig_type,
- 'key_id' : key_id,
- 'signature' : ret,
- })
-
-def get_header_byte_range(package_file):
- """
- Return the start and end bytes of the rpm header object.
-
- For details of the rpm file format, see:
-
http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html
- """
-
- lead_size = 96
-
- # Move past the rpm lead
- package_file.seek(lead_size)
-
- sig_size = get_header_struct_size(package_file)
-
- # Now we can find the start of the actual header.
- header_start = lead_size + sig_size
-
- package_file.seek(header_start)
-
- header_size = get_header_struct_size(package_file)
-
- header_end = header_start + header_size
-
- return (header_start, header_end)
-
-def get_header_struct_size(package_file):
- """
- Compute the size in bytes of the rpm header struct starting at the current
- position in package_file.
- """
- # Move past the header preamble
- package_file.seek(8, 1)
-
- # Read the number of index entries
- header_index = package_file.read(4)
- (header_index_value, ) = struct.unpack('>I', header_index)
-
- # Read the the size of the header data store
- header_store = package_file.read(4)
- (header_store_value, ) = struct.unpack('>I', header_store)
-
- # The total size of the header. Each index entry is 16 bytes long.
- header_size = 8 + 4 + 4 + header_index_value * 16 + header_store_value
-
- # Headers end on an 8-byte boundary. Round out the extra data.
- round_out = header_size % 8
- if round_out != 0:
- header_size = header_size + (8 - round_out)
-
- return header_size
-
-# Loads the package header from a file / stream / file descriptor
-# Raises rpm.error if an error is found, or InvalidPacageError if package is
-# busted
-# XXX Deal with exceptions better
-def get_package_header(filename=None, file=None, fd=None):
- if (filename is None and file is None and fd is None):
- raise ValueError, "No parameters passed"
-
- if filename is not None:
- f = open(filename)
- elif file is not None:
- f = file
- f.seek(0, 0)
- else: # fd is not None
- f = None
-
- if f is None:
- os.lseek(fd, 0, 0)
- file_desc = fd
- else:
- file_desc = f.fileno()
-
- if hasattr(rpm, 'headerFromPackage'):
- hdr, is_source = rpm.headerFromPackage(file_desc)
- if hdr is None:
- raise InvalidPackageError
- else:
- if hasattr(rpm, 'readHeaderFromFD'):
- header_start, header_end = \
- get_header_byte_range(os.fdopen(os.dup(file_desc)))
- os.lseek(file_desc, header_start, 0)
- hdr, offset = rpm.readHeaderFromFD(file_desc)
- else:
- # RHEL-4 and older, do the old way
- ts = RPMReadOnlyTransaction()
- nomd5 = getattr(rpm, 'RPMVSF_NOMD5')
- needpayload = getattr(rpm, 'RPMVSF_NEEDPAYLOAD')
- ts.pushVSFlags(~(nomd5 | needpayload))
- hdr = RPMReadOnlyTransaction().hdrFromFdno(file_desc)
- ts.popVSFlags()
- if hdr is None:
- raise InvalidPackageError
- is_source = hdr[getattr(rpm, 'RPMTAG_SOURCEPACKAGE')]
-
- return RPM_Header(hdr, is_source)
-
-class MatchIterator:
- def __init__(self, tag_name=None, value=None):
- # Query by name, by default
- if not tag_name:
- tag_name = "name"
-
- if hasattr(rpm, "headerFromPackage"):
- # rpm 4.0.4 or earlier
- self.db = rpm.opendb()
- method = self.db.match
- else:
- # rpm 4.1 or later
- self.ts = rpm.TransactionSet()
- self.ts.setVSFlags(8)
- method = self.ts.dbMatch
-
- if value:
- self.mi = method(tag_name, value)
- else:
- self.mi = method(tag_name)
-
- def pattern(self, tag_name, mode, pattern):
- self.mi.pattern(tag_name, mode, pattern)
-
- def next(self):
- try:
- hdr = self.mi.next()
- except StopIteration:
- hdr = None
-
- if hdr is None:
- return None
- if hasattr(rpm, "headerFromPackage"):
- is_source = not hdr[rpm.RPMTAG_SOURCERPM]
- else:
- is_source = hdr[getattr(rpm, 'RPMTAG_SOURCEPACKAGE')]
- return RPM_Header(hdr, is_source)
-
-
-def headerLoad(data):
- hdr = rpm.headerLoad(data)
- if hasattr(rpm, "headerFromPackage"):
- is_source = not hdr[rpm.RPMTAG_SOURCERPM]
- else:
- is_source = hdr[getattr(rpm, 'RPMTAG_SOURCEPACKAGE')]
- return RPM_Header(hdr, is_source)
-
-def labelCompare(t1, t2):
- return rpm.labelCompare(t1, t2)
-
-def nvre_compare(t1, t2):
- def build_evr(p):
- evr = [p[3], p[1], p[2]]
- evr = map(str, evr)
- if evr[0] == "":
- evr[0] = None
- return evr
- if t1[0] != t2[0]:
- raise ValueError("You should only compare packages with the same
name")
- evr1, evr2 = (build_evr(t1), build_evr(t2))
- return rpm.labelCompare(evr1, evr2)
-
-
-def hdrLabelCompare(hdr1, hdr2):
- """ take two RPMs or headers and compare them for order
"""
-
- if hdr1['name'] == hdr2['name']:
- hdr1 = [hdr1['epoch'] or None, hdr1['version'],
hdr1['release']]
- hdr2 = [hdr2['epoch'] or None, hdr2['version'],
hdr2['release']]
- if hdr1[0]:
- hdr1[0] = str(hdr1[0])
- if hdr2[0]:
- hdr2[0] = str(hdr2[0])
- return rpm.labelCompare(hdr1, hdr2)
- elif hdr1['name'] < hdr2['name']:
- return -1
- return 1
-
-
-def rpmLabelCompare(rpmFilename1, rpmFilename2):
- """ take two RPMs and compare them for order """
- return hdrLabelCompare(get_package_header(rpmFilename1),
- get_package_header(rpmFilename2))
-
-
-def sortHeaders(hdrs):
- """ Sorts a list of RPM headers (or RPMs).
- Assertion: they *must* exist.
- """
-
- assert isinstance(hdrs, type([]))
-
- sorted = hdrs[:]
- sorted.sort(hdrLabelCompare)
- return sorted
-
-
-def sortRPMs(rpms):
- """ Sorts a list of RPM files. They *must* exist. """
-
- assert isinstance(rpms, type([]))
-
- # We don't want to use rpmLabelCompare as a sorting mechanism, it would
- # extract the rpm header for each comparison.
- # Build a list of (header, rpm)
- helper = map(lambda x: (get_package_header(x), x), rpms)
-
- # Sort the list using the headers as a comparison
- helper.sort(lambda x, y: hdrLabelCompare(x[0], y[0]))
-
- # Extract the rpm names now
- return map(lambda x: x[1], helper)
-
-
-def getInstalledHeader(rpmName):
- """ quieries the RPM DB for a header matching rpmName.
"""
-
- mi = MatchIterator("name")
- mi.pattern("name", rpm.RPMMIRE_STRCMP, rpmName)
- return mi.next()
-
-
-if __name__ == '__main__':
- mi = MatchIterator("name")
- mi.pattern("name", rpm.RPMMIRE_GLOB, "*ker*")
- while 1:
- h = mi.next()
- if not h:
- break
- print h['name']
- sys.exit(1)
- hdr = get_package_header(filename="/tmp/python-1.5.2-42.72.i386.rpm")
- print dir(hdr)
- # Sources
- hdr = get_package_header(filename="/tmp/python-1.5.2-42.72.src.rpm")
- hdr2 = headerLoad(hdr.unload())
- print hdr2
- print len(hdr2.keys())
-
-
diff --git a/client/rhel/rhnlib/setup.py.in b/client/rhel/rhnlib/setup.py.in
index 99a8c59..35d5028 100644
--- a/client/rhel/rhnlib/setup.py.in
+++ b/client/rhel/rhnlib/setup.py.in
@@ -15,7 +15,7 @@ Red Hat Network (
http://rhn.redhat.com) software.""",
author = 'Mihai Ibanescu',
author_email = 'misa(a)redhat.com',
url = 'http://rhn.redhat.com',
- packages = ["rhn", "rhn/common"],
+ packages = ["rhn"],
license = "GPL",
)
diff --git a/client/tools/rhnpush/rhnpush.spec b/client/tools/rhnpush/rhnpush.spec
index 26efa29..9cd1d58 100644
--- a/client/tools/rhnpush/rhnpush.spec
+++ b/client/tools/rhnpush/rhnpush.spec
@@ -10,7 +10,8 @@ Release: 1%{?dist}
Source0:
https://fedorahosted.org/releases/s/p/spacewalk/%{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch: noarch
-Requires: rpm-python, rhnlib >= 2.5.16
+Requires: rpm-python, rhnlib
+Requires: spacewalk-backend-libs >= 0.8.3
BuildRequires: docbook-utils, gettext
Summary: Package uploader for the Red Hat Network Satellite Server
diff --git a/spacewalk/certs-tools/spacewalk-certs-tools.spec
b/spacewalk/certs-tools/spacewalk-certs-tools.spec
index 3f882d1..76477aa 100644
--- a/spacewalk/certs-tools/spacewalk-certs-tools.spec
+++ b/spacewalk/certs-tools/spacewalk-certs-tools.spec
@@ -10,7 +10,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u}
-n)
BuildArch: noarch
Requires: openssl rpm-build
Requires: rhn-client-tools
-Requires: rhnlib >= 2.5.16
+Requires: spacewalk-backend-libs >= 0.8.3
BuildRequires: docbook-utils
BuildRequires: python
Obsoletes: rhns-certs < 5.3.0