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

Collapse All | Expand All

(-)umc/python/updater/de.po (-7 / +11 lines)
 Lines 3-9    Link Here 
3
msgstr ""
3
msgstr ""
4
"Project-Id-Version: univention-management-console-module-updater\n"
4
"Project-Id-Version: univention-management-console-module-updater\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
6
"POT-Creation-Date: 2012-11-05 09:45+0100\n"
6
"POT-Creation-Date: 2013-10-01 06:51+0200\n"
7
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
7
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
"Language-Team: LANGUAGE <LL@li.org>\n"
9
"Language-Team: LANGUAGE <LL@li.org>\n"
 Lines 12-39    Link Here 
12
"Content-Type: text/plain; charset=UTF-8\n"
12
"Content-Type: text/plain; charset=UTF-8\n"
13
"Content-Transfer-Encoding: 8bit\n"
13
"Content-Transfer-Encoding: 8bit\n"
14
14
15
#: umc/python/updater/__init__.py:108
15
#: umc/python/updater/__init__.py:107
16
msgid "Install all available updates for the current release"
16
msgid "Install all available updates for the current release"
17
msgstr "Alle verfügbaren Aktualisierungen installieren"
17
msgstr "Alle verfügbaren Aktualisierungen installieren"
18
18
19
#: umc/python/updater/__init__.py:101
19
#: umc/python/updater/__init__.py:100
20
msgid "Install all package updates"
20
msgid "Install all package updates"
21
msgstr "Alle Paket-Aktualisierungen installieren"
21
msgstr "Alle Paket-Aktualisierungen installieren"
22
22
23
#: umc/python/updater/__init__.py:95
23
#: umc/python/updater/__init__.py:94
24
#, python-format
24
#, python-format
25
msgid "Perform release update up to version '%s'"
25
msgid "Perform release update up to version '%s'"
26
msgstr "Release auf Version '%s' aktualisieren"
26
msgstr "Release auf Version '%s' aktualisieren"
27
27
28
#: umc/python/updater/__init__.py:705
28
#: umc/python/updater/__init__.py:925
29
msgid "Unknown"
29
msgid "Unknown"
30
msgstr "Unbekannt"
30
msgstr "Unbekannt"
31
31
32
#: umc/python/updater/__init__.py:275
32
#: umc/python/updater/__init__.py:248
33
msgid "Updating system"
34
msgstr "Aktualisierung des Systems"
35
36
#: umc/python/updater/__init__.py:514
33
msgid "latest version"
37
msgid "latest version"
34
msgstr "neueste Version"
38
msgstr "neueste Version"
35
39
36
#: umc/python/updater/__init__.py:382
40
#: umc/python/updater/__init__.py:648
37
msgid "unknown"
41
msgid "unknown"
38
msgstr "unbekannt"
42
msgstr "unbekannt"
39
43
(-)umc/python/updater/__init__.py (-68 / +288 lines)
 Lines 39-57    Link Here 
39
import univention.config_registry
39
import univention.config_registry
40
40
41
import re
41
import re
42
from os import stat, getpid
42
from os import stat, getpid, path, SEEK_END, lseek
43
from time import time
43
from time import time, sleep
44
from subprocess import Popen
44
from subprocess import Popen
45
from hashlib import md5
45
from hashlib import md5
46
from copy import deepcopy
46
from copy import deepcopy
47
import univention.hooks
47
import univention.hooks
48
import notifier.threads
48
import notifier.threads
49
50
from univention.management.console.log import MODULE
49
from univention.management.console.log import MODULE
51
from univention.management.console.protocol.definitions import *
50
from univention.management.console.protocol.definitions import *
52
53
from univention.updater import UniventionUpdater
51
from univention.updater import UniventionUpdater
54
52
53
55
_ = umc.Translation('univention-management-console-module-updater').translate
54
_ = umc.Translation('univention-management-console-module-updater').translate
56
55
57
# Base UCR path definitions
56
# Base UCR path definitions
 Lines 169-174    Link Here 
169
168
170
		return self._last_returned_stamp
169
		return self._last_returned_stamp
171
170
171
class Progress(object):
172
	"""Class to get the progress of updates according
173
	to the log file (/var/log/univention/updater.log).
174
	 Output is stored in a dict to be polled by a progress bar
175
	in auto mode
176
	"""
177
178
179
180
	def __init__(self, versions, nrPackageTotal):
181
		self._log_versions = versions
182
		self.nrPackageTotal = nrPackageTotal
183
		self._steps = 0
184
		self._iPackage = 0
185
		self._addPackages = True
186
		self._ipercent = 0
187
		self._log_packageLines =[]
188
		self._countDownloadedPackages = False
189
		self._istep = 0
190
		self._log_finalVersion = []
191
		self._log_currentVersion = []
192
		self._percent_output = 0
193
		self._did_run_before = False
194
		self._log_lineOriginal = ''
195
		self._update_finished = False
196
		self._update_errors = []
197
		self._update_error_critical = False
198
		self.values = {}
199
200
	def startMonitoring(self,logSize1,job):
201
		""" main function of class Progress 
202
		looks for changes in log size. If size is different
203
		starts processing of log and returns new log size"""
204
		
205
206
		if not self._did_run_before: 
207
			# ----------- DEBUG -----------------
208
			MODULE.info("Percent is running")
209
			MODULE.info("Packages so far: %d "%self.nrPackageTotal)
210
			MODULE.info(" %s " %self._log_versions)	
211
			# -----------------------------------
212
			self._did_run_before = True
213
		self.job = job
214
		data = '/var/log/univention/updater.log'		
215
		newlines = []
216
		logSize2 = int(path.getsize(data))
217
		if logSize2 <= logSize1:
218
			return (logSize2)
219
		with open(data) as z:
220
			z.seek((logSize1-logSize2),SEEK_END)
221
			self.processNewLines(z.readlines())
222
		self.poll();
223
		return logSize2
224
		
225
	def poll(self):
226
		""" polling function to feed an automated progress bar
227
		 refurbishes the data just like our little progress bar likes it """
228
229
		regStatus = re.compile(r"status=(?P<state>\w+)")
230
		if not self.job:
231
			self._update_error_critical = True
232
			self._update_finished = True
233
		else:
234
			with open(INSTALLERS[self.job]['statusfile']) as s:
235
				lines = s.readlines()
236
				for line in lines:
237
					line = line.lower()
238
					matchStatus = regStatus.match(line)
239
					if matchStatus:			
240
						if matchStatus.group("state") == 'failed':
241
							self._update_error_critical = True
242
							self._update_finished = True	
243
						if matchStatus.group("state") == 'success':
244
							self._update_finished = True
245
		self.values = dict(
246
			finished=self._update_finished,
247
			steps=self._percent_output,
248
			component=_('Updating system'),
249
			info=self._log_lineOriginal,
250
			errors=self._update_errors,		
251
			critical=self._update_error_critical
252
		)
253
254
	
255
256
	def processNewLines(self, newlines):
257
		"""Read unprocessed lines from log file and process them."""
258
		for line in newlines:
259
			self._log_lineOriginal = line
260
			line = line.lower()
261
			# any line with 'error:' at the beginning will be collected for error handling
262
			if line.startswith('error:'):
263
				self._update_errors.append(self._log_lineOriginal)
264
				MODULE.error (" WARNING: %s "%self._log_lineOriginal)
265
			if not self.nrPackageTotal:
266
				self.preDistUpgrade(line)
267
			else:
268
				self.countPackages(line)
269
	
270
			if self._log_finalVersion:
271
				self.findCurrentVersion(line)
272
273
			# safety-switch so only the right 'Get:'s are counted
274
			if not self._countDownloadedPackages:
275
				if line.startswith('need to get') or line.startswith('after this operation') :
276
					self._countDownloadedPackages = True
277
						
278
279
280
281
	def findCurrentVersion(self, line):
282
		""" in case of a dist-upgrade find the current version """
283
		regCurrVers = re.compile(r"version=(?P<currVersion>[0-9.]+).*")
284
		regCurrPatch = re.compile(r"patchlevel=(?P<currPatch>[0-9]*).*")
285
		matchCurrVers = regCurrVers.match(line)
286
		if matchCurrVers:			
287
			self._log_currentVersion = []
288
			self._log_currentVersion.append(matchCurrVers.group("currVersion"))
289
290
			# ----------- DEBUG -----------------
291
			MODULE.info(" Found Version= %s " %self._log_currentVersion)
292
			# -----------------------------------
293
294
		matchCurrPatch = regCurrPatch.match(line)
295
		if matchCurrPatch:
296
			MODULE.info (" Found Patchlevel= %s " %matchCurrPatch.group("currPatch"))
297
			self._log_currentVersion.append('-')
298
			self._log_currentVersion.append(matchCurrPatch.group("currPatch"))
299
			self._log_currentVersion = ''.join(self._log_currentVersion)
300
301
			# ----------- DEBUG -----------------
302
			MODULE.info(" Current Version : %s " %self._log_currentVersion)
303
			# -----------------------------------
304
305
			#end if Current Version = Final Version
306
			if self._log_currentVersion == self._log_finalVersion :
307
				MODULE.info (' trigger update finished ')
308
				self._percent_output = 100
309
				self._update_finished = True
310
				self.nrPackageTotal = 0
311
			else :
312
			# else reset counter between upgrade-steps
313
314
				# ----------- DEBUG -----------------
315
				MODULE.info (" Resetting counter ")
316
				# -----------------------------------
317
318
				self.nrPackageTotal = 0
319
				self._countDownloadedPackages = False
320
				if self._ipercent:
321
					self._istep += 1
322
				self._iPackage = 0
323
								
324
325
326
	def increaseProgress(self):
327
		""" calculating % """
328
		self._iPackage += 0.33
329
		p = 100.0 * self._iPackage / self.nrPackageTotal
330
		if not self._steps:
331
			self._steps = 1
332
		self._ipercent = p / self._steps
333
334
		# ----------- DEBUG -----------------
335
		MODULE.info(" %.2f "%self.totalProgress)
336
		# -----------------------------------
337
338
		self._percent_output = ("%.2f" %self.totalProgress)
339
340
	@property
341
	def totalProgress(self):
342
		return self._istep * (100.0 / self._steps) + self._ipercent
343
344
	def countPackages(self, line):
345
		""" count the number of already downloaded / unpacked and progressed packages """
346
		regSettingUpOrUnpacking = re.compile(r"^(setting up|unpacking) .* \.\.\.\s*$")
347
		if line.startswith('get:') and self._countDownloadedPackages:
348
			self.increaseProgress()						
349
		if regSettingUpOrUnpacking.match(line):
350
			self.increaseProgress()
351
352
		if line.startswith('the update has been finished'):
353
			MODULE.info(' trigger update finished ')
354
			self._percent_output = 100
355
			self._update_finished = True
356
			self.nrPackageTotal = 0
357
358
359
	def preDistUpgrade(self, line):
360
		""" getting the version to wich is upgraded so we can get
361
		 the number of neccessary steps"""
362
		regStartUpdater = re.compile(r"\*\*\*\* starting univention-updater with parameter.*--updateto', '(?P<finalVersion>[0-9.-]+)'.*")
363
		if not self._log_finalVersion:
364
			matchStartUpdater = regStartUpdater.match(line)
365
			if matchStartUpdater:
366
				self._log_finalVersion = matchStartUpdater.group("finalVersion")
367
368
				# ----------- DEBUG -----------------
369
				MODULE.info(" Final Version found: %s " %self._log_finalVersion)
370
				# -----------------------------------
371
372
				if not self._steps:
373
					self._steps = len(self._log_versions[0:(self._log_versions.index(self._log_finalVersion)+1)])
374
		# if not available get number of packages to be progressed
375
		self.percdistupgrade(line)
376
377
378
379
	def percdistupgrade(self, line):
380
		""" in case no package number is gathered from pre-update procedures
381
		 this function counts the number of packages to be installed / updated """
382
		if line.startswith('the following packages will be removed'):
383
			self._addPackages = False
384
		elif line.startswith('the following new packages will be installed') or line.startswith('the following packages will be upgraded'):
385
			self._addPackages = True
386
		elif line.startswith('  ') and self._addPackages:
387
			self._log_packageLines.append(line)
388
		elif line.startswith('after this operation'):
389
			packageStr = (''.join(self._log_packageLines)).strip()
390
		        r = re.compile(r"\s+")
391
			packages = r.split(packageStr)
392
			self.nrPackageTotal = len(packages)
393
			self._log_packageLines = []
394
395
			# ----------- DEBUG -----------------
396
			MODULE.info(" Packages: %d "%self.nrPackageTotal)
397
			# -----------------------------------
398
399
			# +1 imaginary package so the progress won't 'rest' at 100%
400
			self.nrPackageTotal += 1
401
402
172
class Watched_Files(object):
403
class Watched_Files(object):
173
	""" Convenience class to monitor more than one file at a time.
404
	""" Convenience class to monitor more than one file at a time.
174
	"""
405
	"""
 Lines 211-218    Link Here 
211
	def __init__( self ):
442
	def __init__( self ):
212
		umcm.Base.__init__( self )
443
		umcm.Base.__init__( self )
213
444
445
		self.nrPackageTotal = 0
446
		self._log_versions =[]
447
		self.progress = None
448
214
		self.init_called = False
449
		self.init_called = False
215
450
451
		# get initial log size early so we don't miss any lines
452
		self.last_log_size = int(path.getsize('/var/log/univention/updater.log'))
453
		self.ori_log_size = self.last_log_size
454
216
	def init(self):
455
	def init(self):
217
		try:
456
		try:
218
			if self.init_called:
457
			if self.init_called:
 Lines 286-292    Link Here 
286
		for s in st:
525
		for s in st:
287
				MODULE.info("   >> %s" % s)
526
				MODULE.info("   >> %s" % s)
288
		# -----------------------------------
527
		# -----------------------------------
289
528
	
290
		self.finished(request.id,result)
529
		self.finished(request.id,result)
291
530
292
	def _check_thread_error( self, thread, result, request ):
531
	def _check_thread_error( self, thread, result, request ):
 Lines 307-313    Link Here 
307
			return
546
			return
308
		self.finished( request.id, result )
547
		self.finished( request.id, result )
309
548
549
	def parseprogressresult(self, request):
550
		"""Returns current updater progress """
551
		#defined earlier, this is 'just in case'
552
		if not self.last_log_size:
