View | Details | Raw Unified | Return to bug 15550 | Differences between
and this patch

Collapse All | Expand All

(-)python/univention-updater (-35 / +10 lines)
Lines 129-169 Link Here
129
		if os.path.exists(os.path.join(tempdir,sh)):
129
		if os.path.exists(os.path.join(tempdir,sh)):
130
			os.remove(os.path.join(tempdir,sh))
130
			os.remove(os.path.join(tempdir,sh))
131
131
132
		proxy_headers = updater.open_connection()
132
		(response, data) = updater.repository().access(server_path, sh, method="GET")
133
		path="%s/%s" % ( server_path, sh )
133
		if response.status != 200:
134
		site = '%s/%s/%s' % (updater.proxy_prefix, updater.repository_prefix, path)
134
			dprint('failed to download %s' % path)
135
		replace_slash = re.compile ('[/]{2,}')
135
			dprint(' %s: %s' % (response.status,response.reason))
136
		site = replace_slash.sub ('/', site)
136
			continue
137
		if not site.startswith ('http://') and proxy_headers != None:
138
			site = 'http://%s' % site
139
		if proxy_headers != None:
140
			updater.connection.putrequest('GET', site, skip_accept_encoding=1)
141
		else:
142
			updater.connection.putrequest('GET', site)
143
144
		if proxy_headers != None:
145
			for k, v in proxy_headers.items ():
146
				updater.connection.putheader (k, v)
147
		try:
148
			updater.connection.endheaders ()
149
			response = updater.connection.getresponse()
150
			response_data = response.read()
151
152
			if response.status != 200:
153
				dprint('failed to download %s' % path)
154
				dprint(' %s: %s' % (response.status,response.reason))
155
				continue
156
		except:
137
		except:
157
			dprint( traceback.format_exc ())
138
			dprint( traceback.format_exc ())
158
139
159
		f=open(os.path.join(tempdir, sh), 'w+' )
140
		f=open(os.path.join(tempdir, sh), 'w+' )
160
		f.write(response_data)
141
		f.write(data)
161
		f.close()
142
		f.close()
162
		os.chmod(os.path.join(tempdir, sh), 0744)
143
		os.chmod(os.path.join(tempdir, sh), 0744)
163
144
164
		updater.close_connection()
165
166
167
def update_available(mode, baseConfig, cdrom_mount_point, sourcedir, stdout, sys_stdout, reboot, internal=1, iso=None, updater=None):
145
def update_available(mode, baseConfig, cdrom_mount_point, sourcedir, stdout, sys_stdout, reboot, internal=1, iso=None, updater=None):
168
	# Checks if there is an update available
146
	# Checks if there is an update available
169
147
Lines 284-292 Link Here
284
			code, message = msg
262
			code, message = msg
285
263
286
			if code == socket.EAI_NONAME:
264
			if code == socket.EAI_NONAME:
287
				dprint('Error: The name %s is not known.\n       Please check your network settings or set the UCR variable repository/online/server to a diffrent value.' % (updater.repository_server), [ sys.stdout, stdout ])
265
				dprint('Error: The name %s is not known.\n       Please check your network settings or set the UCR variable repository/online/server to a diffrent value.' % (updater.repository()), [ sys.stdout, stdout ])
288
			else:
266
			else:
289
				dprint('Error: An error occurs during the connection to %s.\n       Please check your network settings and check the logfile /var/log/univention/updater.log' % (updater.repository_server), [ sys.stdout, stdout ])
267
				dprint('Error: An error occurs during the connection to %s.\n       Please check your network settings and check the logfile /var/log/univention/updater.log' % (updater.repository()), [ sys.stdout, stdout ])
290
268
291
			sys.exit( 1 )
269
			sys.exit( 1 )
292
270
Lines 516-529 Link Here
516
		for maintained in maintained_state_list:
494
		for maintained in maintained_state_list:
517
			for arch in ['all', architecture, 'extern' ]:
495
			for arch in ['all', architecture, 'extern' ]:
518
				if updater.net_path_exists('%s/%s/%s-%s/%s/' % (next_vv, maintained, next_vv, next_vp, arch)):
496
				if updater.net_path_exists('%s/%s/%s-%s/%s/' % (next_vv, maintained, next_vv, next_vp, arch)):
519
					if updater.repository_prefix:
497
					add_temporary_sources_list ('deb %s/%s/%s/ %s/%s/' % ( updater.repository(), next_vv, maintained, nextversion, arch))
520
						add_temporary_sources_list ('deb http://%s/%s/%s/%s/ %s/%s/' % ( updater.repository_server, updater.repository_prefix, next_vv, maintained, nextversion, arch))
521
					else:
522
						add_temporary_sources_list ('deb http://%s/%s/%s/ %s/%s/' % ( updater.repository_server, next_vv, maintained, nextversion, arch))
523
498
524
		# Download the pre and postup scripts
499
		# Download the pre and postup scripts
525
		scriptPath = tempdir
500
		scriptPath = tempdir
526
		download_sh_files(updater, '%s/%s/maintained/%s-%s/all' % (updater.repository_prefix, next_vv, next_vv, next_vp), tempdir)
501
		download_sh_files(updater, '%s/maintained/%s-%s/all' % (next_vv, next_vv, next_vp), tempdir)
527
502
528
	dprint('**** Starting actual update at %s' % datetime.datetime.now ().ctime ())
503
	dprint('**** Starting actual update at %s' % datetime.datetime.now ().ctime ())
529
504
(-)python/univention-repository-migrate (-4 / +1 lines)
Lines 31-46 Link Here
31
from optparse import OptionParser
31
from optparse import OptionParser
32
import copy
32
import copy
33
import os
33
import os
34
import re
35
import shutil
34
import shutil
36
import string
37
import subprocess
38
import sys
35
import sys
39
import time
36
import time
40
37
41
import univention.config_registry as ucr
38
import univention.config_registry as ucr
42
import univention.updater.repository as urepo
39
import univention.updater.repository as urepo
43
from univention.updater import UniventionMirror, UCS_Version
40
from univention.updater import UCS_Version
44
41
45
configRegistry = ucr.ConfigRegistry()
42
configRegistry = ucr.ConfigRegistry()
46
configRegistry.load()
43
configRegistry.load()
(-)python/univention-security-update (-2 / +2 lines)
Lines 194-202 Link Here
194
			code, message = msg
194
			code, message = msg
195
195
196
			if code == socket.EAI_NONAME:
196
			if code == socket.EAI_NONAME:
197
				dprint( 'Error: The name %s is not known.\n       Please check your network settings or set the UCR variable repository/online/server to a diffrent value.' % (updater.repository_server), [fp_debug,sys.stderr] )
197
				dprint( 'Error: The name %s is not known.\n       Please check your network settings or set the UCR variable repository/online/server to a diffrent value.' % (updater.repository()), [fp_debug,sys.stderr] )
198
			else:
198
			else:
199
				dprint( 'Error: An error occurs during the connection to %s.\n       Please check your network settings and check the logfile /var/log/univention/security-updates.log' % (updater.repository_server), [fp_debug,sys.stderr] )
199
				dprint( 'Error: An error occurs during the connection to %s.\n       Please check your network settings and check the logfile /var/log/univention/security-updates.log' % (updater.repository()), [fp_debug,sys.stderr] )
200
200
201
			sys.exit( 1 )
201
			sys.exit( 1 )
202
202
(-)python/univention-repository-merge (-4 / +1 lines)
Lines 30-40 Link Here
30
30
31
import os, string
31
import os, string
32
import shutil, sys
32
import shutil, sys
33
import getopt, time
33
import getopt
34
34
35
import univention.config_registry as ucr
36
import univention.updater.repository as urepo
35
import univention.updater.repository as urepo
37
from univention.updater import UniventionMirror, UCS_Version
38
36
39
l_package={}
37
l_package={}
40
p_remove=[]
38
p_remove=[]
Lines 174-177 Link Here
174
	os.chdir(packages_dir)
