|
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() |