553
			self.last_log_size =  int(path.getsize('/var/log/univention/updater.log'))
310
554
555
		if not self.progress:
556
			self._log_versions = self.uu.get_all_available_release_updates()[0]
557
			self.progress = Progress(self._log_versions, self.nrPackageTotal)
558
559
		(self.last_log_size) = self.progress.startMonitoring(self.last_log_size,self.__which_job_is_running())						
560
561
		result = self.progress.values
562
		if result:
563
			if self.progress.values['finished']:
564
				self.progress = None
565
566
		# ----------- DEBUG -----------------
567
		MODULE.info("### updater/updates/parseprogress returns %s ###")
568
		pp = pprint.PrettyPrinter(indent=4)
569
		st = pp.pformat(result).split("\n")
570
		for s in st:
571
				MODULE.info("###   >> %s" % s)
572
		#------------------------------------
573
		
574
		self.finished( request.id, result )
575
576
311
	def call_hooks(self, request):
577
	def call_hooks(self, request):
312
		""" Calls the specified hooks and returns data given back by each hook
578
		""" Calls the specified hooks and returns data given back by each hook
313
		"""
579
		"""
 Lines 390-398    Link Here 
390
		result['install'] = sorted(result['install'])
656
		result['install'] = sorted(result['install'])
391
		result['remove'] = sorted(result['remove'])
657
		result['remove'] = sorted(result['remove'])
392
658
659
		# get number of packages
660
		nrPackageUpdated = len(result['update'])
661
		nrPackageInstalled = len(result['install'])
662
 		
663
664
		self.nrPackageTotal = nrPackageUpdated + nrPackageInstalled
665
		# add 1 imaginary packet so progress won't rest at 100 % because of post update scripts
666
		self.nrPackageTotal = self.nrPackageTotal + 1
667
	
668
393
		self.finished(request.id,result)
669
		self.finished(request.id,result)
394
670
395
671
672
396
	def updates_available(self,request):
673
	def updates_available(self,request):
397
		""" Asks if there are package updates available. (don't get confused
674
		""" Asks if there are package updates available. (don't get confused
398
			by the name of the UniventionUpdater function that is called here.)
675
			by the name of the UniventionUpdater function that is called here.)
 Lines 581-649    Link Here 
581
		self.finished(request.id, result)
858
		self.finished(request.id, result)
582
859
583
	def updater_log_file(self,request):
860
	def updater_log_file(self,request):
584
		""" returns the content of the log file associated with
585
			the job.
586
861
587
			Argument 'count' has the same meaning as already known:
862
		# replaced old code since it's not needed anymore 
588
			<0 ...... return timestamp of file (for polling)
863
		data = '/var/log/univention/updater.log'	
589
			0 ....... return whole file as a string list
864
		with open(data) as z:
590
			>0 ...... ignore this many lines, return the rest of the file
865
			result = z.readlines()
591
866
	
592
			*** NOTE *** As soon as we have looked for a running job at least once,
593
						we know the job key and can associate it here.
594
595
			TODO: honor a given 'job' argument
596
		"""
597
		# ----------- DEBUG -----------------
598
		MODULE.info("updater/installer/logfile invoked with:")
599
		pp = pprint.PrettyPrinter(indent=4)
600
		st = pp.pformat(request.options).split("\n")
601
		for s in st:
602
				MODULE.info("   << %s" % s)
603
		# -----------------------------------
604
		result = None
605
		job = ''
606
		if self._current_job and 'job' in self._current_job:
607
			job = self._current_job['job']
608
		else:
609
			job = request.options.get('job','')
610
611
		count = request.options.get('count',0)
612
		if count < 0:
613
			result = 0
614
		else:
615
			result = []
616
		if not job in INSTALLERS:
617
			# job empty: this is the first call I can't avoid
618
			if job != '':
619
				MODULE.warn("   ?? Don't know a '%s' job" % job)
620
		else:
621
			if not 'logfile' in INSTALLERS[job]:
622
				MODULE.warn("   ?? Job '%s' has no associated log file" % job)
623
			else:
624
				fname = INSTALLERS[job]['logfile']
625
				if count < 0:
626
					result = self._logstamp(fname)
627
				else:
628
					# don't read complete file if we have an 'ignore' count
629
					if ('lines' in self._current_job) and (self._current_job['lines']):
630
						count += int(self._current_job['lines'])
631
					result = self._logview(fname, -count)
632
633
		# again debug, shortened
634
		if isinstance(result,int):
635
			MODULE.info("   >> %d" % result)
636
		else:
637
			MODULE.info("   >> %d lines" % len(result))
638
639
		# ----------- DEBUG -----------------
640
		MODULE.info("updater/installer/logfile returns:")
641
		pp = pprint.PrettyPrinter(indent=4)
642
		st = pp.pformat(result).split("\n")
643
		for s in st:
644
				MODULE.info("   >> %s" % s)
645
		# -----------------------------------
646
647
		self.finished(request.id, result)
867
		self.finished(request.id, result)
648
868
649
869
 Lines 924-930    Link Here 
924
''' % (started,detail,logfile,lines,command,command)
1144
''' % (started,detail,logfile,lines,command,command)
925
		p1 = subprocess.Popen( [ 'LC_ALL=C at now', ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True )
1145
		p1 = subprocess.Popen( [ 'LC_ALL=C at now', ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True )
926
		(stdout,stderr) = p1.communicate( script )
1146
		(stdout,stderr) = p1.communicate( script )
927
1147
	
928
		if p1.returncode != 0:
1148
		if p1.returncode != 0:
929
			return (p1.returncode,stderr)
1149
			return (p1.returncode,stderr)
930
		else:
1150
		else:
(-)umc/updater.xml (+4 lines)
 Lines 41-45    Link Here 
41
		<!-- STATUS: get job status, even if job has finished -->
41
		<!-- STATUS: get job status, even if job has finished -->
42
		<command name="updater/installer/status" function="updater_job_status" />
42
		<command name="updater/installer/status" function="updater_job_status" />
43
		<command name="updater/hooks/call" function="call_hooks"/>
43
		<command name="updater/hooks/call" function="call_hooks"/>
44
		<!--PARSEPROGRESS: get update progress in % -->
45
                <command name="updater/installer/parseprogress" function="parseprogressresult"/>
46
47
	
44
	</module>
48
	</module>
45
</umc>
49
</umc>
(-)umc/de.po (-1 / +2 lines)
 Lines 3-9    Link Here 
3
msgstr ""
3
msgstr ""
4
"Project-Id-Version: univention-management-console-module-updater\n"
4
"Project-Id-Version: univention-management-console-module-updater\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
6
"POT-Creation-Date: Tue, 30 Aug 2011 23:10:28 +0200\n"
6
"POT-Creation-Date: Fri, 13 Sep 2013 04:17:09 +0200\n"
7
"PO-Revision-Date: \n"
7
"PO-Revision-Date: \n"
8
"Last-Translator: Univention GmbH <packages@univention.de>\n"
8
"Last-Translator: Univention GmbH <packages@univention.de>\n"
9
"Language-Team: Univention GmbH <packages@univention.de>\n"
9
"Language-Team: Univention GmbH <packages@univention.de>\n"
 Lines 17-19    Link Here 
17
17
18
msgid "Software update"
18
msgid "Software update"
19
msgstr "Software-Aktualisierung"
19
msgstr "Software-Aktualisierung"
20
(-)umc/js/updater.js (-44 / +81 lines)
 Lines 34-45    Link Here 
34
	"dojo/_base/array",
34
	"dojo/_base/array",
35
	"dijit/Dialog",
35
	"dijit/Dialog",
36
	"umc/dialog",
36
	"umc/dialog",
37
	"umc/tools",
37
	"umc/widgets/ConfirmDialog",
38
	"umc/widgets/ConfirmDialog",
38
	"umc/widgets/Module",
39
	"umc/widgets/Module",
39
	"umc/modules/updater/UpdatesPage",
40
	"umc/modules/updater/UpdatesPage",
40
	"umc/modules/updater/ProgressPage",
41
	"umc/widgets/ProgressBar",
42
	"umc/modules/updater/LogPage",
43
	"umc/modules/lib/server",
41
	"umc/i18n!umc/modules/updater"
44
	"umc/i18n!umc/modules/updater"
42
], function(declare, lang, array, Dialog, dialog, ConfirmDialog, Module, UpdatesPage, ProgressPage, _) {
45
], function(declare, lang, array, Dialog, dialog, tools, ConfirmDialog, Module, UpdatesPage, ProgressBar, LogPage, libServer, _) {
43
	return declare("umc.modules.updater", Module, {
46
	return declare("umc.modules.updater", Module, {
44
47
45
		// some variables related to error handling
48
		// some variables related to error handling
 Lines 49-54    Link Here 
49
		_busy_dialog: null, 		// a handle to the 'connection lost' dialog while
52
		_busy_dialog: null, 		// a handle to the 'connection lost' dialog while
50
								// queries return with errors.
53
								// queries return with errors.
51
		_error_count: 0, 		// how much errors in one row
54
		_error_count: 0, 		// how much errors in one row
55
		
56
		_reboot_required: null,
52
57
53
		buildRendering: function() {
58
		buildRendering: function() {
54
59
 Lines 60-88    Link Here 
60
				standby: lang.hitch(this, 'standby'),
65
				standby: lang.hitch(this, 'standby'),
61
				standbyDuring: lang.hitch(this, 'standbyDuring')
66
				standbyDuring: lang.hitch(this, 'standbyDuring')
62
			});
67
			});
63
			this._progress = new ProgressPage({});
68
		
69
			this._progressBar = new ProgressBar;
70
			this.own(this._progressBar);			
64
71
72
			this._log = new LogPage;
73
65
			this.addChild(this._updates);
74
			this.addChild(this._updates);
66
			this.addChild(this._progress);
75
			this.addChild(this._log);
67
76
77
			
68
			// --------------------------------------------------------------------------
78
			// --------------------------------------------------------------------------
69
			//
79
			//
70
			//		Connections that make the UI work (mostly tab switching)
71
			//
72
73
			this._progress.on('stopwatching', lang.hitch(this, function() {
74
				// Revert to the 'Updates' page if the installer action encountered
75
				// the 'reboot' affordance.
76
				this.selectChild(this._updates);
77
			}));
78
79
			// waits for the Progress Page to notify us that a job is running
80
			this._progress.on('jobstarted', lang.hitch(this, function() {
81
				this._switch_to_progress_page();
82
			}));
83
84
			// --------------------------------------------------------------------------
85
			//
86
			//		Connections that listen for changes and propagate
80
			//		Connections that listen for changes and propagate
87
			//		them to other pages
81
			//		them to other pages
88
			//
82
			//
 Lines 140-147    Link Here 
140
134
141
			// propagate the status information to other pages
135
			// propagate the status information to other pages
142
			this._updates.on('statusloaded', lang.hitch(this, function(vals) {
136
			this._updates.on('statusloaded', lang.hitch(this, function(vals) {
143
				this._progress.updateStatus(vals);
137
				this._updateStatus(vals);
144
			}));
138
			}));
139
140
			// open Log when triggered
141
			this._updates.on('clicklog', lang.hitch(this, function() {
142
				//read log every time button is clicked
143
				this._log._fetch_log();
144
				this.selectChild(this._log);
145
			}));
146
147
			// change view back to updates page (hide log)
148
			this._log.on('closelog', lang.hitch(this, function() {
149
				this.selectChild(this._updates);
150
			}));
151
152
			// shows progress bar if module is loaded while update is running in background
153
			this._updates.on('progressresume', lang.hitch(this, function() {
154
				this.standby(false);
155
				this._query_progress();
156
 			}));
145
		},
157
		},
146
158
147
		// We defer these actions until the UI is readily rendered
159
		// We defer these actions until the UI is readily rendered
 Lines 152-158    Link Here 
152
			this.selectChild(this._updates);
164
			this.selectChild(this._updates);
153
165
154
		},
166
		},
167
		
168
		_updateStatus: function(values) {
169
			this._reboot_required = tools.isTrue(values.reboot_required);
170
		},
155
171
172
		_ask_for_reboot: function() {
173
			if (this._reboot_required) {
174
						// show an alert
175
						dialog.alert(_('In order to complete the recently executed action, it is required to reboot the system.'))
176
					} else {
177
						// ask user to restart
178
						libServer.askRestart(_('For the changes to take effect, it is recommended to perform a restart of the UMC server components.')).then(
179
							function() { /* nothing to do */ },
180
							function() { /* nothing at all */}
181
						);
182
					}
183
184
		},
185
186
156
		// Seperate function that can be called the same way as _call_installer:
187
		// Seperate function that can be called the same way as _call_installer:
157
		// instead of presenting the usual confirm dialog it presents the list
188
		// instead of presenting the usual confirm dialog it presents the list
158
		// of packages for a distupgrade.
189
		// of packages for a distupgrade.
 Lines 347-353    Link Here 
347
				this.standby(false);
378
				this.standby(false);
348
				if (data.result.status === 0)
379
				if (data.result.status === 0)
349
				{
380
				{
350
					this._switch_to_progress_page();
381
					this._query_progress();
351
				}
382
				}
352
				else
383
				else
353
				{
384
				{
 Lines 358-385    Link Here 
358
			// (popup or login prompt) is well suited for the situation, so we don't disable it.
389
			// (popup or login prompt) is well suited for the situation, so we don't disable it.
359
			lang.hitch(this, function() {
390
			lang.hitch(this, function() {
360
				this.standby(false);
391
				this.standby(false);
361
			}));
392
			})
393
			);
362
		},
394
		},
363
395
364
396
365
		// Switches to the progress view: all tabs but the 'update in progess' will disappear.
366
		// Remembers the currently selected tab and will restore it when finished.
367
		// NOTE that we don't pass any args to the progress page since it is able
368
		//		to fetch them all from the AT job.
369
		_switch_to_progress_page: function() {
370
397
371
			try
372
			{
373
				this.selectChild(this._progress);
374
375
				this._progress.startWatching();
376
			}
377
			catch(error)
378
			{
379
				console.error("switch_progress: " + error.message);
380
			}
381
		},
382
383
		// We must establish a NO ERROR callback too, so we can reset
398
		// We must establish a NO ERROR callback too, so we can reset
384
		// the error status
399
		// the error status