172
	os.chdir(packages_dir)
175
	urepo.update_indexes( packages_dir, stdout = fp_debug, stderr = fp_debug )
173
	urepo.update_indexes( packages_dir, stdout = fp_debug, stderr = fp_debug )
176
	fp_debug.close()
174
	fp_debug.close()
177
(-)debian/univention-updater.univention-config-registry (+1 lines)
Lines 57-59 Link Here
57
Variables: repository/mirror/threads
57
Variables: repository/mirror/threads
58
Variables: repository/mirror/architectures
58
Variables: repository/mirror/architectures
59
Variables: repository/mirror/version/.*
59
Variables: repository/mirror/version/.*
60
Variabled: online/repository/clean
(-)conffiles/etc/apt/mirror.list (-1 / +1 lines)
Lines 16-22 Link Here
16
16
17
try:
17
try:
18
	mirror = UniventionMirror()
18
	mirror = UniventionMirror()
19
	if mirror.online_repository in ['false', '0', 'no', 'disabled']:
19
	if not mirror.online_repository:
20
		print '# The mirror mode is disabled and can be enabled with:'
20
		print '# The mirror mode is disabled and can be enabled with:'
21
		print '#   univention-config-registry set repository/mirror=true'
21
		print '#   univention-config-registry set repository/mirror=true'
22
		print ''
22
		print ''
(-)modules/univention/updater/mirror.py (-41 / +20 lines)
Lines 35-94 Link Here
35
from tools import UniventionUpdater, UCS_Version
35
from tools import UniventionUpdater, UCS_Version
36
36
37
class UniventionMirror( UniventionUpdater ):
37
class UniventionMirror( UniventionUpdater ):
38
	""" Handle /etc/apt/mirror.list """
38
	def __init__( self ):
39
	def __init__( self ):
39
		UniventionUpdater.__init__( self )
40
		UniventionUpdater.__init__( self )
40
		self.online_repository = self.configRegistry.get( 'repository/mirror', 'yes' )
41
		self.repository_server = self.configRegistry.get( 'repository/mirror/server', 'apt.univention.de' )
42
		self.repository_path =  self.configRegistry.get( 'repository/mirror/basepath', '/var/lib/univention-repository' )
41
		self.repository_path =  self.configRegistry.get( 'repository/mirror/basepath', '/var/lib/univention-repository' )
43
		self.repository_prefix = self.configRegistry.get( 'repository/mirror/prefix', '' )
44
		if not self.repository_prefix and self.net_path_exists( '/univention-repository/' ):
45
			self.repository_prefix = 'univention-repository'
46
			
42
			
47
		if self.configRegistry.has_key( 'repository/mirror/version/end' ):
43
		self.version_end = UCS_Version(
48
			self.version_end = UCS_Version( self.configRegistry.get( 'repository/mirror/version/end' ) )
44
				self.configRegistry.get('repository/mirror/version/end',
49
		else:
45
					(self.version_major, self.version_minor, self.patchlevel) )
50
			self.version_end = UCS_Version( ( self.version_major, self.version_minor, self.patchlevel ) )
46
				)
51
		if self.configRegistry.has_key( 'repository/mirror/version/start' ):
47
		self.version_start = UCS_Version(
52
			self.version_start = UCS_Version( self.configRegistry.get( 'repository/mirror/version/start' ) )
48
				self.configRegistry.get('repository/mirror/version/start',
53
		else:
49
					(self.version_major, 0, 0) ) )
54
			self.version_start = UCS_Version( ( self.version_major, 0, 0 ) )
55
		# set architectures to mirror
50
		# set architectures to mirror
56
		archs = self.configRegistry.get( 'repository/mirror/architectures', '' )
51
		archs = self.configRegistry.get('repository/mirror/architectures', '').split(' ')
57
		if archs:
52
	
58
			self.architectures = archs.split( ' ' )
53
	def config_repository( self ):
54
		""" Retrieve configuration to access repository. Overrides UniventionUpdater. """
55
		self.online_repository = self.ucr_bool('repository/mirror', True)
56
		self.repositoryFromRegistry(self.configRegistry, 'repository/online')
59
57
60
	def retrieve_url( self, path ):
58
	def retrieve_url( self, path ):
61
		'''downloads the given path from the repository server'''
59
		'''downloads the given path from the repository server'''
62
		# path MUST NOT contain the schema and hostname
63
		proxy_headers = self.open_connection()
64
		site = '%s/%s/%s' % (self.proxy_prefix, self.repository_prefix, path)
65
66
		replace_slash = re.compile ('[/]{2,}')
67
		site = replace_slash.sub ('/', site)
68
		if not site.startswith ('http://') and proxy_headers != None:
69
			site = 'http://%s' % site
70
71
		if proxy_headers != None:
72
			self.connection.putrequest('GET', site, skip_accept_encoding=1)
73
		else:
74
			self.connection.putrequest('GET', site)
75
76
		if proxy_headers != None:
77
			for k, v in proxy_headers.items ():
78
				self.connection.putheader (k, v)
79
		try:
60
		try:
80
			self.connection.endheaders ()
61
			(response, data) = self.repository().access(path, method='GET')
81
			response = self.connection.getresponse()
82
			body = response.read()
83
84
			if response.status == 200:
62
			if response.status == 200:
85
				self.close_connection()
63
				return data
86
				return body
87
		except:
64
		except:
88
			import traceback
65
			import traceback
89
			print traceback.format_exc ()
66
			print traceback.format_exc ()
90
91
		self.close_connection()
92
		return None
67
		return None
93
68
94
	def copy_script( self, script, repository, directory ):
69
	def copy_script( self, script, repository, directory ):
Lines 218-220 Link Here
218
		self.mirror_repositories()
193
		self.mirror_repositories()
219
		self.mirror_update_scripts()
194
		self.mirror_update_scripts()
220
		self.update_dists_files()
195
		self.update_dists_files()
196
if __name__ == '__main__':
197
	umi = UniventionMirror()
198
	import doctest
199
	doctest.testmod()
(-)modules/univention/updater/tools.py (-234 / +324 lines)
Lines 47-54 Link Here
47
47
48
	def __init__( self, version ):
48
	def __init__( self, version ):
49
		'''version must a string matching the pattern X.Y-Z or a triple
49
		'''version must a string matching the pattern X.Y-Z or a triple
50
		with major, minor and patchlevel'''
50
		with major, minor and patchlevel
51
51
52
		>>> str(UCS_Version('2.3-0'))
53
		'2.3-0'
54
		>>> str(UCS_Version((2,3,0)))
55
		'2.3-0'
56
		'''
57
52
		if isinstance( version, ( tuple, list ) ) and len( version ) == 3:
58
		if isinstance( version, ( tuple, list ) ) and len( version ) == 3:
53
			self.major = int( version[ 0 ] )
59
			self.major = int( version[ 0 ] )
54
			self.minor = int( version[ 1 ] )
60
			self.minor = int( version[ 1 ] )
Lines 59-65 Link Here
59
	def __cmp__( self, right ):
65
	def __cmp__( self, right ):
60
		'''Compare to UCS versions. The method returns 0 if the versions
66
		'''Compare to UCS versions. The method returns 0 if the versions
61
		are equal, -1 if the left is less than the right and 1 of the
67
		are equal, -1 if the left is less than the right and 1 of the
62
		left is greater than the right'''
68
		left is greater than the right
69
70
		>>> UCS_Version('2.2-0') < UCS_Version('2.2-1')
71
		True
72
		>>> UCS_Version('2.2-0') > UCS_Version('2.3-0')
73
		False
74
		'''
63
		# major version differ
75
		# major version differ
64
		if self.major < right.major:
76
		if self.major < right.major:
65
			return -1
77
			return -1
Lines 79-84 Link Here
79
		return 0
91
		return 0
80
92
81
	def set( self, version ):
93
	def set( self, version ):
94
		"""Convert "version" string into its parts."""
82
		match = UCS_Version._regexp.match( version )
95
		match = UCS_Version._regexp.match( version )
