DEBIAN-HOWTO | 17 +
client/apt-spacewalk/debian/apt-spacewalk.install | 1
client/apt-spacewalk/debian/changelog | 6
client/apt-spacewalk/debian/compat | 1
client/apt-spacewalk/debian/control | 15 +
client/apt-spacewalk/debian/copyright | 21 +
client/apt-spacewalk/debian/docs | 2
client/apt-spacewalk/debian/pycompat | 1
client/apt-spacewalk/debian/rules | 46 +++
client/apt-spacewalk/debian/source/format | 1
client/apt-spacewalk/debian/watch | 2
client/apt-spacewalk/spacewalk.py | 262 ++++++++++++++++++++++
12 files changed, 374 insertions(+), 1 deletion(-)
New commits:
commit 4239f043da4e457a8ade4f7771d0c17dea8e9cd4
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Sat Jan 29 19:58:06 2011 +0100
howto build apt-spacewalk debian package
diff --git a/DEBIAN-HOWTO b/DEBIAN-HOWTO
index 4b001d5..ed04f6a 100644
--- a/DEBIAN-HOWTO
+++ b/DEBIAN-HOWTO
@@ -3,10 +3,11 @@ HOW TO BUILD DEBIAN PACKAGES
python-rhnlib in client/rhel/rhnlib
-----------------------------------
git checkout master
-cd rhnlib
+cd client/rhel/rhnlib
tito build --tgz
copy rhnlib-2.5.27.tar.gz /tmp/python-rhnlib_2.5.27.orig.tar.gz
git checkout debian
+cd ..
cp -a rhnlib /tmp/python-rhnlib-2.5.27
cd /tmp/python-rhnlib-2.5.27
debuild -i -S
@@ -18,3 +19,17 @@ Similary for other packages.
All packages available:
python-rhnlib in client/rhel/rhnlib
python-ethtool-0.5 in spec-tree/python-ethtool-0.5
+apt-spacewalk
+
+
+apt-spacewalk is not in master, so the instructions is little differen:
+cd client/apt-spacewalk
+tar zcvf /tmp/apt-spacewalk_1.0.0.orig.tar.gz spacewalk.py
+cd ..
+cp -a apt-spacewalk /tmp/apt-spacewalk-1.0.0
+cd /tmp/apt-spacewalk-1.0.0
+#build source package
+debuild -i -S
+#or build binary package
+debuild -b
+
commit 5bb8d7698b7e7dbc61eb5243303b2a84c3a48b7f
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Sat Jan 29 19:53:52 2011 +0100
add apt-spacewalk package
diff --git a/client/apt-spacewalk/debian/apt-spacewalk.install
b/client/apt-spacewalk/debian/apt-spacewalk.install
new file mode 100644
index 0000000..6819a30
--- /dev/null
+++ b/client/apt-spacewalk/debian/apt-spacewalk.install
@@ -0,0 +1 @@
+spacewalk.py /usr/lib/apt/methods/
diff --git a/client/apt-spacewalk/debian/changelog
b/client/apt-spacewalk/debian/changelog
new file mode 100644
index 0000000..8235644
--- /dev/null
+++ b/client/apt-spacewalk/debian/changelog
@@ -0,0 +1,6 @@
+apt-spacewalk (1.0.0-1) unstable; urgency=low
+
+ * Initial release Package was created.
+
+ -- Miroslav Suchý <miroslav(a)suchy.cz> Mon, 20 Sep 2010 10:38:44 +0200
+
diff --git a/client/apt-spacewalk/debian/compat b/client/apt-spacewalk/debian/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/client/apt-spacewalk/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/client/apt-spacewalk/debian/control b/client/apt-spacewalk/debian/control
new file mode 100644
index 0000000..96b6a22
--- /dev/null
+++ b/client/apt-spacewalk/debian/control
@@ -0,0 +1,15 @@
+Source: apt-spacewalk
+Section: python
+Priority: extra
+Maintainer: Miroslav Suchý <miroslav(a)suchy.cz>
+Build-Depends: python, debhelper (>= 7.0.50~)
+Build-Depends-Indep: python-support (>= 0.8)
+Standards-Version: 3.9.1
+Homepage:
https://fedorahosted.org/spacewalk
+
+Package: apt-spacewalk
+Architecture: all
+Depends: ${python:Depends}, ${misc:Depends}, rhn-client-tools
+Provides: ${python:Provides}
+Description: Spacewalk transport for apt-get.
+ This is used to connect to Spacewalk servers.
diff --git a/client/apt-spacewalk/debian/copyright
b/client/apt-spacewalk/debian/copyright
new file mode 100644
index 0000000..98b52fb
--- /dev/null
+++ b/client/apt-spacewalk/debian/copyright
@@ -0,0 +1,21 @@
+apt-spacewalk is copyright 2011 by Red Hat Inc.
+apt-spacewalk is currently developed by Spacewalk Development Team
<spacewalk-devel(a)redhat.com>.
+
+License: GPLv2
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+See /usr/share/common-licenses/GPL-2, or
+<http://www.gnu.org/copyleft/gpl.txt> for the terms of the latest version
+of the GNU General Public License.
diff --git a/client/apt-spacewalk/debian/docs b/client/apt-spacewalk/debian/docs
new file mode 100644
index 0000000..a48c3b0
--- /dev/null
+++ b/client/apt-spacewalk/debian/docs
@@ -0,0 +1,2 @@
+ChangeLog
+copyright
diff --git a/client/apt-spacewalk/debian/pycompat b/client/apt-spacewalk/debian/pycompat
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/client/apt-spacewalk/debian/pycompat
@@ -0,0 +1 @@
+2
diff --git a/client/apt-spacewalk/debian/rules b/client/apt-spacewalk/debian/rules
new file mode 100755
index 0000000..e652103
--- /dev/null
+++ b/client/apt-spacewalk/debian/rules
@@ -0,0 +1,46 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_prep
+ dh_installdirs -A $(CURDIR)/usr/lib/apt/methods/
+ dh_install
+
+build: build-stamp
+
+build-stamp:
+ dh_testdir
+ touch build-stamp
+
+clean:
+ rm -rf build
+
+binary: binary-indep binary-arch
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installdebconf
+ dh_installdeb
+ dh_python
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+.PHONY: build clean binary-indep binary-arch binary install
+
diff --git a/client/apt-spacewalk/debian/source/format
b/client/apt-spacewalk/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/client/apt-spacewalk/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/client/apt-spacewalk/debian/watch b/client/apt-spacewalk/debian/watch
new file mode 100644
index 0000000..c76ceee
--- /dev/null
+++ b/client/apt-spacewalk/debian/watch
@@ -0,0 +1,2 @@
+version=3
+https://fedorahosted.org/releases/s/p/spacewalk/rhnlib-(.*)\.tar\.gz
diff --git a/client/apt-spacewalk/spacewalk.py b/client/apt-spacewalk/spacewalk.py
new file mode 100644
index 0000000..989fed3
--- /dev/null
+++ b/client/apt-spacewalk/spacewalk.py
@@ -0,0 +1,262 @@
+#!/usr/bin/python -u
+#
+# Very early prototype of apt-transport-spacewalk
+#
+# Author: Simon Lukasik <xlukas08 [at] stud.fit.vutbr.cz>
+# Date: 2011-01-01
+# License: GPLv2
+#
+#
+
+import sys
+import hashlib
+
+import warnings
+warnings.filterwarnings("ignore", message="the md5 module is deprecated;
use hashlib instead")
+sys.path.append("/usr/share/rhn/")
+
+from httplib import HTTPConnection, HTTPSConnection
+from up2date_client import config
+from up2date_client import rhnChannel
+from up2date_client import up2dateAuth
+from up2date_client import up2dateErrors
+
+
+
+class pkg_acquire_method:
+ """
+ This is slightly modified python variant of apt-pkg/acquire-method.
+ It is a skeleton class that implements only very basic of apt methods
+ functionality.
+ """
+ __eof = False
+
+ def __init__(self):
+ print "100 Capabilities\nVersion: 1.0\nSingle-Instance: true\n\n",
+
+ def __get_next_msg(self):
+ """
+ Apt uses for communication with its methods the text protocol similar
+ to http. This function parses the protocol messages from stdin.
+ """
+ if self.__eof:
+ return None
+ result = {};
+ line = sys.stdin.readline()
+ if not line:
+ self.__eof = True
+ return None
+ s = line.split(" ", 1)
+ result['_number'] = int(s[0])
+ result['_text'] = s[1].strip()
+
+ while not self.__eof:
+ line = sys.stdin.readline()
+ if not line:
+ self.__eof = True
+ return result
+ if line == '\n':
+ return result
+ s = line.split(":", 1)
+ result[s[0]] = s[1].strip()
+
+ def __dict2msg(self, msg):
+ """Convert dictionary to http like message"""
+ result = ""
+ for item in msg.keys():
+ if msg[item] != None:
+ result += item + ": " + msg[item] + "\n"
+ return result
+
+ def status(self, **kwargs):
+ print "102 Status\n%s\n" % self.__dict2msg(kwargs),
+
+ def uri_start(self, msg):
+ print "200 URI Start\n%s\n" % self.__dict2msg(msg),
+
+ def uri_done(self, msg):
+ print "201 URI Done\n%s\n" % self.__dict2msg(msg),
+
+ def uri_failure(self, msg):
+ print "400 URI Failure\n%s\n" % self.__dict2msg(msg),
+
+ def run(self):
+ """Loop through requests on stdin"""
+ while True:
+ msg = self.__get_next_msg()
+ if msg == None:
+ return 0
+ if msg['_number'] == 600:
+ # TODO: catch exceptions
+ self.fetch(msg)
+ else:
+ return 100
+
+
+
+
+def get_ssl_ca_cert(up2date_cfg):
+ if not (up2date_cfg.has_key('sslCACert') and
up2date_cfg['sslCACert']):
+ raise BadSslCaCertConfig
+
+ ca_certs = up2date_cfg['sslCACert']
+ if type(ca_certs) == list:
+ return ca_certs
+
+
+
+class spacewalk_method(pkg_acquire_method):
+ """
+ Spacewalk acquire method
+ """
+ up2date_cfg = None
+ server_fqdn = None
+ login_info = None
+ current_url = None
+ svr_channels = None
+ http_headers = None
+ base_channel = None
+ conn = None
+
+ def fail(self, message = 'This system is not registered with the spacewalk
server'):
+ self.uri_failure({'URI': self.uri,
+ 'Message': message})
+ return False
+
+
+ def __load_config(self):
+ if self.up2date_cfg == None:
+ self.up2date_cfg = config.initUp2dateConfig()
+ self.server_fqdn =
self.up2date_cfg['serverURL'].split("/",3)[2]
+ # TODO: proxy settings
+
+
+ def __login(self):
+ if self.login_info == None:
+ self.status(URI = self.uri, Message = 'Logging into the spacewalk
server')
+ self.login_info = up2dateAuth.getLoginInfo() # TODO: catch exceptions
+ if not self.login_info:
+ return self.fail()
+ self.status(URI = self.uri, Message = 'Logged in')
+ return True
+
+
+ def __init_channels(self):
+ if self.svr_channels == None:
+ self.svr_channels = rhnChannel.getChannelDetails() # TODO: catch exceptions
+ # TODO: some conduit magic here (or rather not)
+ # TODO CHANNELS
+ # sslcacert = get_ssl_ca_cert(self.up2date_cfg) # TODO: to remove or not to
remove
+ for channel in self.svr_channels:
+ if channel['parent_channel'] == '':
+ self.base_channel = channel['label']
+ # TODO: Full RhnRepo
+
+
+ def __init_headers(self):
+ if self.http_headers == None:
+ rhn_needed_headers = ['X-RHN-Server-Id',
+ 'X-RHN-Auth-User-Id',
+ 'X-RHN-Auth',
+ 'X-RHN-Auth-Server-Time',
+ 'X-RHN-Auth-Expire-Offset']
+ self.http_headers = {};
+ for header in rhn_needed_headers:
+ if not self.login_info.has_key(header):
+ return self.fail("Missing required login information %s" %
(header))
+ self.http_headers[header] = self.login_info[header]
+ self.http_headers['X-RHN-Transport-Capability'] =
'follow-redirects=3'
+ return True
+
+
+ def __make_conn(self):
+ # TODO: HTTPS + certificate verification
+ if self.conn == None:
+ self.conn = HTTPConnection(self.server_fqdn)
+
+
+ def __transform_document(self, document):
+ """Transform url given by apt to real spacewalk
url"""
+ document = document.replace('dists/channels:/main/',
+ 'dists/channels:/' + self.base_channel + '/', 1)
+ document = document.replace('binary-i386', 'repodata', 1) # TODO
+ document = document.replace('dists/channels:/',
'/XMLRPC/GET-REQ/', 1)
+ return document
+
+
+ def fetch(self, msg):
+ """
+ Fetch the content from spacewalk server to the file.
+
+ Acording to the apt protocol msg must contain: 'URI' and
'Filename'.
+ Other possible keys are: 'Last-Modified', 'Index-File',
'Fail-Ignore'
+ """
+ self.uri = msg['URI']
+ self.filename = msg['Filename']
+
+ self.__load_config()
+ server_fqdn, document = self.uri.split("/",3)[2:]
+ if server_fqdn != self.server_fqdn:
+ return self.fail()
+
+ if not self.__login():
+ return
+
+ self.__init_channels()
+
+ document = self.__transform_document(document)
+
+ if not self.__init_headers():
+ return
+
+ self.__make_conn()
+
+ self.conn.request("GET", "/" + document, headers =
self.http_headers)
+ self.status(URI = self.uri, Message = 'Waiting for headers')
+
+ res = self.conn.getresponse()
+ if res.status != 200:
+ self.uri_failure({'URI': self.uri,
+ 'Message': str(res.status) + ' ' +
res.reason,
+ 'FailReason': 'HttpError' +
str(res.status)})
+ while True:
+ data = res.read(4096)
+ if not len(data): break
+ return
+
+ self.uri_start({'URI': self.uri,
+ 'Size': res.getheader('content-length'),
+ 'Last-Modified':
res.getheader('last-modified')})
+
+ f = open(self.filename, "w")
+ hash_sha256 = hashlib.sha256()
+ hash_md5 = hashlib.md5()
+ while True:
+ data = res.read(4096)
+ if not len(data):
+ break
+ hash_sha256.update(data)
+ hash_md5.update(data)
+ f.write(data)
+ f.close()
+
+ self.uri_done({'URI': self.uri,
+ 'Filename': self.filename,
+ 'Size': res.getheader('content-length'),
+ 'Last-Modified': res.getheader('last-modified'),
+ 'MD5-Hash': hash_md5.hexdigest(),
+ 'MD5Sum-Hash': hash_md5.hexdigest(),
+ 'SHA256-Hash': hash_sha256.hexdigest()})
+
+
+ def __del__(self):
+ if self.conn:
+ self.conn.close()
+
+
+
+if __name__ == '__main__':
+ method = spacewalk_method()
+ ret = method.run()
+ sys.exit(ret)
+