385
		handleQuerySuccess: function(subject) {
400
		handleQuerySuccess: function(subject) {
 Lines 390-395    Link Here 
390
				this._reset_error_status();
405
				this._reset_error_status();
391
			}
406
			}
392
		},
407
		},
408
		// invokes a progress bar which automagically polls the updater script
409
		// for current progress and stops if finished or errors occur
410
		_query_progress: function() {
411
			this.standby(true, this._progressBar);
412
			this._progressBar.reset(_('Starting the update process...'));
413
			this._progressBar.auto(
414
				'updater/installer/parseprogress',
415
				{},
416
				lang.hitch(this, function() {
417
					this.standby(false);
418
					var errors = this._progressBar.getErrors();
419
					if (errors.critical) {
420
						// in case of errors notify user
421
						dialog.alert((_('An error has occurred :') + '<br>' + '<br>' + errors.errors[0] + '<br>'+ '<br>' + _('See the log for further info !')),_('Update error'));
422
					} else {
423
						dialog.notify(_('The update process was successful.'));
424
						this._ask_for_reboot();
425
					}
426
				}),
427
				undefined,
428
				undefined,
429
				true // let our callback handle errors
430
			);
431
		},
393
432
394
		// Recover after any kind of long-term failure:
433
		// Recover after any kind of long-term failure:
395
		//
434
		//
 Lines 410-415    Link Here 
410
			}
449
			}
411
		},
450
		},
412
451
452
413
		// Handles gracefully all things related to fatal query errors while
453
		// Handles gracefully all things related to fatal query errors while
414
		// an installer call is running. The background is that all polling
454
		// an installer call is running. The background is that all polling
415
		// queries are done with 'handleErrors=false', and their corresponding
455
		// queries are done with 'handleErrors=false', and their corresponding
 Lines 446-456    Link Here 
446
							// is already active.
486
							// is already active.
447
							this._updates.refreshPage();
487
							this._updates.refreshPage();
448
							this._updates.startPolling();
488
							this._updates.startPolling();
449
							this._progress.startPolling();
489
						}));
450
						})
451
						);
452
490
453
454
						dialog.notify(_("Your current session has expired, or the connection to the server was lost. You must authenticate yourself again."));
491
						dialog.notify(_("Your current session has expired, or the connection to the server was lost. You must authenticate yourself again."));
455
					}
492
					}
456
	//				else
493
	//				else
(-)umc/js/updater/LogPage.js (+150 lines)
Line 0    Link Here 
1
/*
2
 * Copyright 2011-2013 Univention GmbH
3
 *
4
 * http://www.univention.de/
5
 *
6
 * All rights reserved.
7
 *
8
 * The source code of this program is made available
9
 * under the terms of the GNU Affero General Public License version 3
10
 * (GNU AGPL V3) as published by the Free Software Foundation.
11
 *
12
 * Binary versions of this program provided by Univention to you as
13
 * well as other copyrighted, protected or trademarked materials like
14
 * Logos, graphics, fonts, specific documentations and configurations,
15
 * cryptographic keys etc. are subject to a license agreement between
16
 * you and Univention and not subject to the GNU AGPL V3.
17
 *
18
 * In the case you use this program under the terms of the GNU AGPL V3,
19
 * the program is provided in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public
25
 * License with the Debian GNU/Linux or Univention distribution in file
26
 * /usr/share/common-licenses/AGPL-3; if not, see
27
 * <http://www.gnu.org/licenses/>.
28
 */
29
/*global define window console*/
30
31
// Class that provides a scrollable logfile viewer.
32
33
define([
34
	"dojo/_base/declare",
35
	"dojo/_base/lang",
36
	"umc/tools",
37
	"umc/widgets/Text",
38
	"umc/widgets/ContainerWidget",
39
	"umc/modules/updater/Page",
40
	"umc/widgets/ExpandingTitlePane",
41
	"umc/i18n!umc/modules/updater"
42
], function(declare, lang, tools, Text, ContainerWidget, Page, ExpandingTitlePane, _) {
43
	return declare('umc.modules.updater.LogPage', Page, {
44
45
		_all_lines:		[], // hold all past _max_number_of_lines lines
46
47
		// FIXME which class should I take here?
48
		style:		'border:1px solid #d0d0d0;background-color:#f8f8f8;padding:.3em;',
49
50
		postMixInProperties: function () {
51
52
		this.footerButtons = [{
53
				
54
				name:		'closelog',
55
				align:		'left',
56
				label:		_("back"),
57
				callback: lang.hitch(this, function() {
58
					this.onCloseLog();
59
					})
60
				},
61
				{
62
				name:		'jumptoend',
63
				align:		'right',
64
				label: 		_("jump to end of log"),
65
				callback: lang.hitch(this, function(){
66
					this.scrollToBottom();
67
					})
68
				
69
				}];
70
71
		},
72
73
74
		buildRendering: function() {
75
76
			this.inherited(arguments);
77
78
			this._pane = new ExpandingTitlePane({
79
				title:		_("Log file view")
80
			});
81
			
82
			this._container = new ContainerWidget ({
83
				scrollable: 		true  });
84
85
			this.addChild(this._pane);
86
			this._pane.addChild(this._container);	
87
88
			this._text = new Text({
89
				style:		'font-family:monospace;',
90
				content:	_("... loading log file ...")
91
			});
92
			this._container.addChild(this._text);
93
		},
94
		
95
		// read /var/log/univention/updater.log
96
		_fetch_log: function() {
97
98
			tools.umcpCommand('updater/installer/logfile', {},false).then(lang.hitch(this, function (data) {
99
				this.onQuerySuccess('updater/installer/logfile');
100
				this.setContentAttr(data.result);
101
			}));
102
		},
103
			
104
105
		// set content of _text
106
		setContentAttr: function(lines) {
107
			this._all_lines = this._all_lines.concat(lines);
108
			var printable_lines = this._all_lines;
109
			var content = printable_lines.join('<br />\n');
110
			this._text.set('content', content);
111
		},
112
113
	
114
		// scrolls to the bottom of the log. 
115
		scrollToBottom: function() {
116
117
			var todo = true;
118
			var node = this._text.contentNode.parentNode;
119
			var skip = 1024;
120
			while (todo)
121
			{
122
				var oldval = node.scrollTop;
123
				node.scrollTop = oldval+skip;
124
				var newval = node.scrollTop;
125
126
				// manually changed?
127
				// or new value not accepted?
128
				if (newval != (oldval+skip))
129
				{
130
					if (skip > 1)
131
					{
132
						skip = Math.floor(skip / 2);
133
					}
134
					else
135
					{
136
						todo = false;
137
					}
138
				}
139
			}
140
		},
141
142
		// can be listened to from outside
143
		onQueryError: function(subject,data) {
144
		},
145
		onQuerySuccess: function(subject) {
146
		},
147
		onCloseLog: function() {
148
		}
149
	});
150
});
0
  + *
151
  + *
(-)umc/js/updater/ProgressPage.js (-401 lines)
 Lines 1-401    Link Here 
1
/*
2
 * Copyright 2011-2013 Univention GmbH
3
 *
4
 * http://www.univention.de/
5
 *
6
 * All rights reserved.
7
 *
8
 * The source code of this program is made available
9
 * under the terms of the GNU Affero General Public License version 3
10
 * (GNU AGPL V3) as published by the Free Software Foundation.
11
 *
12
 * Binary versions of this program provided by Univention to you as
13
 * well as other copyrighted, protected or trademarked materials like
14
 * Logos, graphics, fonts, specific documentations and configurations,
15
 * cryptographic keys etc. are subject to a license agreement between
16
 * you and Univention and not subject to the GNU AGPL V3.
17
 *
18
 * In the case you use this program under the terms of the GNU AGPL V3,
19
 * the program is provided in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public
25
 * License with the Debian GNU/Linux or Univention distribution in file
26
 * /usr/share/common-licenses/AGPL-3; if not, see
27
 * <http://www.gnu.org/licenses/>.
28
 */
29
/*global define window*/
30
31
// Some thoughts about the programmatic page structure:
32
//
33
//	(1)	we establish a timer that will check if a job is running. All information
34
//		about the corresponding job come from the Python module, so we will have
35
//		accurate information even if we have closed and reopened the whole module.
36
//	(2)	the main purpose of this page is to watch the corresponding log file. This
37
//		is accomplished with a _LogView class that inherits from umc.widgets.Text
38
//		and umc.modules._updater._PollingMixin.
39
//	(3)	no matter how the page is closed: the main Module is listening to our
40
//		onStopWatching method to know when our current page can be closed.
41
//
42
define([
43
	"dojo/_base/declare",
44
	"dojo/_base/lang",
45
	"dojo/dom-class",
46
	"umc/dialog",
47
	"umc/tools",
48
	"umc/modules/updater/Page",
49
	"umc/modules/updater/_LogViewer",
50
	"umc/widgets/Button",
51
	"umc/widgets/Text",
52
	"umc/widgets/ExpandingTitlePane",
53
	"umc/modules/lib/server",
54
	"umc/i18n!umc/modules/updater"
55
], function(declare, lang, domClass, dialog, tools, Page, _LogViewer, Button, Text, ExpandingTitlePane, libServer, _) {
56
	return declare("umc.modules.updater.ProgressPage", Page, {
57
58
		// Polling interval for eventually running Updater jobs. If this is
59
		// set to zero it effectively stops the timer.
60
		_interval:		1000,
61
62
		_job_key:		'', 			// the key of the currently running job
63
64
		_reboot_required: null,
65
66
		postMixInProperties: function() {
67
68
			this.inherited(arguments);
69
70
			// If I don't do that -> the page will switch 'show module help description' off
71
			lang.mixin(this, {
72
				helpText:	' ',
73
				title:		_("Update progress")
74
			});
75
		},
76
77
		buildRendering: function() {
78
79
			this.inherited(arguments);
80
81
			this._pane = new ExpandingTitlePane({
82
				title:		_("Log file view")
83
			});
84
			this.addChild(this._pane);
85
86
			this._head = new Text({
87
				region:		'top',
88
				content:	_("... please wait ...")
89
			});
90
			this._pane.addChild(this._head);
91
92
			this._log = new _LogViewer({
93
				region:			'center',
94
				query:			'updater/installer/logfile'
95
			});
96
			this._pane.addChild(this._log);
97
98
			this._log.on('queryerror', lang.hitch(this, 'onQueryError'));
99
			this._log.on('querysuccess', lang.hitch(this, 'onQuerySuccess'));
100
101
			// returns to the calling page
102
			this._close = new Button({
103
				label:		_("back"),
104
				region:		'bottom',
105
				onClick:	lang.hitch(this, function() {
106
					// local function to close the log view
107
					var _closeLogView = lang.hitch(this, function() {
108
						this.onStopWatching();
109
					});
110
111
					if (this._reboot_required) {
112
						// show an alert
113
						dialog.alert(_('In order to complete the recently executed action, it is required to reboot the system.'));
114
						_closeLogView();
115
					} else {
116
						// ask user to restart
117
						libServer.askRestart(_('For the changes to take effect, it is recommended to perform a restart of the UMC server components.')).then(
118
							function() { /* nothing to do */ },
119
							function() {
120
								// user canceled -> change current view
121
								_closeLogView();
122
							}
123
						);
124
					}
125
126
				})
127
			});
128
			this._pane.addChild(this._close);
129
			this._allow_close(false);
130
		},
131
132
		// starts the polling timer as late as possible.
133
		startup: function() {
134
135
			this.inherited(arguments);
136
			this._query_job_status();
137
		},
138
139
		// callback that processes job status and reschedules itself.
140
		_process_job_status: function(data) {
141
142
			if (data !== null)
143
			{
144
				// This is the response that tells us which job is running. As soon as we have this
145
				// key we will ask for the full properties hash until the job is finished.
146
				if (typeof(data.result) == 'string')
147
				{
148
					var txt = data.result;
149
					if (txt !== '')
150
					{
151
						if (this._job_key === '')
152
						{
153
							this._job_key = txt;			// from now on, we'll fetch full job details
154
							this._log.setJobKey(txt);		// tell the logViewer which job we're referring to.
155
						}
156
157
						// if the page is currently in background then we must notify
158
						// our Module that we want to be shown now
159
						this.onJobStarted();
160
						this._allow_close(false);		// close button now invisible.
161
					}
162
					if (data.result !== '')
163
					{
164
						// start the first call for 'update/installer/status' if we got a job name
165
						if ((this._interval) && (! this._timer))
166
						{
167
							this._timer = window.setTimeout(lang.hitch(this, function() {
168
								this._timer = '';
169
								this._query_job_status();
170
							}), this._interval);
171
						}
172
					}
173
				}
174
				else
175
				{
176
					// This knows about all details of the job, and it will know when the job
177
					// is finished.
178
					this._last_job = data.result;	// remember for later
179
180
					// FIXME Making margins by adding empty lines before and after the text; should
181
					//		be done by a style or style class.
182
					var msg = "&nbsp;<br/>";
183
					msg = msg + lang.replace(_("The job <b>{label}</b> (started {elapsed} ago) is currently running."), this._last_job);
184
185
					if (this._last_job.logfile)
186
					{
187
						msg = msg + ('<br/>' + lang.replace(_("You're currently watching its log file <b>{logfile}</b>"), this._last_job));
188
					}
189
					msg = msg + "<br/>&nbsp;<br/>";
190
191
192
					this._head.set('content', msg);
193
194
					// if (! data.result['running'])
195
					// {
196
					// }
197
198
					if (data.result.running)
199
					{
200
						// reschedule this as long as the job runs.
201
						if ((this._interval) && (! this._timer))
202
						{
203
							this._timer = window.setTimeout(lang.hitch(this, function() {
204
								this._timer = '';
205
								this._query_job_status();
206
							}), this._interval);
207
						}
208
					}
209
					else
210
					{
211
						this._allow_close(true);		// does the rest.
212
					}
213
214
					this._pane.layout();
215
216
				}
217
			}
218
			else {
219
				// error case, request could not been sent... try again
220
				if ((this._interval) && (! this._timer))
221
				{
222
					this._timer = window.setTimeout(lang.hitch(this, function() {
223
						this._timer = '';
224
						this._query_job_status();
225
					}), this._interval);
226
				}
227
			}
228
229
		},
230
231
		// queries job status. As long as we know a job key -> ask for full
232
		// details. The handler _process_job_status() handles this gracefully.
233
		_query_job_status: function() {
234
235
			if (this._job_key === '')
236
			{
237
				tools.umcpCommand(
238
					'updater/installer/running', {}, false).then(
239
					lang.hitch(this, function(data) {
240
						this.onQuerySuccess('updater/installer/running');
241
						this._process_job_status(data);
242
					}),
243
					lang.hitch(this, function(data) {
244
						this.onQueryError('updater/installer/running', data);		// handles error
245
						this._process_job_status(null);							// only for rescheduling
246
					})
247
				);
248
			}
249
			else
250
			{
251
				tools.umcpCommand('updater/installer/status', {job:this._job_key}, false).then(
252
						lang.hitch(this, function(data) {
253
							this.onQuerySuccess("updater/installer/status(" + this._job_key + ")");
254
							this._process_job_status(data);
255
						}),
256
						lang.hitch(this, function(data) {
257
							this.onQueryError('updater/installer/status', data);		// handles error
258
							this._process_job_status(null);							// only for rescheduling
259
						})
260
					);
261
			}
262
		},
263
264
		// switches visibility of our 'close' button on or off.
265
		// Additionally, changes some labels to reflect the current situation.
266
		_allow_close: function(yes) {
267
			domClass.toggle(this._close.domNode, 'dijitHidden', ! yes);
268
			// While the button is hidden, the polling callback maintains the content
269
			// of this._head. Only if Close is enabled -> set to a different text.
270
			if (yes)
271
			{
272
				if ((this._job_key !== '') && (this._last_job))
273
				{
274
					// First thing to do: notify the Module that the job is finished. So it can already
275
					// refresh the 'Updates' and 'Components' pages before the user gets back there.
276
					this.onJobFinished();
277
278
					// FIXME Manually making empty lines before and after this text; should better be done
279
					//		by a style or a style class.
280
					var msg = "&nbsp;<br/>";
281
					msg = msg + lang.replace(_("The current job (<b>{label}</b>) is now finished.<br/>"), this._last_job);
282
					if (this._last_job.elapsed !== undefined)
283
					{
284
						msg = msg + lang.replace(_("It took {elapsed} to complete.<br/>"), this._last_job);
285
					}
286
					msg = msg + _("You may return to the overview by clicking the 'back' button now.");
287
					msg = msg + "<br/>&nbsp;<br/>";
288
289
					this._head.set('content', msg);
290
291
					// set headers according to the outcome
292
					var status = 'success';
293
					var lstat = this._last_job._status_;
294
					if ((lstat === undefined) || (lstat != 'DONE'))
295
					{
296
						status = 'failed';
297
					}
298
					this._switch_headings(status);
299
					this._log.scrollToBottom();		// jump to bottom a very last time
300
					this._log.onStopWatching();		// now log is freely scrollable manually
301
302
					this._last_job = null;	// can be deleted, but this._job_key should be retained!
303
				}
304
			}
305
		},
306
307
		// gives a means to restart polling after reauthentication
308
		startPolling: function() {
309
			this._process_job_status(null);
310
		},
311
312
		// This function will be called when the (background) ProgressPage encounters
313
		// that a job has been started. The updater Module listens here and will then
314
		// call startWatching.
315
		onJobStarted: function() {
316
		},
317
318
		// This function will be called when the already opened ProgressPage encounters
319
		// the end of the current job. The updater Module listens here and will refresh
320
		// the 'Updates' and 'Components' pages.
321
		onJobFinished: function() {
322
		},
323
324
		// updater Module calls this when the ProgressPage is to be opened.
325
		startWatching: function() {
326
327
			// ensure a clean look (and not some stale text from last job)
328
			this._head.set('content', _("... loading job data ..."));
329
330
			this._allow_close(false);					// forbid closing this tab.
331
			this._log.startWatching(this._interval);	// start logfile tail
332
		},
333
334
		// updater Module listens to this event to close the page
335
		//
336
		// This is a good place to reset the log viewer contents too.
337
		onStopWatching: function() {
338
			this._job_key = '';
339
			this._last_job = null;
340
			this._log.onStopWatching(true);
341
		},
342
343
		// lets the timer loop stop when the module is closed.
344
		uninitialize: function() {
345
346
			this.inherited(arguments);
347
			this._interval = 0;
348
		},
349
350
		// on switch to this page: set initial headings, and fetch
351
		// the 'job running' status at least once.
352
		onShow: function() {
353
			this._switch_headings('running');
354
			this._query_job_status();
355
		},
356
357
		// internal function that switches any heading variables of
358
		// our current page, according to the retrieved job status
359
		_switch_headings: function(status) {
360
361
			// avoid doing that repeatedly
362
			if (status == this._last_heading_status)
363
			{
364
				return;
365
			}
366
367
			this._last_heading_status = status;
368
369
			var headings = {
370
				'running': {
371
					// title:			_("Update in progress"),
372
					headerText:		_("Univention Updater is working"),
373
					helpText:		_("As long as the Univention Updater is updating your system, you're not allowed to manage settings. You may watch the progress, or close the module.")
374
				},
375
				'success': {
376
					// title:			_("Update finished"),
377
					headerText:		_("Univention Updater job completed"),
378
					helpText:		_("Univention Updater has successfully finished the current job. You may read through the log file. If you're finished you may press the 'back' button to close this view.")
379
				},
380
				'failed': {
381
					// title:			_("Update failed"),
382
					headerText:		_("Univention Updater job failed"),
383
					helpText:		_("Univention Updater could not successfully complete the current job. The log file should show the cause of the failure. If you're finished examining the log file you may press the 'back' button to close this view.")
384
				}
385
			};
386
387
			var info = headings[status];
388
			for (var v in info)
389
			{
390
				this.set(v, info[v]);
391
			}
392
			// this.layout();
393
394
		},
395
396
		updateStatus: function(values) {
397
			// receive new status values from update page
398
			this._reboot_required = tools.isTrue(values.reboot_required);
399
		}
400
	});
401
});
(-)umc/js/updater/UpdatesPage.js (-62 / +123 lines)
 Lines 46-55    Link Here 