83
		if not match:
96
		if not match:
84
			raise AttributeError( 'string does not match UCS version pattern' )
97
			raise AttributeError( 'string does not match UCS version pattern' )
Lines 91-262 Link Here
91
	def __str__( self ):
104
	def __str__( self ):
92
		return '%d.%d-%d' % ( self.major, self.minor, self.patchlevel )
105
		return '%d.%d-%d' % ( self.major, self.minor, self.patchlevel )
93
106
94
class UniventionUpdater:
107
class ResolvableUrl:
108
	""" Represents an URL of a repository """
109
	failed = {}
95
110
96
	def __init__(self):
111
	def __init__(self, baseurl, username=None, password=None, proxy=None):
97
		self.connection = None
112
		""" Initialize APT source.
98
		self.proxy_prefix = None
113
		url: REQUIRED
99
		self.proxy_username = None
114
		username: None
100
		self.proxy_password = None
115
		password: None
101
		self.proxy_server = None
116
		proxy: OPTIONAL, e.g. [http://][user:password@]host[:port]
102
		self.proxy_port = None
117
		"""
118
		self.baseurl = baseurl.rstrip('/') + '/'
119
		self.username = username
120
		self.password = password
121
		if proxy != None and proxy.lower().startswith('http://'):
122
			self.proxy_netloc = proxy[len('http://'):]
123
		else:
124
			self.proxy_netloc = proxy
125
		if self.proxy_netloc:
126
			if self.proxy_netloc.find ('@') != -1:
127
				user_pwd, self.proxy_netloc = location.split ('@')
128
				self.proxy_username, self.proxy_password = user_pwd.split(':')
129
			else:
130
				self.proxy_username, self.proxy_password = (None, None)
103
131
104
		self.ucr_reinit()
132
	def __str__( self ):
133
		"""Return a nice string representation of the url."""
134
		(scheme, netloc, path, query, fragment) = httplib.urlsplit(self.baseurl)
135
		s = [ scheme, '://' ]
136
		if self.username and self.password:
137
			s += [ self.username, ':', self.password, '@' ]
138
		s += [ netloc, path ]
139
		if query:
140
			s += ['?', query]
141
		if fragment:
142
			s += ['?', fragment]
143
		return ''.join(s)
105
144
106
	def open_connection(self, server=None, port=None):
145
	def access(self, *path, **options):
107
		'''Open http-connection to server:port'''
146
		""" Access url and return 2-tuple (respone, response.data).
147
		optional method overrides default  HTTP-method HEAD """
148
		url = self.baseurl + '/'.join( map(lambda x:x.lstrip('/'), filter(None, path) ) )
149
		method = options.get('method','HEAD')
150
		(scheme, netloc, path, query, fragment) = httplib.urlsplit(url)
151
		# if we already know a net-location being bad, re-raise exception
152
		if ResolvableUrl.failed.has_key(netloc):
153
			raise ResolvableUrl.failed[netloc]
154
		try:
155
			try:
156
				if self.proxy_netloc != None:
157
					connection = httplib.HTTPConnection(self.proxy_netloc)
158
					connection.putrequest(method, url, skip_accept_encoding=True)
159
					if self.proxy_username != None and self.proxy_password != None:
160
						user_pass = base64.encodestring('%s:%s' % (self.proxy_username, self.proxy_password)).rstrip()
161
						connection.putheader('Proxy-Authorization', 'Basic %s' % user_pass)
162
				else:
163
					connection = httplib.HTTPConnection(netloc)
164
					connection.putrequest(method, path)
165
				if self.username != None and self.password != None:
166
					user_pass = base64.encodestring('%s:%s' % (self.username, self.password)).rstrip()
167
					connection.putheader('Authorization', 'Basic %s' % user_pass)
168
				connection.endheaders()
169
				response = connection.getresponse()
170
				response_data = response.read()
171
				return (response, response_data)
172
			except socket.gaierror, e:
173
				ResolvableUrl.failed[netloc] = e
174
				raise e
175
			except socket.error, e:
176
				ResolvableUrl.failed[netloc] = e
177
				raise e
178
		finally:
179
			connection.close()
108
180
109
		if not self.nameserver_available:
181
	def exists(self, *path):
110
			raise socket.gaierror, (socket.EAI_NONAME, 'The repository server %s could not be resolved.' % server)
182
		""" Test if path exists on repository """
111
		if not server:
183
		m = {'method':'HEAD'}
112
			server = self.repository_server
184
		(response, data) = self.access(*path, **m)
113
		if port in (None, ''):
185
		return response.status == httplib.OK
114
			port = self.repository_port
115
186
116
		if self.proxy and self.proxy != '':
187
class RepositoryConfig:
117
			self.proxy_prefix = "%s:%s" % (server, port)
188
	""" Repository configuration """
189
	def __init__(self):
190
		self.repository_server = None
191
		self.repository_port = None
192
		self.repository_prefix = None
193
		self.repository_username = None
194
		self.repository_password = None
195
		self.repository_proxy = None
196
		self._repository_hash = 0
197
		self._repository = None
118
198
119
			location = self.proxy
199
	def repository(self):
120
			if location.find ('@') != -1:
200
		h = hash((self.repository_server, self.repository_port,
121
				user_pwd, location = location.split ('@')
201
			self.repository_prefix, self.repository_username,
122
				self.proxy_username, self.proxy_password = user_pwd.split(':')
202
			self.repository_password, self.repository_proxy))
203
		if h != self._repository_hash:
204
			self._repository_hash = h
205
			self._repository = self._repositoryFromSelf()
206
		return self._repository
123
207
124
			if location.find (':') != -1:
208
	def _repositoryFromSelf(self):
125
				location, pport = location.split (':')
209
		""" Create repository URL from self """
126
				self.proxy_port = int (pport)
210
		if self.repository_prefix not in (None, "none", "/"):
127
			else:
211
			url = 'http://%s:%s/%s/' % (self.repository_server,
128
				self.proxy_port = HTTP_PROXY_DEFAULT_PORT
212
					self.repository_port, self.repository_prefix.strip('/'))
129
			self.proxy_server   = location
213
		else:
214
			url = 'http://%s:%s/' % (self.repository_server, self.repository_port)
215
		return ResolvableUrl(url, username=self.repository_username,
216
				password=self.repository_password, proxy=self.repository_proxy)
130
217
131
			self.connection = httplib.HTTPConnection(self.proxy_server, self.proxy_port)
218
	def repositoryFromRegistry(self, configRegistry, basepath, altPrefix='/univention-repository/'):
132
			proxy_headers = {}
219
		""" Create repository URL from configRegistry[basepath/*] """
220
		self.repository_server = configRegistry.get('%s/server' % basepath, 'apt.univention.de')
221
		self.repository_port = configRegistry.get('%s/port' % basepath, '80')
222
		self.repository_prefix = configRegistry.get('%s/prefix' % basepath, '')
223
		self.repository_username = configRegistry.get('%s/username' % basepath, None)
224
		self.repository_password = configRegistry.get('%s/password' % basepath, None)
225
		# check for prefix on repository server (if the repository server is reachable)
226
		if not self.repository_prefix:
227
			u = self._repositoryFromSelf()
228
			try:
229
				if u.exists(altPrefix.strip('/')):
230
					self.repository_prefix = altPrefix
231
			except:
232
				pass
133
233
134
			if self.proxy_username and self.proxy_password:
234
class UniventionUpdater(RepositoryConfig):
135
				#setup basic authentication
235
	""" Handle /etc/apt/sources.list.d/* """
136
				user_pass = base64.encodestring('%s:%s' % (self.proxy_username, self.proxy_password))
236
	def __init__(self):
137
				proxy_headers['Proxy-Authorization'] = string.strip ('Basic %s' % user_pass)
237
		RepositoryConfig.__init__(self)
138
			return proxy_headers
238
		self.architectures = [ os.popen('dpkg-architecture -qDEB_BUILD_ARCH 2>/dev/null').readline()[:-1] ]