46
], function(declare, lang, array, all, domClass, topic, sprintf, dialog, tools, store, TitlePane, Page, Form, _) {
46
], function(declare, lang, array, all, domClass, topic, sprintf, dialog, tools, store, TitlePane, Page, Form, _) {
47
	return declare("umc.modules.updater.UpdatesPage", Page, {
47
	return declare("umc.modules.updater.UpdatesPage", Page, {
48
48
49
49
		_last_reboot:	false,
50
		_last_reboot:	false,
50
		_update_prohibited: false,
51
		_update_prohibited: false,
51
		standby: null, // parents standby method must be passed. weird IE-Bug (#29587)
52
		standby: null, // parents standby method must be passed. weird IE-Bug (#29587)
52
		standbyDuring: null, // parents standby method must be passed. weird IE-Bug (#29587)
53
		standbyDuring: null, // parents standby method must be passed. weird IE-Bug (#29587)
54
		_update_runnig :false, //will be used to determine if 'check for updates' should be performed depending on if an update process is running or not
53
55
54
		postMixInProperties: function() {
56
		postMixInProperties: function() {
55
57
 Lines 60-71    Link Here 
60
				headerText:		_("Available system updates"),
62
				headerText:		_("Available system updates"),
61
				helpText:		_("Overview of all updates that affect the system as a whole.")
63
				helpText:		_("Overview of all updates that affect the system as a whole.")
62
			});
64
			});
65
66
67
			this.footerButtons = [{
68
				name: 'showlog',
69
				label: _('Show logfile'),
70
				callback: lang.hitch(this, function() {
71
					this.onClickLog();
72
				})
73
			}];
74
63
		},
75
		},
64
76
77
78
65
		buildRendering: function() {
79
		buildRendering: function() {
66
80
67
			this.inherited(arguments);
81
			this.inherited(arguments);
68
69
			var widgets =
82
			var widgets =
70
			[
83
			[
71
				// --------------------- Reboot pane -----------------------------
84
				// --------------------- Reboot pane -----------------------------
 Lines 134-190    Link Here 
134
					// FIXME Manual placement: should be done by the layout framework some day.
147
					// FIXME Manual placement: should be done by the layout framework some day.
135
					style:			'width:300px;',
148
					style:			'width:300px;',
136
					onValuesLoaded:	lang.hitch(this, function(values) {
149
					onValuesLoaded:	lang.hitch(this, function(values) {
137
						// TODO check updater/installer/running, don't do anything if something IS running
150
									
138
						try
151
					// check if updater is running, don't check for updates if it is
139
						{
152
					//
140
							this.onQuerySuccess('updater/updates/query');
153
					//	this._update_running will be set to true in case an update is running
141
							var element_releases = this._form.getWidget('releases');
154
					//	or false if it isn't
142
							var to_show = false;
155
					//
143
							var to_show_msg = true;
156
					tools.umcpCommand('updater/installer/running', {}, false).then(lang.hitch(this, function(data) {	
157
						this.isRunning = data.result;
158
						if (this.isRunning == "" ) {
159
							// only do this if no update is running
160
							this._update_running=false;	
161
							try
162
							{
163
								this.onQuerySuccess('updater/updates/query');
164
								var element_releases = this._form.getWidget('releases');
165
								var to_show = false;
166
								var to_show_msg = true;
144
167
145
							var element_updatestext = this._form.getWidget('ucs_updates_text');
168
								var element_updatestext = this._form.getWidget('ucs_updates_text');
146
							element_updatestext.set('content', _("There are no release updates available."));
169
								element_updatestext.set('content', _("There are no release updates available."));
147
170
148
							if (values.length)
171
								if (values.length)
149
							{
172
								{
150
								var val = values[values.length-1].id;
173
									var val = values[values.length-1].id;
151
								to_show = true;
174
									to_show = true;
152
								to_show_msg = false;
175
									to_show_msg = false;
153
								element_releases.set('value', val);
176
									element_releases.set('value', val);
154
							}
177
								}
155
178
156
							var appliance_mode = (this._form.getWidget('appliance_mode').get('value') === 'true');
179
								var appliance_mode = (this._form.getWidget('appliance_mode').get('value') === 'true');
157
							var blocking_component = this._form.getWidget('release_update_blocking_component').get('value');
180
								var blocking_component = this._form.getWidget('release_update_blocking_component').get('value');
158
							if ((blocking_component) && (! appliance_mode)) {
181
								if ((blocking_component) && (! appliance_mode)) {
159
								// further updates are available but blocked by specified component which is required for update
182
									// further updates are available but blocked by specified component which is required for update
160
								element_updatestext.set('content', lang.replace(_("Further release updates are available but cannot be installed because the component '{0}' is not available for newer release versions."), [blocking_component]));
183
									element_updatestext.set('content', lang.replace(_("Further release updates are available but cannot be installed because the component '{0}' is not available for newer release versions."), [blocking_component]));
161
								to_show_msg = true;
184
									to_show_msg = true;
162
							}
185
								}
186
								// hide or show combobox, spacers and corresponding button
187
								this._form.showWidget('releases', to_show);
188
								this._form.showWidget('hspacer_180px', to_show);
189
								this._form.showWidget('vspacer_1em', to_show);
163
190
164
							// hide or show combobox, spacers and corresponding button
191
								this._form.showWidget('ucs_updates_text', to_show_msg);
165
							this._form.showWidget('releases', to_show);
166
							this._form.showWidget('hspacer_180px', to_show);
167
							this._form.showWidget('vspacer_1em', to_show);
168
192
169
							this._form.showWidget('ucs_updates_text', to_show_msg);
193
								var but = this._form._buttons.run_release_update;
194
								but.set('visible', to_show);
170
195
171
							var but = this._form._buttons.run_release_update;
196
								// renew affordance to check for package updates, but only
172
							but.set('visible', to_show);
197
								// if we didn't see availability yet.
173
198
								if (! this._updates_available) 
174
							// renew affordance to check for package updates, but only
199
								{
175
							// if we didn't see availability yet.
200
									this._set_updates_button(false, _("Package update status not yet checked"));
176
							if (! this._updates_available)
201
									this.standbyDuring(all([this._check_dist_upgrade(), this._check_app_updates()]));
202
								}
203
							}	
204
							catch(error)
177
							{
205
							{
178
								this._set_updates_button(false, _("Package update status not yet checked"));
206
								console.error("onValuesLoaded: " + error.message);
179
							}
207
							} 
180
208
181
							this.standbyDuring(all([this._check_dist_upgrade(), this._check_app_updates()]));
182
						}
209
						}
183
						catch(error)
210
						else
184
						{
211
						{ 
185
							console.error("onValuesLoaded: " + error.message);
212
							// notify parent page if update is already running 
186
						}
213
							this.onProgressResume();
187
					})
214
							this._update_running=true;
215
						}	
216
					}))		
217
				})
218
219
220
				
188
				},
221
				},
189
				{
222
				{
190
					type:			'HiddenInput',
223
					type:			'HiddenInput',
 Lines 267-272    Link Here 
267
					name:			'app_center_updates_apps',
300
					name:			'app_center_updates_apps',
268
					style:			'width:500px;margin-top:.5em;',
301
					style:			'width:500px;margin-top:.5em;',
269
					content:		''
302
					content:		''
303
				},
304
				{
305
					type:			'Text',
306
					label:			'',
307
					name:			'app_center_updates_link'
270
				}
308
				}
271
			];
309
			];
272
310
 Lines 282-290    Link Here 
282
					callback:	lang.hitch(this, function() {
320
					callback:	lang.hitch(this, function() {
283
						var element = this._form.getWidget('releases');
321
						var element = this._form.getWidget('releases');
284
						var release = element.get('value');
322
						var release = element.get('value');
285
						// TODO check updater/installer/running, don't do action if a job is running
323
286
						this.onRunReleaseUpdate(release);
324
						//check updater/installer/running, don't do action if a job is running
287
						topic.publish('/umc/actions', this.moduleID, this.moduleFlavor, 'release-update');
325
						if (! this._update_running){
326
						
327
							this.onRunReleaseUpdate(release);
328
							topic.publish('/umc/actions', this.moduleID, this.moduleFlavor, 'release-update');
329
						}
288
					}),
330
					}),
289
					visible:	false
331
					visible:	false
290
				},
332
				},
 Lines 292-299    Link Here 
292
					name:		'run_packages_update',
334
					name:		'run_packages_update',
293
					label:		_("Check for package updates"),
335
					label:		_("Check for package updates"),
294
					callback:	lang.hitch(this, function() {
336
					callback:	lang.hitch(this, function() {
295
						this.standbyDuring(this._check_dist_upgrade());
337
296
						topic.publish('/umc/actions', this.moduleID, this.moduleFlavor, 'package-update');
338
						if (! this._update_running){
339
340
							this.standbyDuring(this._check_dist_upgrade());
341
							topic.publish('/umc/actions', this.moduleID, this.moduleFlavor, 'package-update');
342
						}
297
					})
343
					})
298
				},
344
				},
299
				// If refresh isn't automatic anymore... should we show a "Refresh" button?
345
				// If refresh isn't automatic anymore... should we show a "Refresh" button?
 Lines 316-324    Link Here 
316
					name:		'easy_upgrade',
362
					name:		'easy_upgrade',
317
					label:		_("Start Upgrade"), 		// FIXME Label not correct
363
					label:		_("Start Upgrade"), 		// FIXME Label not correct
318
					callback:	lang.hitch(this, function() {
364
					callback:	lang.hitch(this, function() {
319
						// TODO check updater/installer/running, don't do action if a job is running
365
						
320
						this.onRunEasyUpgrade();
366
						//check updater/installer/running, don't do action if a job is running	
321
						topic.publish('/umc/actions', this.moduleID, this.moduleFlavor, 'easy-upgrade');
367
						if (! this._update_running){
368
							this.onRunEasyUpgrade();
369
							topic.publish('/umc/actions', this.moduleID, this.moduleFlavor, 'easy-upgrade');
370
						}
322
					})
371
					})
323
				}
372
				}
324
			];
373
			];
 Lines 364-370    Link Here 
364
					layout:
413
					layout:
365
					[
414
					[
366
						['app_center_updates_text'],
415
						['app_center_updates_text'],
367
						['app_center_updates_apps']
416
						['app_center_updates_apps', 'app_center_updates_link']
368
					]
417
					]
369
				}
418
				}
370
			];
419
			];
 Lines 493-498    Link Here 
493
542
494
		},
543
		},
495
544
545
496
		_update_errata_link: function(version) {
546
		_update_errata_link: function(version) {
497
			var versionWithoutPatchlevel;
547
			var versionWithoutPatchlevel;
498
			try {
548
			try {
 Lines 536-546    Link Here 
536
					if (apps.length) {
586
					if (apps.length) {
537
						msg = _('There are App Center updates available.');
587
						msg = _('There are App Center updates available.');
538
						var appUpdatesInfo = array.map(apps, function(app) {
588
						var appUpdatesInfo = array.map(apps, function(app) {
539
							var link = sprintf('<a href="javascript:void(0)" onclick="require(\'umc/app\').openModule(\'apps\', \'%(id)s\')">%(name)s</a>', app);
589
							return _('%(name)s: Version %(old)s can be updated to %(new)s', {name: app.name, old: app.version, 'new': app.candidate_version});
540
							return _('%(name)s: Version %(old)s can be updated to %(new)s', {name: link, old: app.version, 'new': app.candidate_version});
541
						});
590
						});
542
						var appUpdatesList = '<ul><li>' + appUpdatesInfo.join('</li><li>') + '</li></ul>';
591
						var appUpdatesList = '<ul><li>' + appUpdatesInfo.join('</li><li>') + '</li></ul>';
543
						this._form.getWidget('app_center_updates_apps').set('content', appUpdatesList);
592
						this._form.getWidget('app_center_updates_apps').set('content', appUpdatesList);
593
						var link = 'href="javascript:void(0)" onclick="require(\'umc/app\').openModule(\'appcenter\')"';
594
						this._form.getWidget('app_center_updates_link').set('content', _('Please visit the <a %s>App Center Module</a> to install these updates.', link));
544
					} else {
595
					} else {
545
						msg = _('There are no App Center updates available.');
596
						msg = _('There are no App Center updates available.');
546
					}
597
					}
 Lines 658-676    Link Here 
658
		// First page refresh doesn't work properly when invoked in 'buildRendering()' so
709
		// First page refresh doesn't work properly when invoked in 'buildRendering()' so
659
		// we defer it until the UI is being shown
710
		// we defer it until the UI is being shown
660
		startup: function() {
711
		startup: function() {
661
712
			if (! this._update_running){
662
			this.inherited(arguments);
713
				this.inherited(arguments);
663
			this._show_reboot_pane(false);
714
				this._show_reboot_pane(false);
664
715
			}
665
		},
716
		},
666
717
667
		// ensures refresh whenever we're returning from any action.
718
		// ensures refresh whenever we're returning from any action.
668
		onShow: function() {
719
		onShow: function() {
669
720
670
			this.inherited(arguments);
721
			this.inherited(arguments);		
671
			// show standby while loading data
722
			// we don't want any 'standby' to interfere with our progress bar if active
672
			this.standby(true);
723
			if (! this._update_running){
673
			this.refreshPage(true);
724
725
				this.standby(true);
726
				this.refreshPage(true);
727
728
			}
674
		},
729
		},
675
730
676
		// should refresh any data contained here. (can be called from outside when needed)
731
		// should refresh any data contained here. (can be called from outside when needed)
 Lines 689-694    Link Here 
689
		startPolling: function() {
744
		startPolling: function() {
690
			// not needed anymore.
745
			// not needed anymore.
691
			// this._form.startPolling();
746
			// this._form.startPolling();
747
			//this.onProgressResume();
692
		},
748
		},
693
749
694
		// These functions are stubs that the 'updater' Module is listening to,
750
		// These functions are stubs that the 'updater' Module is listening to,
 Lines 701-710    Link Here 
701
		},
757
		},
702
		onRunEasyUpgrade: function() {
758
		onRunEasyUpgrade: function() {
703
		},
759
		},
760
		onProgressResume: function() {
761
		},
704
762
705
		onStatusLoaded: function(vals) {
763
		onStatusLoaded: function(vals) {
706
			// event stub
764
			// event stub
765
		},
766
		onClickLog: function() {
707
		}
767
		}
708
768
769
709
	});
770
	});
710
});
771
});
(-)umc/js/updater/_LogViewer.js (-291 lines)
 Lines 1-291    Link Here 
1
/*
2
 * Copyright 2011-2013 Univention GmbH
3
 *
4
 * http://www.univention.de/
5
 *
6
 * All rights reserved.
7
 *
8
 * The source code of this program is made available
9
 * under the terms of the GNU Affero General Public License version 3
10
 * (GNU AGPL V3) as published by the Free Software Foundation.
11
 *
12
 * Binary versions of this program provided by Univention to you as
13
 * well as other copyrighted, protected or trademarked materials like
14
 * Logos, graphics, fonts, specific documentations and configurations,
15
 * cryptographic keys etc. are subject to a license agreement between
16
 * you and Univention and not subject to the GNU AGPL V3.
17
 *
18
 * In the case you use this program under the terms of the GNU AGPL V3,
19
 * the program is provided in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public
25
 * License with the Debian GNU/Linux or Univention distribution in file
26
 * /usr/share/common-licenses/AGPL-3; if not, see
27
 * <http://www.gnu.org/licenses/>.
28
 */
29
/*global define window console*/
30
31
// Class that provides a logfile viewer. Features are:
32
//
33
//	(1)	uses the _PollingMixin to query for the mtime of the named log file
34
//	(2)	provides scrolling capability
35
//	(3)	can scroll to the bottom of the file if new data has arrived
36
//		(should only work if the current position is at EOF)
37
//
38
// the passed query argument must be a backend function that understands
39
// the 'count' argument specially:
40
//
41
//	-1 ...... return the file timestamp of the log
42
//	0 ....... return the whole file contents
43
//  <any> ... return this many last lines (tail -n)
44
45
define([
46
	"dojo/_base/declare",
47
	"dojo/_base/lang",
48
	"umc/tools",
49
	"umc/widgets/Text",
50
	"umc/widgets/ContainerWidget",
51
	"umc/i18n!umc/modules/updater"
52
], function(declare, lang, tools, Text, ContainerWidget, _) {
53
	return declare('umc.modules.updater._LogViewer', [ ContainerWidget ], {
54
55
		scrollable:			true,
56
		_first_call:		3,
57
		_last_stamp:		0,
58
		_check_interval:	0,
59
		_current_job:		'',
60
		_log_position:		0,
61
		_max_number_of_lines:	2500, // ~ 200kB if one line ^= 80 chars
62
		_all_lines:		[], // hold all past _max_number_of_lines lines
63
64
		// FIXME which class should I take here?
65
		style:		'border:1px solid #d0d0d0;background-color:#f8f8f8;padding:.3em;',
66
67
	//	postMixinProperties: function() {
68
	//
69
	//		this.inherited(arguments);
70
	//
71
	//		// mix in the polling capability
72
	//		lang.mixin(this,umc.modules._updater._PollingMixin({
73
	//			polling: {
74
	//				interval:	1000,
75
	//				'function':	lang.hitch(this, function() {
76
	//					this._fetch_log();
77
	//				}),
78
	//				query:		this.query
79
	//			}
80
	//		}));
81
	//	},
82
83
		buildRendering: function() {
84
85
			this.inherited(arguments);
86
87
			this._text = new Text({
88
				style:		'font-family:monospace;',
89
				content:	_("... loading log file ...")
90
			});
91
			this.addChild(this._text);
92
		},
93
94
		_fetch_log: function() {
95
96
			tools.umcpCommand(this.query,{job:this._current_job, count:-1},false).then(lang.hitch(this,function(data) {
97
98
				this.onQuerySuccess(this.query + " [count=-1]");
99
				var stamp = data.result;
100
				if (stamp != this._last_stamp)
101
				{
102
					this._last_stamp = stamp;
103
					tools.umcpCommand(this.query,{job:this._current_job,count:this._log_position},false).then(lang.hitch(this, function(data) {
104
105
						var contentLength = parseInt( data.result.length, 10 );
106
						if( contentLength ) {
107
							this._log_position += contentLength;
108
						}
109
						this.onQuerySuccess(this.query + " [count=0]");
110
						this.setContentAttr(data.result);
111
					}),
112
					lang.hitch(this, function(data) {
113
						this.onQueryError(this.query + " [count=0]",data);
114
					})
115
					);
116
				}
117
118
				if (this._check_interval)
119
				{
120
					window.setTimeout(lang.hitch(this,function() {
121
						this._fetch_log();
122
					}),this._check_interval);
123
				}
124
125
			}),
126
			lang.hitch(this,function(data) {
127
				this.onQueryError(this.query + " [count=-1]",data);
128
				// even in case of errors -> reschedule polling!
129
				if (this._check_interval)
130
				{
131
					window.setTimeout(lang.hitch(this,function() {
132
						this._fetch_log();
133
					}),this._check_interval);
134
				}
135
			})
136
			);
137
138
		},
139
140
		// set content. Additionally checks if the current scroll position
141
		// (before setting content) is at bottom, and if it is -> set
142
		// bottom position after setting content too.
143
		// Also checks if the log file exceeds a certain limit
144
		setContentAttr: function(lines) {
145
			this._all_lines = this._all_lines.concat(lines);
146
			var printable_lines = this._all_lines;
147
			if (this._lines_exceeded || this._all_lines.length > this._max_number_of_lines) {
148
				var lines_exceeded = this._all_lines.length - this._max_number_of_lines;
149
				this._lines_exceeded += lines_exceeded;
150
				this._all_lines = this._all_lines.slice(lines_exceeded, this._all_lines.length);
151
				var logfile_exceeded = '[...] ' + dojo.replace(_('The log file exceeded {max} lines by {exceeded}. Please see the full logfile.'),
152
					{
153
						max: this._max_number_of_lines,
154
						exceeded: this._lines_exceeded
155
					}
156
				);
157
				printable_lines = [logfile_exceeded].concat(this._all_lines);
158
			}
159
			var content = printable_lines.join('<br />\n');
160
			try
161
			{
162
				var oldpos = this._get_positions();
163
164
				// check if we should scroll to bottom. We avoid that if the current position
165
				// is not at the end, indicating that the user has moved the pane manually.
166
				//
167
				// our height measure doesn't strictly reflect what we need, so we add a little tolerance:
168
				// regard the positon 'at bottom' if its plus/minus 20px around zero
169
				var to_scroll = false;
170
				if ( (this._first_call > 0) || ( /* (oldpos['d_bottom'] > -20) && */ (oldpos.d_bottom < 20)))
171
				{
172
					to_scroll = true;
173
				}
174
175
				this._text.set('content', content);
176
				if (to_scroll)
177
				{
178
					this.scrollToBottom();
179
					if (this._first_call > 0)
180
					{
181
						this._first_call--;
182
					}
183
				}
184
			}
185
			catch(error)
186
			{
187
				console.error("SCROLL ERROR: " + error.message);
188
			}
189
		},
190
191
		// gets the scrolling state of the text widget relative to its container
192
		_get_positions: function() {
193
194
			var result = {};
195
			result.h_text = this._text.contentNode.scrollHeight;						// text height
196
			result.h_container = this.domNode.clientHeight;							// container widget height
197
			result.d_top = this._text.contentNode.parentNode.scrollTop;				// scroll distance from top
198
			result.d_bottom = result.h_text - (result.h_container + result.d_top);	// scroll distance from bottom
199
200
			return result;
201
		},
202
203
		// scrolls to the bottom of the scroll area. Will be called from different places:
204
		//
205
		//	-	unconditionally when the ProgressPage is being opened
206
		//	-	in the 'content' setter if the position is roughly at the bottom
207
		//
208
		scrollToBottom: function() {
209
210
			// we ignore any calls to 'scrollToBottom()' if we're not currently
211
			// watching. This makes the pane free movable at the 'return to overview'
212
			// prompt when a job is finished.
213
			if (this._check_interval === 0)
214
			{
215
				return;
216
			}
217
			var todo = true;
218
			var node = this._text.contentNode.parentNode;
219
			var skip = 1024;
220
			while (todo)
221
			{
222
				var oldval = node.scrollTop;
223
				node.scrollTop = oldval+skip;
224
				var newval = node.scrollTop;
225
226
				// manually changed?
227
				// or new value not accepted?
228
				if (newval != (oldval+skip))
229
				{
230
					if (skip > 1)
231
					{
232
						skip = Math.floor(skip / 2);
233
					}
234
					else
235
					{
236
						todo = false;
237
					}
238
				}
239
			}
240
		},
241
242
		// Called from ProgressPage when the log file polling is to be started.
243
		// job key can't be an argument here as we don't know it.
244
		startWatching: function(interval) {
245
246
			this._check_interval = interval;
247
			// clean up any stale display and states from last run
248
			this.set('content', _("... loading log file ..."));
249
			this._all_lines = [];
250
			this._lines_exceeded = 0;
251
252
			this._first_call = 3;
253
			this._last_stamp = 0;
254
255
			this._fetch_log();		// first call, will reschedule itself as long
256
									// as _check_interval is not zero
257
		},
258
259
		// A seperate function that is called by the 'ProgressPage' when the key of the
260
		// current job has become known.
261
		setJobKey: function(job) {
262
			this._current_job = job;
263
		},
264
265
		// effectively stops the polling timer. Can be called from outside (if ProgressPage is being closed)
266
		// or from inside (as 'uninitialize' handler)
267
		//
268
		// Argument 'clean' = TRUE -> also clean up display buffer contents.
269
		onStopWatching: function(clean) {
270
271
			this._check_interval = 0;
272
273
			if ((typeof(clean) != 'undefined') && (clean))
274
			{
275
				this.set('content',_("... loading log file ..."));
276
			}
277
		},
278
279
		uninitialize: function() {
280
281
			this.inherited(arguments);
282
			this.onStopWatching();
283
		},
284
285
		// can be listened to from outside
286
		onQueryError: function(subject,data) {
287
		},
288
		onQuerySuccess: function(subject) {
289
		}
290
	});
291
});
(-)umc/js/de.po (-171 / +186 lines)
 Lines 3-9    Link Here 