139
		else:
239
		self.ucr_reinit()
140
			self.connection = httplib.HTTPConnection(server, int(port))
141
240
142
	def close_connection(self):
241
	def ucr_bool(self, key, default=False):
143
		'''Close http-connection'''
242
		'''Retrieve boolean value from Univention Configuration Registry
144
		self.connection.close()
243
		>>> uup.ucr_bool('repository/online', True)
244
		True
245
		'''
246
		value = self.configRegistry.get(key, None)
247
		if value == None:
248
			return default
249
		return value.lower() in ('true', 'yes', 'enable', 'enabled', '1')
145
250
146
	def ucr_reinit(self):
251
	def ucr_reinit(self):
147
		'''Re-initialize settings'''
252
		'''Re-initialize settings'''
148
		self.configRegistry=univention.config_registry.ConfigRegistry()
253
		self.configRegistry = univention.config_registry.ConfigRegistry()
149
		self.configRegistry.load()
254
		self.configRegistry.load()
150
255
151
		self.architectures = [ os.popen('dpkg-architecture -qDEB_BUILD_ARCH 2>/dev/null').readline()[:-1] ]
152
153
		self.online_repository=self.configRegistry.get('repository/online', 'True')
154
		if self.online_repository.lower() in ['true', 'yes', '1']:
155
			self.online_repository = True
156
		else:
157
			self.online_repository = False
158
159
		self.repository_server = self.configRegistry.get('repository/online/server', 'apt.univention.de')
160
		self.repository_port = self.configRegistry.get('repository/online/port', '80')
161
		self.repository_prefix = self.configRegistry.get('repository/online/prefix', '')
162
		self.is_repository_server = self.configRegistry.get( 'local/repository', 'no' ) in ( 'yes', 'true' )
163
164
		if self.configRegistry.has_key('proxy/http') and self.configRegistry['proxy/http']:
256
		if self.configRegistry.has_key('proxy/http') and self.configRegistry['proxy/http']:
165
			self.proxy = self.configRegistry['proxy/http'].lower().replace('http://','')
257
			self.repository_proxy = self.configRegistry['proxy/http'];
166
		elif os.environ.has_key('http_proxy') and os.environ['http_proxy']:
258
		elif os.environ.has_key('http_proxy') and os.environ['http_proxy']:
167
			self.proxy = os.environ['http_proxy'].lower().replace('http://','')
259
			self.repository_proxy = os.environ['http_proxy'];
168
		else:
260
		else:
169
			self.proxy = None
261
			self.repository_proxy = None
170
		self.proxy_prefix = ''
171
262
263
		self.is_repository_server = self.ucr_bool('local/repository', False)
264
172
		# check for maintained and unmaintained
265
		# check for maintained and unmaintained
173
		self.parts = []
266
		self.parts = []
174
267
175
		maintained = self.configRegistry.get('repository/online/maintained', 'True')
268
		if self.ucr_bool('repository/online/maintained', True):
176
		if maintained.lower() in ['true', 'yes', '1']:
177
			self.parts.append('maintained')
269
			self.parts.append('maintained')
178
270
179
		unmaintained = self.configRegistry.get('repository/online/unmaintained', 'False')
271
		if self.ucr_bool('repository/online/unmaintained', False):
180
		if unmaintained.lower() in ['true', 'yes', '1']:
181
			self.parts.append('unmaintained')
272
			self.parts.append('unmaintained')
182
273
183
		#UCS version
274
		#UCS version
184
		self.ucs_version=self.configRegistry['version/version']
275
		self.ucs_version = self.configRegistry['version/version']
185
		self.patchlevel=self.configRegistry['version/patchlevel']
276
		self.patchlevel = self.configRegistry['version/patchlevel']
186
		self.security_patchlevel=self.configRegistry['version/security-patchlevel']
277
		self.security_patchlevel = self.configRegistry['version/security-patchlevel']
187
		self.version_major = self.ucs_version.split('.')[0]
278
		self.version_major, self.version_minor = self.ucs_version.split('.')[0:2]
188
		self.version_minor = self.ucs_version.split('.')[-1]
189
279
190
		# should hotfixes be used
280
		# should hotfixes be used
191
		self.hotfixes = self.configRegistry.get( 'repository/online/hotfixes', 'no' ).lower() in ( 'true', 'yes' )
281
		self.hotfixes = self.ucr_bool('repository/online/hotfixes', False)
192
282
193
		# check availability of the repository server
283
		self.config_repository()
194
		try:
195
			socket.gethostbyname(self.repository_server)
196
			self.nameserver_available=True
197
		except socket.gaierror:
198
			self.nameserver_available=False
199
284
200
		# check for prefix on repository server (if the repository server is reachable)
285
	def config_repository( self ):
201
		try:
286
		""" Retrieve configuration to access repository. Overridden in UniventionMirror. """
202
			if not self.repository_prefix and self.net_path_exists( '/univention-repository/' ):
287
		self.online_repository = self.ucr_bool('repository/online', True)
203
				self.repository_prefix = 'univention-repository'
288
		self.repositoryFromRegistry(self.configRegistry, 'repository/online')
204
		except:
205
			self.repository_prefix = ''
206
289
207
	def net_path_exists (self, path, server='', port='', prefix='', username='', password='', debug=False):
290
	def net_path_exists (self, path, repository=None, debug=False):
291
		""" Check if a path on the repository(defaults to self) exists.
292
		>>> uup.net_path_exists('/')
293
		True
294
		>>> uup.net_path_exists('/foo',debug=True)
295
		# The site http://apt.knut.univention.de:80/foo was not found
296
		False
297
		"""
208
		# path MUST NOT contain the schema and hostname
298
		# path MUST NOT contain the schema and hostname
209
		proxy_headers = self.open_connection(server=server, port=port)
299
		''' check if 'path' exists on http://[username:password@]server[:port]/[prefix/]path '''
210
		if server: #if we use a diffrent server we should also use a diffrent prefix
300
		if repository == None:
211
			if prefix:
301
			repository = self.repository()
212
				site = '%s/%s/%s' % (self.proxy_prefix, prefix, path)
302
		#return repository.exists(path.lstrip('/'))
213
			else:
303
		(response,data) = repository.access(path)
214
				site = '%s/%s' % (self.proxy_prefix, path)
304
		if response.status == httplib.OK:
215
		else:
216
			site = '%s/%s/%s' % (self.proxy_prefix, self.repository_prefix, path)
217
218
		replace_slash = re.compile ('[/]{2,}')
219
		site = replace_slash.sub ('/', site)
220
		if not site.startswith ('http://') and proxy_headers != None:
221
			site = 'http://%s' % site
222
223
		if proxy_headers != None:
224
			self.connection.putrequest('GET', site, skip_accept_encoding=1)
225
		else:
226
			self.connection.putrequest('GET', site)
227
228
229
		if username and password:
230
			auth = 'Basic ' + string.strip(base64.encodestring(username + ':' + password))
231
			self.connection.putheader('Authorization', auth)
232
233
		if proxy_headers != None:
234
			for k, v in proxy_headers.items ():
235
				self.connection.putheader (k, v)
236
		self.connection.endheaders ()
237
		response = self.connection.getresponse()
238
		response.read()
239
240
		if response.status == 200:
241
			self.close_connection()
242
			return True
305
			return True
243
306
244
		if debug:
307
		if debug:
245
			if response.status == 404:
308
			url = '%s%s' % (repository, path.lstrip('/'))
246
				print '# The site http://%s%s was not found' % (server, site)
309
			if response.status == httplib.NOT_FOUND:
247
			elif response.status == 401:
310
				print '# The site %s was not found' % url
311
			elif response.status == httplib.UNAUTHORIZED:
248
				if username and password:
312
				if username and password:
249
					print '# Authentication failure for http://%s:%s@%s%s' % (username, password, server, site)
313
					print '# Authentication failure for %s' % url
250
				else:
314
				else:
251
					print '# Username and password are requiered for http://%s%s' % (server, site)