3
msgstr ""
3
msgstr ""
4
"Project-Id-Version: univention-management-console-module-updater\n"
4
"Project-Id-Version: univention-management-console-module-updater\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
6
"POT-Creation-Date: 2013-08-26 10:40+0200\n"
6
"POT-Creation-Date: 2013-10-01 06:51+0200\n"
7
"PO-Revision-Date: 2012-02-27 16:03+0100\n"
7
"PO-Revision-Date: 2012-02-27 16:03+0100\n"
8
"Last-Translator: Frank Greif <fg@it25.de>\n"
8
"Last-Translator: Frank Greif <fg@it25.de>\n"
9
"Language-Team: LANGUAGE <LL@li.org>\n"
9
"Language-Team: LANGUAGE <LL@li.org>\n"
 Lines 12-57    Link Here 
12
"Content-Type: text/plain; charset=UTF-8\n"
12
"Content-Type: text/plain; charset=UTF-8\n"
13
"Content-Transfer-Encoding: 8bit\n"
13
"Content-Transfer-Encoding: 8bit\n"
14
14
15
#: umc/js/updater/UpdatesPage.js:543
15
#: umc/js/updater/UpdatesPage.js:589
16
#, python-format
16
#, python-format
17
msgid "%(name)s: Version %(old)s can be updated to %(new)s"
17
msgid "%(name)s: Version %(old)s can be updated to %(new)s"
18
msgstr "%(name)s: Version %(old)s kann auf %(new)s aktualisiert werden"
18
msgstr "%(name)s: Version %(old)s kann auf %(new)s aktualisiert werden"
19
19
20
#: umc/js/updater/UpdatesPage.js:229 umc/js/updater/UpdatesPage.js:261
20
#: umc/js/updater/UpdatesPage.js:263 umc/js/updater/UpdatesPage.js:295
21
msgid "... loading data ..."
21
msgid "... loading data ..."
22
msgstr "... Daten werden geladen ..."
22
msgstr "... Daten werden geladen ..."
23
23
24
#: umc/js/updater/ProgressPage.js:328
24
#: umc/js/updater/LogPage.js:90
25
msgid "... loading job data ..."
26
msgstr "... Daten werden geladen ..."
27
28
#: umc/js/updater/_LogViewer.js:89 umc/js/updater/_LogViewer.js:248
29
#: umc/js/updater/_LogViewer.js:275
30
msgid "... loading log file ..."
25
msgid "... loading log file ..."
31
msgstr "... Protokolldatei wird geladen ..."
26
msgstr "... Protokolldatei wird geladen ..."
32
27
33
#: umc/js/updater/ProgressPage.js:88
28
#: umc/js/updater.js:212
34
msgid "... please wait ..."
35
msgstr "... bitte warten ..."
36
37
#: umc/js/updater.js:181
38
msgid "1 package to be REMOVED"
29
msgid "1 package to be REMOVED"
39
msgstr "1 Paket wird ENTFERNT"
30
msgstr "1 Paket wird ENTFERNT"
40
31
41
#: umc/js/updater.js:219
32
#: umc/js/updater.js:250
42
msgid "1 package to be installed"
33
msgid "1 package to be installed"
43
msgstr "1 Paket wird NEU installiert"
34
msgstr "1 Paket wird NEU installiert"
44
35
45
#: umc/js/updater.js:200
36
#: umc/js/updater.js:231
46
msgid "1 package to be updated"
37
msgid "1 package to be updated"
47
msgstr "1 Paket wird aktualisiert"
38
msgstr "1 Paket wird aktualisiert"
48
39
49
#: umc/js/updater.js:310
40
#: umc/js/updater.js:341
50
msgid "Again, DO NOT power off the system even in these cases!"
41
msgid "Again, DO NOT power off the system even in these cases!"
51
msgstr ""
42
msgstr ""
52
"Noch einmal: Schalten Sie das System auch unter diesen Umständen NICHT aus."
43
"Noch einmal: Schalten Sie das System auch unter diesen Umständen NICHT aus."
53
44
54
#: umc/js/updater.js:483
45
#: umc/js/updater.js:520
55
msgid ""
46
msgid ""
56
"Alternatively, you may close the current Management Console window, wait "
47
"Alternatively, you may close the current Management Console window, wait "
57
"some time, and try to open it again."
48
"some time, and try to open it again."
 Lines 59-115    Link Here 
59
"Sie können die Management Console jetzt auch schließen, und später wieder "
50
"Sie können die Management Console jetzt auch schließen, und später wieder "
60
"öffnen."
51
"öffnen."
61
52
62
#: umc/js/updater/UpdatesPage.js:367
53
#: umc/js/updater.js:421
54
msgid "An error has occurred :"
55
msgstr "Ein Fehler ist aufgetreten :"
56
57
#: umc/js/updater/UpdatesPage.js:412
63
msgid "App Center updates"
58
msgid "App Center updates"
64
msgstr "App Center-Aktualisierungen"
59
msgstr "App Center-Aktualisierungen"
65
60
66
#: umc/js/updater/ProgressPage.js:373
61
#: umc/js/updater.js:321
67
msgid ""
68
"As long as the Univention Updater is updating your system, you're not "
69
"allowed to manage settings. You may watch the progress, or close the module."
70
msgstr ""
71
"Solange Univention Updater Ihr System aktualisiert, können Sie keine "
72
"Einstellungen verändern. Sie können die Aktualisierung hier verfolgen oder "
73
"das Modul schließen."
74
75
#: umc/js/updater.js:290
76
msgid "Attention!"
62
msgid "Attention!"
77
msgstr "Achtung!"
63
msgstr "Achtung!"
78
64
79
#: umc/js/updater/UpdatesPage.js:59
65
#: umc/js/updater/UpdatesPage.js:62
80
msgid "Available system updates"
66
msgid "Available system updates"
81
msgstr "Verfügbare System-Updates"
67
msgstr "Verfügbare System-Updates"
82
68
83
#: umc/js/updater.js:242 umc/js/updater.js:326
69
#: umc/js/updater.js:273 umc/js/updater.js:357
84
#: umc/js/updater/UpdatesPage.js:647
70
#: umc/js/updater/UpdatesPage.js:693
85
msgid "Cancel"
71
msgid "Cancel"
86
msgstr "Abbrechen"
72
msgstr "Abbrechen"
87
73
88
#: umc/js/updater/UpdatesPage.js:297 umc/js/updater/UpdatesPage.js:526
74
#: umc/js/updater/UpdatesPage.js:335 umc/js/updater/UpdatesPage.js:572
89
msgid "Check for package updates"
75
msgid "Check for package updates"
90
msgstr "Paket-Aktualisierungen prüfen"
76
msgstr "Paket-Aktualisierungen prüfen"
91
77
92
#: umc/js/updater.js:476
78
#: umc/js/updater.js:513
93
msgid "Connection lost!"
79
msgid "Connection lost!"
94
msgstr "Verbindung zum Server unterbrochen!"
80
msgstr "Verbindung zum Server unterbrochen!"
95
81
96
#: umc/js/updater.js:469
82
#: umc/js/updater.js:506
97
msgid "Connection to server lost. Trying to reconnect."
83
msgid "Connection to server lost. Trying to reconnect."
98
msgstr ""
84
msgstr ""
99
"Die Verbindung zum Server wurde unterbrochen. Ein erneuter Verbindungsaufbau "
85
"Die Verbindung zum Server wurde unterbrochen. Ein erneuter Verbindungsaufbau "
100
"wird gestartet."
86
"wird gestartet."
101
87
102
#: umc/js/updater.js:306
88
#: umc/js/updater.js:337
103
msgid "DO NOT power off the system during the update."
89
msgid "DO NOT power off the system during the update."
104
msgstr "Schalten Sie das System während des Updates NICHT aus."
90
msgstr "Schalten Sie das System während des Updates NICHT aus."
105
91
106
#: umc/js/updater.js:124
92
#: umc/js/updater.js:118
107
msgid "Do you really want to install release updates up to version {release}?"
93
msgid "Do you really want to install release updates up to version {release}?"
108
msgstr ""
94
msgstr ""
109
"Möchten Sie wirklich alle Release-Aktualisierungen bis zur Version "
95
"Möchten Sie wirklich alle Release-Aktualisierungen bis zur Version "
110
"'{release}' installieren?"
96
"'{release}' installieren?"
111
97
112
#: umc/js/updater.js:234
98
#: umc/js/updater.js:265
113
msgid ""
99
msgid ""
114
"Do you really want to perform the update/install/remove of the above "
100
"Do you really want to perform the update/install/remove of the above "
115
"packages?"
101
"packages?"
 Lines 117-139    Link Here 
117
"Möchten Sie wirklich die genannten Pakete aktualisieren, installieren bzw. "
103
"Möchten Sie wirklich die genannten Pakete aktualisieren, installieren bzw. "
118
"entfernen?"
104
"entfernen?"
119
105
120
#: umc/js/updater/UpdatesPage.js:644
106
#: umc/js/updater/UpdatesPage.js:690
121
msgid "Do you really want to reboot the machine?"
107
msgid "Do you really want to reboot the machine?"
122
msgstr "Möchten Sie die Maschine jetzt neu starten?"
108
msgstr "Möchten Sie die Maschine jetzt neu starten?"
123
109
124
#: umc/js/updater.js:137
110
#: umc/js/updater.js:131
125
msgid "Do you really want to upgrade your system?"
111
msgid "Do you really want to upgrade your system?"
126
msgstr "Möchten Sie Ihr System jetzt aktualisieren?"
112
msgstr "Möchten Sie Ihr System jetzt aktualisieren?"
127
113
128
#: umc/js/updater.js:319
114
#: umc/js/updater.js:350
129
msgid "Do you really wish to proceed?"
115
msgid "Do you really wish to proceed?"
130
msgstr "Möchten Sie wirklich fortfahren?"
116
msgstr "Möchten Sie wirklich fortfahren?"
131
117
132
#: umc/js/updater/UpdatesPage.js:81
118
#: umc/js/updater/UpdatesPage.js:95
133
msgid "During reboot, the connection to the system will be lost. "
119
msgid "During reboot, the connection to the system will be lost. "
134
msgstr "Während des Neustarts wird die Verbindung zum System unterbrochen. "
120
msgstr "Während des Neustarts wird die Verbindung zum System unterbrochen. "
135
121
136
#: umc/js/updater.js:298
122
#: umc/js/updater.js:329
137
msgid ""
123
msgid ""
138
"During setup, the web server may be stopped, leading to a termination of the "
124
"During setup, the web server may be stopped, leading to a termination of the "
139
"HTTP connection. "
125
"HTTP connection. "
 Lines 141-147    Link Here 
141
"Während des Updates ist es möglich, dass die Verbindung zum Webserver "
127
"Während des Updates ist es möglich, dass die Verbindung zum Webserver "
142
"unterbrochen wird. "
128
"unterbrochen wird. "
143
129
144
#: umc/js/updater/ProgressPage.js:117
130
#: umc/js/updater.js:178
145
msgid ""
131
msgid ""
146
"For the changes to take effect, it is recommended to perform a restart of "
132
"For the changes to take effect, it is recommended to perform a restart of "
147
"the UMC server components."
133
"the UMC server components."
 Lines 149-155    Link Here 
149
"Damit die Änderungen wirksam werden, ist es empfohlen einen Neustart der UMC-"
135
"Damit die Änderungen wirksam werden, ist es empfohlen einen Neustart der UMC-"
150
"Server-Komponenten durchzuführen."
136
"Server-Komponenten durchzuführen."
151
137
152
#: umc/js/updater/UpdatesPage.js:159 umc/js/updater/UpdatesPage.js:446
138
#: umc/js/updater/UpdatesPage.js:183 umc/js/updater/UpdatesPage.js:491
153
msgid ""
139
msgid ""
154
"Further release updates are available but cannot be installed because the "
140
"Further release updates are available but cannot be installed because the "
155
"component '{0}' is not available for newer release versions."
141
"component '{0}' is not available for newer release versions."
 Lines 158-164    Link Here 
158
"werden, da die Komponente '{0}' noch nicht für neuere Releaseversionen "
144
"werden, da die Komponente '{0}' noch nicht für neuere Releaseversionen "
159
"bereitgestellt wurde."
145
"bereitgestellt wurde."
160
146
161
#: umc/js/updater.js:293
147
#: umc/js/updater.js:324
162
msgid ""
148
msgid ""
163
"In normal case, trouble-free use by users is not possible during the update, "
149
"In normal case, trouble-free use by users is not possible during the update, "
164
"since system services may need to be restarted. "
150
"since system services may need to be restarted. "
 Lines 166-172    Link Here 