315
					print '# Username and password are requiered for %s' % url
252
			else:
316
			else:
253
				print '# The http error code (%d) was returned for the site http://%s%s' % (response.status, server, site)
317
				print '# The http error code (%d) was returned for the site %s' % (response.status, url)
254
318
255
		self.close_connection()
256
		return False
319
		return False
257
320
258
	def get_next_version( self, version ):
321
	def get_next_version( self, version ):
259
		'''Check if a new patchlevel, minor or major release is available for the given version'''
322
		'''Check if a new patchlevel, minor or major release is available for the given version
323
324
		>>> uup.get_next_version( UCS_Version( (2,1,2) ) )
325
		'2.2-0'
326
		>>> uup.get_next_version( UCS_Version( (2,2,0) ) )
327
		'2.2-1'
328
		>>> uup.get_next_version( UCS_Version( (99,99,99) ) )
329
		>>> 
330
		'''
260
		if self.net_path_exists( '%d.%d/maintained/%d.%d-%d/' % ( version.major, version.minor, version.major, version.minor, version.patchlevel + 1 ) ): #check for x.y-(z+1)
331
		if self.net_path_exists( '%d.%d/maintained/%d.%d-%d/' % ( version.major, version.minor, version.major, version.minor, version.patchlevel + 1 ) ): #check for x.y-(z+1)
261
			return '%d.%d-%d' % ( version.major, version.minor, version.patchlevel + 1 )
332
			return '%d.%d-%d' % ( version.major, version.minor, version.patchlevel + 1 )
262
		elif self.net_path_exists( '%d.%d/maintained/%d.%d-0/' % ( version.major, version.minor + 1, version.major, version.minor + 1 ) ): #check for x.(y+1)-0
333
		elif self.net_path_exists( '%d.%d/maintained/%d.%d-0/' % ( version.major, version.minor + 1, version.major, version.minor + 1 ) ): #check for x.(y+1)-0
Lines 267-299 Link Here
267
		return None
338
		return None
268
339
269
	def release_update_available( self, ucs_version = None ):
340
	def release_update_available( self, ucs_version = None ):
270
		'''Check if an update is available for the ucs_version'''
341
		'''Check if an update is available for the ucs_version
342
		>>> uup.release_update_available( '2.1-2' )
343
		'2.2-0'
344
		>>> uup.release_update_available( '2.2-0' )
345
		'2.2-1'
346
		'''
271
		if not ucs_version:
347
		if not ucs_version:
272
			return self.get_next_version( UCS_Version( ( self.version_major, self.version_minor, self.patchlevel ) ) )
348
			return self.get_next_version( UCS_Version( ( self.version_major, self.version_minor, self.patchlevel ) ) )
273
349
274
		return self.get_next_version( UCS_Version( ucs_version ) )
350
		return self.get_next_version( UCS_Version( ucs_version ) )
275
351
276
	def security_update_temporary_sources_list(self):
352
	def security_update_temporary_sources_list(self):
277
		'''Create a list of debian repository statements for the next security update'''
353
		'''Create a list of debian repository statements for the next security update
354
		>>> uup.security_update_temporary_sources_list()
355
		['deb http://apt.knut.univention.de:80/2.3/maintained/ sec1/all/', 'deb http://apt.knut.univention.de:80/2.3/maintained/ sec1/extern/', 'deb http://apt.knut.univention.de:80/2.3/maintained/ sec1/i386/']
356
		'''
278
		sources_list = []
357
		sources_list = []
279
		for part in self.parts:
358
		repConf = { 'server':str(self.repository()), 'version':self.ucs_version }
359
		for repConf['part'] in self.parts:
280
			# for example: http://apt.univention.de/2.0/maintained/
360
			# for example: http://apt.univention.de/2.0/maintained/
281
			path='/%s/%s/' % (self.ucs_version, part)
361
			path = '/%(version)s/%(part)s/' % repConf
282
			if not self.net_path_exists(path):
362
			if not self.net_path_exists(path):
283
				continue
363
				continue
284
364
285
			next_security_version = int(self.security_patchlevel) + 1
365
			repConf['sec'] = next_security_version = int(self.security_patchlevel) + 1
286
			path='/%s/%s/sec%s/' % (self.ucs_version, part, next_security_version)
366
			path = '/%(version)s/%(part)s/sec%(sec)d/' % repConf
287
			if self.net_path_exists(path):
367
			if self.net_path_exists(path):
288
				for arch in ['all', 'extern'] + self.architectures:
368
				for repConf['arch'] in ['all', 'extern'] + self.architectures:
289
					path='/%s/%s/sec%s/%s/' % (self.ucs_version, part, next_security_version, arch)
369
					path = '/%(version)s/%(part)s/sec%(sec)d/%(arch)s/' % repConf
290
					if self.net_path_exists(path):
370
					if self.net_path_exists(path):
291
						sources_list.append('deb http://%s/%s/%s/%s/ sec%s/%s/' % (self.repository_server, self.repository_prefix, self.ucs_version, part, next_security_version, arch))
371
						sources_list.append('deb %(server)s%(version)s/%(part)s/ sec%(sec)d/%(arch)s/' % repConf)
292
372
293
		return sources_list
373
		return sources_list
294
374
295
	def security_update_available(self):
375
	def security_update_available(self):
296
		'''Check for the security version for the current version'''
376
		'''Check for the security version for the current version.
377
		>>> uup.security_update_available()
378
		'sec1'
379
		'''
297
		for part in self.parts:
380
		for part in self.parts:
298
			# for example: http://apt.univention.de/2.0/maintained/
381
			# for example: http://apt.univention.de/2.0/maintained/
299
			path='/%s/%s/' % (self.ucs_version, part)
382
			path='/%s/%s/' % (self.ucs_version, part)
Lines 308-327 Link Here
308
		return False
391
		return False
309
392
310
	def get_ucs_version(self):
393
	def get_ucs_version(self):
394
		'''Return current UCS version (major.minor-patchlevel).
395
		>>> uup.get_ucs_version()
396
		'2.3-0'
397
		'''
311
		return '%s-%s' % (self.ucs_version, self.patchlevel)
398
		return '%s-%s' % (self.ucs_version, self.patchlevel)
312
399
313
	def get_components(self):
400
	def get_components(self):
314
		'''Retrieve all enabled components from registry as list'''
401
		'''Retrieve all enabled components from registry as list.
402
		>>> uup.get_components()
403
		['ucsschool']
404
		'''
315
		components = []
405
		components = []
316
		for key in self.configRegistry.keys():
406
		for key in self.configRegistry.keys():
317
			if key.startswith('repository/online/component/'):
407
			if key.startswith('repository/online/component/'):
318
				component_part = key.split('repository/online/component/')[1]
408
				component_part = key.split('repository/online/component/')[1]
319
				if component_part.find('/') == -1 and self.configRegistry[key].lower() in [ 'true', 'yes', 'enabled', '1']:
409
				if component_part.find('/') == -1 and self.ucr_bool(key, False):
320
					components.append(component_part)
410
					components.append(component_part)
321
		return components
411
		return components
322
412
323
	def get_all_components(self):
413
	def get_all_components(self):
324
		'''Retrieve all configured components from registry as list'''
414
		'''Retrieve all configured components from registry as list.
415
		>>> uup.get_all_components()
416
		['udm', 'ucsschool']
417
		'''
325
		components = []
418
		components = []
326
		for key in self.configRegistry.keys():
419
		for key in self.configRegistry.keys():
327
			if key.startswith('repository/online/component/'):
420
			if key.startswith('repository/online/component/'):
Lines 331-337 Link Here
331
		return components
424
		return components
332
425
333
	def get_component(self, name):
426
	def get_component(self, name):
334
		'''Retrieve named component from registry as hash'''
427
		'''Retrieve named component from registry as hash
428
		>>> uup.get_component('udm')
429
		{'description': 'udm?', 'activated': 'disabled', 'name': 'udm', 'server': 'apt.knut.univention.de'}
430
		'''
335
		component = {}
431
		component = {}
336
		for key in self.configRegistry.keys():
432
		for key in self.configRegistry.keys():
337
			component['activated'] = self.configRegistry['repository/online/component/%s' % name]
433
			component['activated'] = self.configRegistry['repository/online/component/%s' % name]
Lines 346-352 Link Here
346
		'''Return a string of Debian repository statements for all UCS versions
442
		'''Return a string of Debian repository statements for all UCS versions
347
		between start and end.
443
		between start and end.
348
		For dists=True, additional entries for the parts below dists/ are also added.
444
		For dists=True, additional entries for the parts below dists/ are also added.
349
		For clean=True, additional clean statements are added if online/repository/clean is enabled.'''
445
		For clean=True, additional clean statements are added if online/repository/clean is enabled.
446
447
		>>> uup.print_version_repositories(clean=True,dists=True,start=UCS_Version('2.2-0'),end=UCS_Version('2.2-1')).split(chr(10))
448
		['deb http://apt.knut.univention.de:80/2.2/maintained/2.2-0 dists/univention/main/binary-i386/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ 2.2-0/all/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ 2.2-0/extern/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ 2.2-0/i386/', 'clean http://apt.knut.univention.de:80/2.2/maintained/2.2-0/', '', 'deb http://apt.knut.univention.de:80/2.2/maintained/ 2.2-1/all/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ 2.2-1/extern/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ 2.2-1/i386/', 'clean http://apt.knut.univention.de:80/2.2/maintained/2.2-1/', '', '']
449
		'''
350
		repos = ''
450
		repos = ''
351
		if not self.online_repository:
451
		if not self.online_repository:
352
			return repos
452
			return repos
Lines 360-415 Link Here
360
			end = UCS_Version( ( self.version_major, self.version_minor, self.patchlevel ) )
460
			end = UCS_Version( ( self.version_major, self.version_minor, self.patchlevel ) )
361
461
362
		if clean:
462
		if clean:
363
			clean = self.configRegistry.get( 'online/repository/clean', False )
463
			clean = self.ucr_bool('online/repository/clean', False)
364
464
465
		repConf = { 'server':str(self.repository()) }
365
		while start <= end:
466
		while start <= end:
467
			repConf.update(major=start.major, minor=start.minor, patch=start.patchlevel)
366
			# for example: http://apt.univention.de/2.0/
468
			# for example: http://apt.univention.de/2.0/
367
			path='/%s.%s/' % (start.major, start.minor)
469
			path='/%(major)d.%(minor)d/' % repConf
368
			if not self.net_path_exists( path ):
470
			if not self.net_path_exists( path ):
369
				start.minor += 1
471
				start.minor += 1
370
				continue
472
				continue
371
			if dists:
473
			if dists:
372
				path_base = '/%s.%s/maintained/%s.%s-%s' % ( start.major, start.minor, start.major, start.minor, start.patchlevel )
474
				path_base = '%(major)d.%(minor)d/maintained/%(major)d.%(minor)d-%(patch)d' % repConf
373
				if self.net_path_exists( '%s/dists/' %  path_base ):
475
				if self.net_path_exists( '%s/dists/' %  path_base ):
374
					for arch in self.architectures:
476
					for arch in self.architectures:
375
						path = '%s/dists/univention/main/binary-%s/' % ( path_base, arch )
477
						path = '%s/dists/univention/main/binary-%s/' % ( path_base, arch )
376
						if self.net_path_exists( path ):
478
						if self.net_path_exists( path ):
377
							if self.repository_prefix:
479
							repos += 'deb %s%s dists/univention/main/binary-%s/\n' % ( self.repository(), path_base, arch )
378
								repos += 'deb http://%s/%s%s dists/univention/main/binary-%s/\n' % ( self.repository_server, self.repository_prefix, path_base, arch )
480
			for repConf['part'] in self.parts:
379
							else:
380
								repos += 'deb http://%s%s dists/univention/main/binary-%s/\n' % ( self.repository_server, path_base, arch )
381
			for part in self.parts:
382
				# for example: http://apt.univention.de/2.0/maintained/
481
				# for example: http://apt.univention.de/2.0/maintained/
383
				path='/%s.%s/%s/' % (start.major, start.minor, part)
482
				path='/%(major)d.%(minor)d/%(part)s/' % repConf
384
				if not self.net_path_exists(path):
483
				if not self.net_path_exists(path):
385
					continue
484
					continue
386
				patch_inc = UCS_Version( ( start.major, start.minor, start.patchlevel ) )
485
				patch_inc = UCS_Version( ( start.major, start.minor, start.patchlevel ) )
387
				# as long as we do just increase the patch level ...
486
				# as long as we do just increase the patch level ...
388
				while patch_inc.major == start.major and patch_inc.minor == start.minor:
487
				while patch_inc.major == start.major and patch_inc.minor == start.minor:
389
					path='/%s.%s/%s/%s.%s-%s/' % ( patch_inc.major, patch_inc.minor, part, patch_inc.major, patch_inc.minor, patch_inc.patchlevel )
488
					repConf.update(major=patch_inc.major, minor=patch_inc.minor, patch=patch_inc.patchlevel)
489
					path='/%(major)d.%(minor)d/%(part)s/%(major)d.%(minor)d-%(patch)d/' % repConf
390
					if not self.net_path_exists(path):
490
					if not self.net_path_exists(path):
391
						break
491
						break
392
492
393
					# the helper variable printed is to be used to print a blank line at the end of a block
493
					# the helper variable printed is to be used to print a blank line at the end of a block
394
					printed = False
494
					printed = False
395
					for arch in ['all', 'extern'] + self.architectures:
495
					for repConf['arch'] in ['all', 'extern'] + self.architectures:
396
						# for example: http://apt.univention.de/2.0/maintained/2.0-1
496
						# for example: http://apt.univention.de/2.0/maintained/2.0-1
397
						path='/%s.%s/%s/%s.%s-%s/%s/Packages.gz' % ( patch_inc.major, patch_inc.minor, part, patch_inc.major, patch_inc.minor, patch_inc.patchlevel, arch )
497
						path='/%(major)d.%(minor)d/%(part)s/%(major)d.%(minor)d-%(patch)d/%(arch)s/Packages.gz' % repConf
398
						if not self.net_path_exists(path):
498
						if not self.net_path_exists(path):
399
							continue
499
							continue
400
						printed = True
500
						printed = True
401
						if self.repository_prefix:
501
						repos += 'deb %(server)s%(major)d.%(minor)d/%(part)s/ %(major)d.%(minor)d-%(patch)d/%(arch)s/\n' % repConf
402
							path = 'http://%s/%s/%s.%s/%s/' % ( self.repository_server, self.repository_prefix, patch_inc.major, patch_inc.minor, part )
403
						else:
404
							path = 'http://%s/%s.%s/%s/' % ( self.repository_server, patch_inc.major, patch_inc.minor, part )
405
						repos += 'deb %s %s.%s-%s/%s/\n' % ( path, patch_inc.major, patch_inc.minor , patch_inc.patchlevel, arch)
406
502
407
					if clean:
503
					if clean:
408
						if self.repository_prefix:
504
						repos += 'clean %(server)s%(major)d.%(minor)d/%(part)s/%(major)d.%(minor)d-%(patch)d/\n' % repConf
409
							path = 'http://%s/%s/%s.%s/%s/' % ( self.repository_server, self.repository_prefix, patch_inc.major, patch_inc.minor, part )
410
						else:
411
							path = 'http://%s/%s.%s/%s/' % ( self.repository_server, patch_inc.major, patch_inc.minor, part )
412
						repos += 'clean %s/%s.%s-%s/\n' % ( path, patch_inc.major, patch_inc.minor , patch_inc.patchlevel )
413
505
414
					if printed:
506
					if printed:
415
						repos += '\n'
507
						repos += '\n'
Lines 433-439 Link Here
433
		updates for UCS versions between start and end.
525
		updates for UCS versions between start and end.