166
"Im Normalfall ist während des Updates kein störungsfreies Arbeiten von "
152
"Im Normalfall ist während des Updates kein störungsfreies Arbeiten von "
167
"Anwendern möglich, da beispielsweise Dienste neu gestartet werden. "
153
"Anwendern möglich, da beispielsweise Dienste neu gestartet werden. "
168
154
169
#: umc/js/updater/ProgressPage.js:113 umc/js/updater/UpdatesPage.js:88
155
#: umc/js/updater.js:175 umc/js/updater/UpdatesPage.js:102
170
msgid ""
156
msgid ""
171
"In order to complete the recently executed action, it is required to reboot "
157
"In order to complete the recently executed action, it is required to reboot "
172
"the system."
158
"the system."
 Lines 174-196    Link Here 
174
"Um die kürzlich ausgeführte Aktion abzuschließen, ist es erforderlich, das "
160
"Um die kürzlich ausgeführte Aktion abzuschließen, ist es erforderlich, das "
175
"System neu zu starten."
161
"System neu zu starten."
176
162
177
#: umc/js/updater/UpdatesPage.js:511
163
#: umc/js/updater/UpdatesPage.js:557
178
msgid "Information about the updates"
164
msgid "Information about the updates"
179
msgstr "Informationen zu den Aktualisierungen"
165
msgstr "Informationen zu den Aktualisierungen"
180
166
181
#: umc/js/updater.js:246 umc/js/updater.js:329
167
#: umc/js/updater.js:277 umc/js/updater.js:360
182
msgid "Install"
168
msgid "Install"
183
msgstr "Installieren"
169
msgstr "Installieren"
184
170
185
#: umc/js/updater/UpdatesPage.js:525
171
#: umc/js/updater/UpdatesPage.js:571
186
msgid "Install package updates"
172
msgid "Install package updates"
187
msgstr "Paket-Aktualisierungen installieren"
173
msgstr "Paket-Aktualisierungen installieren"
188
174
189
#: umc/js/updater/UpdatesPage.js:285
175
#: umc/js/updater/UpdatesPage.js:319
190
msgid "Install release update"
176
msgid "Install release update"
191
msgstr "Release-Aktualisierungen installieren"
177
msgstr "Release-Aktualisierungen installieren"
192
178
193
#: umc/js/updater.js:292
179
#: umc/js/updater.js:323
194
msgid ""
180
msgid ""
195
"Installing a system update is a significant change to this system and could "
181
"Installing a system update is a significant change to this system and could "
196
"have impact to other systems. "
182
"have impact to other systems. "
 Lines 198-204    Link Here 
198
"Das Einspielen eines Updates ist eine signifikante Veränderung des "
184
"Das Einspielen eines Updates ist eine signifikante Veränderung des "
199
"betreffenden Systems, die auch Auswirkungen auf andere Systeme haben kann. "
185
"betreffenden Systems, die auch Auswirkungen auf andere Systeme haben kann. "
200
186
201
#: umc/js/updater.js:295
187
#: umc/js/updater.js:326
202
msgid ""
188
msgid ""
203
"It is also recommended to evaluate the update in a test environment and to "
189
"It is also recommended to evaluate the update in a test environment and to "
204
"create a backup of the system."
190
"create a backup of the system."
 Lines 206-224    Link Here 
206
"Tests in einer Testumgebung und die Erstellung einer Sicherung des Systems "
192
"Tests in einer Testumgebung und die Erstellung einer Sicherung des Systems "
207
"werden ebenfalls empfohlen."
193
"werden ebenfalls empfohlen."
208
194
209
#: umc/js/updater/ProgressPage.js:284
195
#: umc/js/updater/LogPage.js:79
210
msgid "It took {elapsed} to complete.<br/>"
211
msgstr "Er hat {elapsed} benötigt.<br/>"
212
213
#: umc/js/updater/ProgressPage.js:82
214
msgid "Log file view"
196
msgid "Log file view"
215
msgstr "Protokoll"
197
msgstr "Protokoll"
216
198
217
#: umc/js/updater.js:300
199
#: umc/js/updater.js:331
218
msgid "Logfiles can be found in the directory /var/log/univention/."
200
msgid "Logfiles can be found in the directory /var/log/univention/."
219
msgstr "Logdateien können im Verzeichnis /var/log/univention/ gefunden werden."
201
msgstr "Logdateien können im Verzeichnis /var/log/univention/ gefunden werden."
220
202
221
#: umc/js/updater.js:299
203
#: umc/js/updater.js:330
222
msgid ""
204
msgid ""
223
"Nonetheless, the update proceeds and the update can be monitored from a new "
205
"Nonetheless, the update proceeds and the update can be monitored from a new "
224
"UMC session. "
206
"UMC session. "
 Lines 226-249    Link Here 
226
"Das Update wird trotzdem weiter durchgeführt, der Vorgang kann in einer "
208
"Das Update wird trotzdem weiter durchgeführt, der Vorgang kann in einer "
227
"neuen UMC-Sitzung weiter beobachtet werden. "
209
"neuen UMC-Sitzung weiter beobachtet werden. "
228
210
229
#: umc/js/updater/UpdatesPage.js:60
211
#: umc/js/updater/UpdatesPage.js:63
230
msgid "Overview of all updates that affect the system as a whole."
212
msgid "Overview of all updates that affect the system as a whole."
231
msgstr ""
213
msgstr ""
232
"Überblick über Software-Aktualisierungen, die das Gesamtsystem betreffen"
214
"Überblick über Software-Aktualisierungen, die das Gesamtsystem betreffen"
233
215
234
#: umc/js/updater/UpdatesPage.js:177 umc/js/updater/UpdatesPage.js:248
216
#: umc/js/updater/UpdatesPage.js:200 umc/js/updater/UpdatesPage.js:282
235
msgid "Package update status not yet checked"
217
msgid "Package update status not yet checked"
236
msgstr "Der Paket-Aktualisierungsstatus wurde noch nicht geprüft."
218
msgstr "Der Paket-Aktualisierungsstatus wurde noch nicht geprüft."
237
219
238
#: umc/js/updater/UpdatesPage.js:359
220
#: umc/js/updater/UpdatesPage.js:404
239
msgid "Package updates"
221
msgid "Package updates"
240
msgstr "Paket-Aktualisierungen"
222
msgstr "Paket-Aktualisierungen"
241
223
242
#: umc/js/updater/UpdatesPage.js:574
224
#: umc/js/updater/UpdatesPage.js:620
243
msgid "Package updates are available."
225
msgid "Package updates are available."
244
msgstr "Es sind Paket-Aktualisierungen verfügbar."
226
msgstr "Es sind Paket-Aktualisierungen verfügbar."
245
227
246
#: umc/js/updater.js:303
228
#: umc/js/updater.js:334
247
msgid ""
229
msgid ""
248
"Please also consider the release notes, changelogs and references posted in "
230
"Please also consider the release notes, changelogs and references posted in "
249
"the <a href='http://forum.univention.de'>Univention Forum</a>."
231
"the <a href='http://forum.univention.de'>Univention Forum</a>."
 Lines 252-297    Link Here 
252
"jeweiligen Update in dem <a href='http://forum.univention.de'>Univention "
234
"jeweiligen Update in dem <a href='http://forum.univention.de'>Univention "
253
"Forum</a>."
235
"Forum</a>."
254
236
255
#: umc/js/updater/UpdatesPage.js:548
237
#: umc/js/updater/UpdatesPage.js:594
256
#, python-format
238
#, python-format
257
msgid "Please visit the <a %s>App Center Module</a> to install these updates."
239
msgid "Please visit the <a %s>App Center Module</a> to install these updates."
258
msgstr ""
240
msgstr ""
259
"Bitte öffnen Sie das <a %s>App Center Modul</a>, um diese Aktualisierungen "
241
"Bitte öffnen Sie das <a %s>App Center Modul</a>, um diese Aktualisierungen "
260
"zu installieren."
242
"zu installieren."
261
243
262
#: umc/js/updater/UpdatesPage.js:313 umc/js/updater/UpdatesPage.js:651
244
#: umc/js/updater/UpdatesPage.js:355 umc/js/updater/UpdatesPage.js:697
263
msgid "Reboot"
245
msgid "Reboot"
264
msgstr "Neu starten"
246
msgstr "Neu starten"
265
247
266
#: umc/js/updater/UpdatesPage.js:333
248
#: umc/js/updater/UpdatesPage.js:378
267
msgid "Reboot required"
249
msgid "Reboot required"
268
msgstr "Neustart erforderlich"
250
msgstr "Neustart erforderlich"
269
251
270
#: umc/js/updater/UpdatesPage.js:306
252
#: umc/js/updater/UpdatesPage.js:348
271
msgid "Refresh"
253
msgid "Refresh"
272
msgstr "Aktualisieren"
254
msgstr "Aktualisieren"
273
255
274
#: umc/js/updater/UpdatesPage.js:341
256
#: umc/js/updater/UpdatesPage.js:386
275
msgid "Release information"
257
msgid "Release information"
276
msgstr "Aktueller Status"
258
msgstr "Aktueller Status"
277
259
278
#: umc/js/updater/UpdatesPage.js:349
260
#: umc/js/updater/UpdatesPage.js:394
279
msgid "Release updates"
261
msgid "Release updates"
280
msgstr "Release-Aktualisierungen"
262
msgstr "Release-Aktualisierungen"
281
263
282
#: umc/js/updater/UpdatesPage.js:321
264
#: umc/js/updater.js:421
265
msgid "See the log for further info !"
266
msgstr "Weitere Infos entnehmen Sie bitte dem Protokoll"
267
268
#: umc/js/updater/UpdatesPage.js:69
269
msgid "Show logfile"
270
msgstr "Protokoll anzeigen"
271
272
#: umc/js/updater/UpdatesPage.js:363
283
msgid "Start Upgrade"
273
msgid "Start Upgrade"
284
msgstr "Aktualisierung starten"
274
msgstr "Aktualisierung starten"
285
275
286
#: umc/js/updater.js:236
276
#: umc/js/updater.js:267
287
msgid "Start Upgrade?"
277
msgid "Start Upgrade?"
288
msgstr "Aktualisierung starten?"
278
msgstr "Aktualisierung starten?"
289
279
290
#: umc/js/updater/UpdatesPage.js:555
280
#: umc/js/updater.js:412
281
msgid "Starting the update process..."
282
msgstr "Starte den Updatevorgang..."
283
284
#: umc/js/updater/UpdatesPage.js:601
291
msgid "The App Center is not available or currently unreachable"
285
msgid "The App Center is not available or currently unreachable"
292
msgstr "Das App Center ist nicht verfügbar oder momentan nicht erreichbar"
286
msgstr "Das App Center ist nicht verfügbar oder momentan nicht erreichbar"
293
287
294
#: umc/js/updater.js:354
288
#: umc/js/updater.js:385
295
msgid ""
289
msgid ""
296
"The Univention Updater action could not be started [Error {status}]: "
290
"The Univention Updater action could not be started [Error {status}]: "
297
"{message}"
291
"{message}"
 Lines 299-309    Link Here 
299
"Der Univention Updater konnte nicht gestartet werden [Fehler {status}]: "
293
"Der Univention Updater konnte nicht gestartet werden [Fehler {status}]: "
300
"{message}"
294
"{message}"
301
295
302
#: umc/js/updater/UpdatesPage.js:79
296
#: umc/js/updater/UpdatesPage.js:93
303
msgid "The computer is now rebooting. "
297
msgid "The computer is now rebooting. "
304
msgstr "Der Computer wird jetzt neu gestartet. "
298
msgstr "Der Computer wird jetzt neu gestartet. "
305
299
306
#: umc/js/updater.js:482
300
#: umc/js/updater.js:519
307
msgid ""
301
msgid ""
308
"The connection to the server was lost, trying to reconnect. You may need to "
302
"The connection to the server was lost, trying to reconnect. You may need to "
309
"re-authenticate when the connection is restored."
303
"re-authenticate when the connection is restored."
 Lines 312-445    Link Here 
312
"wieder aufzunehmen. Wahrscheinlich müssen Sie sich neu anmelden, wenn die "
306
"wieder aufzunehmen. Wahrscheinlich müssen Sie sich neu anmelden, wenn die "
313
"Verbindung wieder hergestellt ist."
307
"Verbindung wieder hergestellt ist."
314
308
315
#: umc/js/updater/ProgressPage.js:281
309
#: umc/js/updater/UpdatesPage.js:476
316
msgid "The current job (<b>{label}</b>) is now finished.<br/>"
317
msgstr "Der aktuelle Vorgang (<b>{label}</b>) ist jetzt beendet.<br/>"
318
319
#: umc/js/updater/UpdatesPage.js:431
320
msgid "The currently installed release version is {ucs_version}"
310
msgid "The currently installed release version is {ucs_version}"
321
msgstr "Die momentan installierte Version ist {ucs_version}"
311
msgstr "Die momentan installierte Version ist {ucs_version}"
322
312
323
#: umc/js/updater/UpdatesPage.js:429
313
#: umc/js/updater/UpdatesPage.js:474
324
msgid ""
314
msgid ""
325
"The currently installed release version is {ucs_version} errata{erratalevel}"
315
"The currently installed release version is {ucs_version} errata{erratalevel}"
326
msgstr ""
316
msgstr ""
327
"Die momentan installierte Version ist {ucs_version} errata{erratalevel}"
317
"Die momentan installierte Version ist {ucs_version} errata{erratalevel}"
328
318
329
#: umc/js/updater/ProgressPage.js:183
319
#: umc/js/updater.js:339
330
msgid "The job <b>{label}</b> (started {elapsed} ago) is currently running."
331
msgstr ""
332
"Momentan läuft der Aktualisierungsauftrag <b>{label}</b> (gestartet vor "
333
"{elapsed})"
334
335
#: umc/js/updater/_LogViewer.js:151
336
msgid ""
320
msgid ""
337
"The log file exceeded {max} lines by {exceeded}. Please see the full logfile."
338
msgstr ""
339
"Das Protokoll hat {max} Zeilen um {exceeded} überschritten. Bitte überprüfen "
340
"Sie das gesamte Protokoll."
341
342
#: umc/js/updater.js:308
343
msgid ""
344
"The update can take a long time and the system may respond slowly. You may "
321
"The update can take a long time and the system may respond slowly. You may "
345
"be temporarily unable to log in."
322
"be temporarily unable to log in."
346
msgstr ""
323
msgstr ""
347
"Das Update kann eine lange Zeit in Anspruch nehmen und Ihr System träge "
324
"Das Update kann eine lange Zeit in Anspruch nehmen und Ihr System träge "
348
"reagieren. Es ist möglich, dass Sie sich zeitweise nicht neu anmelden können."
325
"reagieren. Es ist möglich, dass Sie sich zeitweise nicht neu anmelden können."
349
326
350
#: umc/js/updater/UpdatesPage.js:541
327
#: umc/js/updater.js:423
328
msgid "The update process was successful."
329
msgstr "Der Updatevorgang war erfolgreich."
330
331
#: umc/js/updater/UpdatesPage.js:587
351
msgid "There are App Center updates available."
332
msgid "There are App Center updates available."
352
msgstr "Es sind App Center-Aktualisierungen verfügbar."
333
msgstr "Es sind App Center-Aktualisierungen verfügbar."
353
334
354
#: umc/js/updater/UpdatesPage.js:550
335
#: umc/js/updater/UpdatesPage.js:596
355
msgid "There are no App Center updates available."
336
msgid "There are no App Center updates available."
356
msgstr "Es sind keine App Center-Aktualisierungen verfügbar."
337
msgstr "Es sind keine App Center-Aktualisierungen verfügbar."
357
338
358
#: umc/js/updater/UpdatesPage.js:575
339
#: umc/js/updater/UpdatesPage.js:621
359
msgid "There are no package updates available."
340
msgid "There are no package updates available."
360
msgstr "Es sind keine Paket-Aktualisierungen verfügbar."
341
msgstr "Es sind keine Paket-Aktualisierungen verfügbar."
361
342
362
#: umc/js/updater/UpdatesPage.js:145 umc/js/updater/UpdatesPage.js:235
343
#: umc/js/updater/UpdatesPage.js:169 umc/js/updater/UpdatesPage.js:269
363
msgid "There are no release updates available."
344
msgid "There are no release updates available."
364
msgstr "Es sind keine Release-Aktualisierungen verfügbar."
345
msgstr "Es sind keine Release-Aktualisierungen verfügbar."
365
346
366
#: umc/js/updater/UpdatesPage.js:448
347
#: umc/js/updater/UpdatesPage.js:493
367
msgid "There are no updates available."
348
msgid "There are no updates available."
368
msgstr "Es sind keine Aktualisierungen verfügbar."
349
msgstr "Es sind keine Aktualisierungen verfügbar."
369
350
370
#: umc/js/updater/UpdatesPage.js:444
351
#: umc/js/updater/UpdatesPage.js:489
371
msgid "There are updates available."
352
msgid "There are updates available."
372
msgstr "Es sind Aktualisierungen verfügbar."
353
msgstr "Es sind Aktualisierungen verfügbar."
373
354
374
#: umc/js/updater/UpdatesPage.js:80
355
#: umc/js/updater/UpdatesPage.js:94
375
msgid "This may take some time. Please be patient. "
356
msgid "This may take some time. Please be patient. "
376
msgstr "Das kann einige Zeit dauern. Bitte haben Sie etwas Geduld. "
357
msgstr "Das kann einige Zeit dauern. Bitte haben Sie etwas Geduld. "
377
358
378
#: umc/js/updater.js:294
359
#: umc/js/updater.js:325
379
msgid "Thus, updates shouldn't be installed on a live system. "
360
msgid "Thus, updates shouldn't be installed on a live system. "
380
msgstr "Deshalb sollten Sie das Update nicht im laufenden Betrieb einspielen. "
361
msgstr "Deshalb sollten Sie das Update nicht im laufenden Betrieb einspielen. "
381
362
382
#: umc/js/updater/ProgressPage.js:383
363
#: umc/js/updater/UpdatesPage.js:624
383
msgid ""
384
"Univention Updater could not successfully complete the current job. The log "
385
"file should show the cause of the failure. If you're finished examining the "
386
"log file you may press the 'back' button to close this view."
387
msgstr ""
388
"Univention Updater konnte den aktuellen Auftrag nicht erfolgreich "
389
"abschließen. Im Protokoll sollten Sie die Ursache des Fehlschlages sehen "
390
"können. Der Knopf 'Zurück' schließt die aktuelle Ansicht."
391
392
#: umc/js/updater/ProgressPage.js:378
393
msgid ""
394
"Univention Updater has successfully finished the current job. You may read "
395
"through the log file. If you're finished you may press the 'back' button to "
396
"close this view."
397
msgstr ""
398
"Univention Updater hat den aktuellen Auftrag erfolgreich abgeschlossen. Sie "
399
"können sich das Protokoll noch anschauen. Drücken Sie dann den 'Zurück' "
400
"Knopf, um die Ansicht zu schließen und zur Übersicht zurückzukehren."
401
402
#: umc/js/updater/ProgressPage.js:372
403
msgid "Univention Updater is working"
404
msgstr "Univention Updater ist gerade aktiv"
405
406
#: umc/js/updater/ProgressPage.js:377
407
msgid "Univention Updater job completed"
408
msgstr "Univention Updater Auftrag abgeschlossen"
409
410
#: umc/js/updater/ProgressPage.js:382
411
msgid "Univention Updater job failed"
412
msgstr "Univention Updater Auftrag ist fehlgeschlagen"
413
414
#: umc/js/updater/UpdatesPage.js:578
415
msgid "Update availability could not be checked."
364
msgid "Update availability could not be checked."
416
msgstr "Verfügbarkeit von Aktualisierungen konnte nicht geprüft werden."
365
msgstr "Verfügbarkeit von Aktualisierungen konnte nicht geprüft werden."
417
366
418
#: umc/js/updater/ProgressPage.js:381
367
#: umc/js/updater.js:421
419
msgid "Update failed"
368
msgid "Update error"
420
msgstr "Aktualisierung fehlgeschlagen"
369
msgstr "Updatefehler"
421
370
422
#: umc/js/updater/ProgressPage.js:376
371
#: umc/js/updater/UpdatesPage.js:141
423
msgid "Update finished"
424
msgstr "Aktualisierung abgeschlossen"
425
426
#: umc/js/updater/ProgressPage.js:371
427
msgid "Update in progress"
428
msgstr "Aktualisierung läuft"
429
430
#: umc/js/updater/ProgressPage.js:73
431
msgid "Update progress"
432
msgstr "Updatevorgang"
433
434
#: umc/js/updater/UpdatesPage.js:127
435
msgid "Update system up to release"
372
msgid "Update system up to release"
436
msgstr "System bis zu dieser Version aktualisieren"
373
msgstr "System bis zu dieser Version aktualisieren"
437
374
438
#: umc/js/updater/UpdatesPage.js:58
375
#: umc/js/updater/UpdatesPage.js:61
439
msgid "Updates"
376
msgid "Updates"
440
msgstr "Aktualisierungen"
377
msgstr "Aktualisierungen"
441
378
442
#: umc/js/updater/UpdatesPage.js:82
379
#: umc/js/updater/UpdatesPage.js:96
443
msgid ""
380
msgid ""
444
"When the connection is back you will be prompted to authenticate yourself "
381
"When the connection is back you will be prompted to authenticate yourself "
445
"again."
382
"again."
 Lines 447-463    Link Here 
447
"Wenn die Verbindung wieder hergestellt ist, werden Sie aufgefordert, sich "
384
"Wenn die Verbindung wieder hergestellt ist, werden Sie aufgefordert, sich "
448
"noch einmal neu anzumelden."
385
"noch einmal neu anzumelden."
449
386
450
#: umc/js/updater/ProgressPage.js:286
387
#: umc/js/updater.js:491
451
msgid "You may return to the overview by clicking the 'back' button now."
452
msgstr ""
453
"Sie können jetzt zur Übersicht zurückkehren, indem Sie den 'Zurück'-Knopf "
454
"drücken."
455
456
#: umc/js/updater/ProgressPage.js:187
457
msgid "You're currently watching its log file <b>{logfile}</b>"
458
msgstr "Sie sehen die Protokolldatei <b>{logfile}</b>"
459
460
#: umc/js/updater.js:454
461
msgid ""
388
msgid ""
462
"Your current session has expired, or the connection to the server was lost. "
389
"Your current session has expired, or the connection to the server was lost. "
463
"You must authenticate yourself again."
390
"You must authenticate yourself again."
 Lines 465-488    Link Here 
465
"Ihre aktuelle Sitzung ist abgelaufen, oder die Verbindung zum Server war "
392
"Ihre aktuelle Sitzung ist abgelaufen, oder die Verbindung zum Server war "
466
"verlorengegangen. Sie müssen sich noch einmal neu anmelden."
393
"verlorengegangen. Sie müssen sich noch einmal neu anmelden."
467
394
468
#: umc/js/updater/ProgressPage.js:103
395
#: umc/js/updater/LogPage.js:56
469
msgid "back"
396
msgid "back"
470
msgstr "Zurück"
397
msgstr "Zurück"
471
398
472
#: umc/js/updater.js:185
399
#: umc/js/updater/LogPage.js:64
400
msgid "jump to end of log"
401
msgstr "Zum Ende des Protokolls springen"
402
403
#: umc/js/updater.js:216
473
msgid "{count} packages to be REMOVED"
404
msgid "{count} packages to be REMOVED"
474
msgstr "{count} Pakete werden ENTFERNT"
405
msgstr "{count} Pakete werden ENTFERNT"
475
406
476
#: umc/js/updater.js:223
407
#: umc/js/updater.js:254
477
msgid "{count} packages to be installed"
408
msgid "{count} packages to be installed"
478
msgstr "{count} Pakete werden NEU installiert"
409
msgstr "{count} Pakete werden NEU installiert"
479
410
480
#: umc/js/updater.js:204
411
#: umc/js/updater.js:235
481
msgid "{count} packages to be updated"
412
msgid "{count} packages to be updated"
482
msgstr "{count} Pakete werden aktualisiert"
413
msgstr "{count} Pakete werden aktualisiert"
483
414
415
#~ msgid "... loading job data ..."
416
#~ msgstr "... Daten werden geladen ..."
417
418
#~ msgid "... please wait ..."
419
#~ msgstr "... bitte warten ..."
420
484
#~ msgid "Application updates available"
421
#~ msgid "Application updates available"
485
#~ msgstr "Aktualisierungen für Applikationen verfügbar"
422
#~ msgstr "Aktualisierungen für Applikationen verfügbar"
486
423
424
#~ msgid ""
425
#~ "As long as the Univention Updater is updating your system, you're not "
426
#~ "allowed to manage settings. You may watch the progress, or close the "
427
#~ "module."
428
#~ msgstr ""
429
#~ "Solange Univention Updater Ihr System aktualisiert, können Sie keine "
430
#~ "Einstellungen verändern. Sie können die Aktualisierung hier verfolgen "
431
#~ "oder das Modul schließen."
432
433
#~ msgid "It took {elapsed} to complete.<br/>"
434
#~ msgstr "Er hat {elapsed} benötigt.<br/>"
435
487
#~ msgid "No application updates available"
436
#~ msgid "No application updates available"
488
#~ msgstr "Keine Aktualisierungen für Applikationen verfügbar"
437
#~ msgstr "Keine Aktualisierungen für Applikationen verfügbar"
438
439
#~ msgid "The current job (<b>{label}</b>) is now finished.<br/>"
440
#~ msgstr "Der aktuelle Vorgang (<b>{label}</b>) ist jetzt beendet.<br/>"
441
442
#~ msgid "The job <b>{label}</b> (started {elapsed} ago) is currently running."
443
#~ msgstr ""
444
#~ "Momentan läuft der Aktualisierungsauftrag <b>{label}</b> (gestartet vor "
445
#~ "{elapsed})"
446
447
#~ msgid ""
448
#~ "The log file exceeded {max} lines by {exceeded}. Please see the full "
449
#~ "logfile."
450
#~ msgstr ""
451
#~ "Das Protokoll hat {max} Zeilen um {exceeded} überschritten. Bitte "
452
#~ "überprüfen Sie das gesamte Protokoll."
453
454
#~ msgid "This may take some time. Please be patient."
455
#~ msgstr "Das kann einige Zeit dauern. Bitte haben Sie etwas Geduld. "
456
457
#~ msgid ""
458
#~ "Univention Updater could not successfully complete the current job. The "
459
#~ "log file should show the cause of the failure. If you're finished "
460
#~ "examining the log file you may press the 'back' button to close this view."
461
#~ msgstr ""
462
#~ "Univention Updater konnte den aktuellen Auftrag nicht erfolgreich "
463
#~ "abschließen. Im Protokoll sollten Sie die Ursache des Fehlschlages sehen "
464
#~ "können. Der Knopf 'Zurück' schließt die aktuelle Ansicht."
465
466
#~ msgid ""
467
#~ "Univention Updater has successfully finished the current job. You may "
468
#~ "read through the log file. If you're finished you may press the 'back' "
469
#~ "button to close this view."
470
#~ msgstr ""
471
#~ "Univention Updater hat den aktuellen Auftrag erfolgreich abgeschlossen. "
472
#~ "Sie können sich das Protokoll noch anschauen. Drücken Sie dann den "
473
#~ "'Zurück' Knopf, um die Ansicht zu schließen und zur Übersicht "
474
#~ "zurückzukehren."
475
476
#~ msgid "Univention Updater is working"
477
#~ msgstr "Univention Updater ist gerade aktiv"
478
479
#~ msgid "Univention Updater job completed"
480
#~ msgstr "Univention Updater Auftrag abgeschlossen"
481
482
#~ msgid "Univention Updater job failed"
483
#~ msgstr "Univention Updater Auftrag ist fehlgeschlagen"
484
485
#~ msgid "Update failed"
486
#~ msgstr "Aktualisierung fehlgeschlagen"
487
488
#~ msgid "Update finished"
489
#~ msgstr "Aktualisierung abgeschlossen"
490
491
#~ msgid "Update in progress"
492
#~ msgstr "Aktualisierung läuft"
493
494
#~ msgid "Updating system..."
495
#~ msgstr "Aktualisiere System"
496
497
#~ msgid "You may return to the overview by clicking the 'back' button now."
498
#~ msgstr ""
499
#~ "Sie können jetzt zur Übersicht zurückkehren, indem Sie den 'Zurück'-Knopf "
500
#~ "drücken."
501
502
#~ msgid "You're currently watching its log file <b>{logfile}</b>"
503
#~ msgstr "Sie sehen die Protokolldatei <b>{logfile}</b>"

Return to bug 25558