434
		For clean=True, additional clean statements are added if online/repository/clean is enabled.
526
		For clean=True, additional clean statements are added if online/repository/clean is enabled.
435
		For all_security_updates=True, all available instead of all needed
527
		For all_security_updates=True, all available instead of all needed
436
		statements for security updates are returned.'''
528
		statements for security updates are returned.
529
		
530
		>>> uup.print_security_repositories(clean=True,start=UCS_Version('2.2-0'),end=UCS_Version('2.2-1')).split(chr(10))
531
		['deb http://apt.knut.univention.de:80/2.2/maintained/ sec1/all/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec1/extern/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec1/i386/', 'clean http://apt.knut.univention.de:80/2.2/maintained/sec1/', '', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec2/all/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec2/extern/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec2/i386/', 'clean http://apt.knut.univention.de:80/2.2/maintained/sec2/', '', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec3/all/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec3/extern/', 'deb http://apt.knut.univention.de:80/2.2/maintained/ sec3/i386/', 'clean http://apt.knut.univention.de:80/2.2/maintained/sec3/', '', '']
532
		'''
437
		repos = ''
533
		repos = ''
438
		if not self.online_repository:
534
		if not self.online_repository:
439
			return repos
535
			return repos
Lines 449-487 Link Here
449
		if clean:
545
		if clean:
450
			clean = self.configRegistry.get( 'online/repository/clean', False )
546
			clean = self.configRegistry.get( 'online/repository/clean', False )
451
547
452
		while start <=end:
548
		repConf = { 'server':str(self.repository()) }
549
		while start <= end:
550
			repConf.update({ 'major':start.major, 'minor':start.minor, 'patch':start.patchlevel })
453
			# check for the security version for the current version
551
			# check for the security version for the current version
454
			for part in self.parts:
552
			for repConf['part'] in self.parts:
455
				# for example: http://apt.univention.de/2.0/maintained/
553
				# for example: http://apt.univention.de/2.0/maintained/
456
				path='/%d.%d/%s/' % ( start.major, start.minor, part)
554
				path='/%(major)d.%(minor)d/%(part)s/' % repConf
457
				if not self.net_path_exists(path):
555
				if not self.net_path_exists(path):
458
					continue
556
					continue
459
				# I think we won't release more than 100 security releases for one UCS release ...
557
				# I think we won't release more than 100 security releases for one UCS release ...
460
				for p in range(1, 100):
558
				for p in range(1, 100):
559
					repConf['sec'] = p
461
					# the sources.list should just contain the already installed seucurity repos; the mirror list should contain all available security repos
560
					# the sources.list should just contain the already installed seucurity repos; the mirror list should contain all available security repos
462
					if not all_security_updates and start.major == int( self.version_major ) and start.minor == int( self.version_minor )  and p > int( self.security_patchlevel ):
561
					if not all_security_updates and start.major == int( self.version_major ) and start.minor == int( self.version_minor )  and p > int( self.security_patchlevel ):
463
						break
562
						break
464
563
465
					path='/%d.%d/%s/sec%s/' % ( start.major, start.minor, part, p )
564
					path='/%(major)d.%(minor)d/%(part)s/sec%(sec)d/' % repConf
466
					if not self.net_path_exists(path):
565
					if not self.net_path_exists(path):
467
						break
566
						break
468
567
469
					printed =  False
568
					printed =  False
470
					for arch in ['all', 'extern'] + self.architectures:
569
					for repConf['arch'] in ['all', 'extern'] + self.architectures:
471
						# for example: http://apt.univention.de/2.0/maintained/sec1
570
						# for example: http://apt.univention.de/2.0/maintained/sec1
472
						path='/%d.%d/%s/sec%s/%s/Packages.gz' % (start.major, start.minor, part, p, arch )
571
						path='/%(major)d.%(minor)d/%(part)s/sec%(sec)s/%(arch)s/Packages.gz' % repConf
473
						if not self.net_path_exists(path):
572
						if not self.net_path_exists(path):
474
							continue
573
							continue
475
						printed = True
574
						printed = True
476
						if self.repository_prefix:
575
						repos += 'deb %(server)s%(major)d.%(minor)d/%(part)s/ sec%(sec)d/%(arch)s/\n' % repConf
477
							repos += 'deb http://%s/%s/%d.%d/%s/ sec%s/%s/\n' % ( self.repository_server, self.repository_prefix, start.major, start.minor, part, p, arch)
478
						else:
479
							repos += 'deb http://%s/%d.%d/%s/ sec%s/%s/\n' % ( self.repository_server, start.major, start.minor, part, p, arch)
480
					if clean:
576
					if clean:
481
						if self.repository_prefix:
577
						repos += 'clean %(server)s%(major)d.%(minor)d/%(part)s/sec%(sec)d/\n' % repConf
482
							repos += 'clean http://%s/%s/%d.%d/%s/sec%s/%s/\n' % ( self.repository_server, self.repository_prefix, start.major, start.minor, part, p )
483
						else:
484
							repos += 'clean http://%s/%d.%d/%s/sec%s/%s/\n' % ( self.repository_server, start.major, start.minor, part, p )
485
					if printed:
578
					if printed:
486
						repos += '\n'
579
						repos += '\n'
487
						printed = False
580
						printed = False
Lines 489-503 Link Here
489
				# check for hotfixes?
582
				# check for hotfixes?
490
				if not self.hotfixes:
583
				if not self.hotfixes:
491
					continue
584
					continue
492
				path = '/%s/%s/hotfixes/' % ( self.ucs_version, part )
585
				path = '/%(major)d.%(minor)d/%(part)s/hotfixes/' % repConf
493
				if self.net_path_exists( path ):
586
				if self.net_path_exists( path ):
494
					for arch in [ 'all', 'extern' ] + self.architectures:
587
					for repConf['arch'] in [ 'all', 'extern' ] + self.architectures:
495
						path='/%s/%s/hotfixes/%s/Packages.gz' % ( self.ucs_version, part, arch )
588
						path='/%(major)d.%(minor)d/%(part)s/hotfixes/%(arch)s/Packages.gz' % repConf
496
						if self.net_path_exists( path ):
589
						if self.net_path_exists( path ):
497
							if self.repository_prefix:
590
							repos += 'deb %(server)s%(major)d.%(minor)d/%(part)s/ hotfixes/%(arch)s/\n' % repConf
498
								repos += 'deb http://%s/%s/%s/%s/ hotfixes/%s/\n' % ( self.repository_server, self.repository_prefix, self.ucs_version, part, arch )
499
							else:
500
								repos += 'deb http://%s/%s/%s/ hotfixes/%s/\n' % ( self.repository_server, self.ucs_version, part, arch )
501
591
502
			start.minor += 1
592
			start.minor += 1
503
			# is there a minor version update
593
			# is there a minor version update
Lines 515-521 Link Here
515
605
516
	def print_component_repositories( self, clean = False ):
606
	def print_component_repositories( self, clean = False ):
517
		'''Return a string of Debian repository statements for all enabled components.
607
		'''Return a string of Debian repository statements for all enabled components.
518
		For clean=True, additional clean statements are added if online/repository/clean is enabled.'''
608
		For clean=True, additional clean statements are added if online/repository/clean is enabled.
609
610
		>>> uup.print_component_repositories(clean=True).split(chr(10))
611
		# The site http://apt.knut.univention.de:80/2.3/maintained/component/ucsschool/Packages.gz was not found
612
		['deb http://apt.knut.univention.de:80/2.3/maintained/component ucsschool/all/', 'deb http://apt.knut.univention.de:80/2.3/maintained/component ucsschool/extern/', 'deb http://apt.knut.univention.de:80/2.3/maintained/component ucsschool/i386/', '', '']
613
		'''
519
		repos = ''
614
		repos = ''
520
		if not self.online_repository:
615
		if not self.online_repository:
521
			return repos
616
			return repos
Lines 523-609 Link Here
523
		version_part_left = int( self.version_major )
618
		version_part_left = int( self.version_major )
524
		version_part_right = int( self.version_minor )
619
		version_part_right = int( self.version_minor )
525
		if clean:
620
		if clean:
526
			clean = self.configRegistry.get( 'online/repository/clean', False )
621
			clean = self.ucr_bool('online/repository/clean', False)
527
622
528
		components = []
623
		components = []
529
		for key in self.configRegistry.keys():
624
		for key in self.configRegistry.keys():
530
			if key.startswith('repository/online/component/'):
625
			if key.startswith('repository/online/component/'):
531
				component_part = key.split('repository/online/component/')[1]
626
				component_part = key.split('repository/online/component/')[1]
532
				if component_part.find('/') == -1 and self.configRegistry[key].lower() in [ 'true', 'yes', 'enabled', '1']:
627
				if component_part.find('/') == -1 and self.ucr_bool(key, False):
533
					components.append(component_part)
628
					components.append(component_part)
534
629
535
		for component in components:
630
		for component in components:
536
			if not self.is_repository_server:
631
			if not self.is_repository_server:
537
				repository_server = self.configRegistry.get('repository/online/component/%s/server' % component, self.repository_server)
632
				config = RepositoryConfig()
633
				config.repositoryFromRegistry(self.configRegistry, 'repository/online/component/%s' % component)
634
				repository = config.repository()
538
			else:
635
			else:
539
				repository_server = self.repository_server
636
				repository = self.repository()
540
			repository_port = self.configRegistry.get('repository/online/component/%s/port' % component, self.repository_port)
541
			prefix_var = 'repository/online/component/%s/prefix' % component
542
			repository_prefix = self.configRegistry.get( 'repository/online/component/%s/prefix' % component, '' )
543
637
544
			versions = self.configRegistry.get('repository/online/component/%s/version' % component, self.ucs_version).split(',')
638
			versions = self.configRegistry.get('repository/online/component/%s/version' % component, self.ucs_version).split(',')
545
			parts = self.configRegistry.get('repository/online/component/%s/parts' % component, 'maintained').split(',')
639
			parts = self.configRegistry.get('repository/online/component/%s/parts' % component, 'maintained').split(',')
546
			username = self.configRegistry.get('repository/online/component/%s/username' % component, None)
547
			password = self.configRegistry.get('repository/online/component/%s/password' % component, None)
548
			if clean:
640
			if clean:
549
				clean = self.configRegistry.get( 'repository/online/component/%s/clean' % component, False )
641
				clean = self.ucr_bool('repository/online/component/%s/clean' % component, False)
550
642
551
			# allow None as a component prefix
643
			repConf = { 'server':str(repository), 'component':component }
552
			if repository_prefix.lower() == 'none':
553
				repository_prefix = ''
554
			elif not repository_prefix:
555
				# check for prefix on component repository server (if the repository server is reachable)
556
				try:
557
					if self.net_path_exists( '/univention-repository/', server = repository_server, port = repository_port, username = username, password = password ):
558
						repository_prefix = 'univention-repository'
559
					elif self.net_path_exists( '/%s/' % self.repository_prefix, server = repository_server, port = repository_port, username = username, password = password ):
560
						repository_prefix = self.repository_prefix
561
				except:
562
					repository_prefix = ''
563
564
			for version in versions:
644
			for version in versions:
565
				if version == 'current':
645
				if version == 'current':
566
					version = self.ucs_version
646
					version = self.ucs_version
567
				for part in parts:
647
				repConf['version'] = version
568
					auth_string = ''
648
				for repConf['part'] in parts:
569
					if username and password:
570
						auth_string = '%s:%s@' % (username, password)
571
					#2.0/maintained/component/
649
					#2.0/maintained/component/
572
					path = '/%s/%s/component/%s/' % ( version, part, component )
650
					path = '/%(version)s/%(part)s/component/%(component)s/' % repConf
573
					if not self.net_path_exists(path, server=repository_server, port=repository_port, prefix=repository_prefix, username=username, password=password, debug=True):
651
					if not self.net_path_exists(path, repository, debug=True):
574
						continue
652
						continue
575
					printed = False
653
					printed = False
576
654
577
					# support a diffrent repository
655
					# support a diffrent repository
578
					path = '/%s/%s/component/%s/Packages.gz' % ( version, part, component )
656
					path = '/%(version)s/%(part)s/component/%(component)s/Packages.gz' % repConf
579
					if self.net_path_exists(path, server=repository_server, port=repository_port, prefix=repository_prefix, username=username, password=password, debug=True):
657
					if self.net_path_exists(path, repository, debug=True):
580
						if repository_prefix:
658
						path = '%(server)s%(version)s/%(part)s/component/%(component)s/' % repConf
581
							path = 'http://%s%s/%s/%s/%s/component/%s/' % ( auth_string, repository_server, repository_prefix, version, part, component)
659
						repos += 'deb %s ./\n' % path
582
						else:
583
							path = 'http://%s%s/%s/%s/component/%s/' % ( auth_string, repository_server, version, part, component)
584
						repos += 'deb %s ./ \n' % path
585
						if clean:
660
						if clean:
586
							repos += 'clean %s\n' % path
661
							repos += 'clean %s\n' % path
587
						printed = True
662
						printed = True
588
					else:
663
					else:
589
						for arch in ['all', 'extern'] + self.architectures:
664
						for repConf['arch'] in ['all', 'extern'] + self.architectures:
590
							path = '/%s/%s/component/%s/%s/' % ( version, part, component, arch )
665
							path = '/%(version)s/%(part)s/component/%(component)s/%(arch)s/' % repConf
591
							if not self.net_path_exists(path, server=repository_server, port=repository_port, prefix=repository_prefix, username=username, password=password, debug=True):
666
							if not self.net_path_exists(path, repository, debug=True):
592
								continue
667
								continue
593
							printed = True
668
							printed = True
594
							if repository_prefix:
669
							repos += 'deb %(server)s%(version)s/%(part)s/component %(component)s/%(arch)s/\n' % repConf
595
								path = 'http://%s%s/%s/%s/%s/' % ( auth_string, repository_server, repository_prefix, version, part )
596
							else:
597
								path = 'http://%s%s/%s/%s/' % ( auth_string, repository_server, version, part )
598
							repos += 'deb %scomponent %s/%s/\n' % ( path, component, arch )
599
					if clean:
670
					if clean:
600
						if repository_prefix:
671
						repos += 'clean %(server)s%(version)s/%(part)s/component/%(component)s/\n' % repConf
601
							path = 'http://%s%s/%s/%s/%s/' % ( auth_string, repository_server, repository_prefix, version, part )
602
						else:
603
							path = 'http://%s%s/%s/%s/' % ( auth_string, repository_server, version, part )
604
						repos += 'clean %s/component/%s/\n' % ( path, component )
605
					if printed:
672
					if printed:
606
						repos += '\n'
673
						repos += '\n'
607
						printed = False
674
						printed = False
608
675
609
		return repos
676
		return repos
677
678
if __name__ == '__main__':
679
	# repository_mirror_basepath="/var/lib/univention-repository"
680
	# repository_mirror="yes"
681
	# repository_online_component_ucsschool_description="UCS School"
682
	# repository_online_component_ucsschool_server="apt.knut.univention.de"
683
	# repository_online_component_ucsschool="enabled"
684
	# repository_online_component_udm_description="udm?"
685
	# repository_online_component_udm_server="apt.knut.univention.de"
686
	# repository_online_component_udm="disabled"
687
	# repository_online_hotfixes="no"
688
	# repository_online_maintained="yes"
689
	# repository_online_port="80"
690
	# repository_online_server="apt.knut.univention.de"
691
	# repository_online_unmaintained="no"
692
	# repository_online="yes"
693
	# local_repository=""
694
	# version_patchlevel="0
695
	# version_security_patchlevel="0
696
	# version_version="2.3"
697
	uup = UniventionUpdater()
698
	import doctest
699
	doctest.testmod()

Return to bug 15550