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

Collapse All | Expand All

(-)umc/python/online/__init__.py (-14 / +49 lines)
 Lines 104-111    Link Here 
104
		'logfile':		'/var/log/univention/updater.log',
104
		'logfile':		'/var/log/univention/updater.log',
105
		'statusfile':	'/var/lib/univention-updater/univention-updater.status'
105
		'statusfile':	'/var/lib/univention-updater/univention-updater.status'
106
	},
106
	},
107
	# no API available, and no wrapper-wrapper too (or at least, didn't find one).
107
	# *** IMPORTANT! *** the arg list from our request contains the COMPONENT name but the command
108
	# Should I write a wrapper, especially to get consistent behaviour in terms of 'logfile' and 'statusfile'?
108
	#					here must contain the list of DEFAULTPACKAGES!
109
	# cmd = '/usr/share/univention-updater/univention-updater-umc-univention-install %s' % (' '.join(pkglist))
109
	# cmd = '/usr/share/univention-updater/univention-updater-umc-univention-install %s' % (' '.join(pkglist))
110
	'component': {
110
	'component': {
111
		'purpose':		_("Install component '%s'"),
111
		'purpose':		_("Install component '%s'"),
 Lines 843-858    Link Here 
843
				MODULE.info("   << %s" % s)
843
				MODULE.info("   << %s" % s)
844
		# -----------------------------------
844
		# -----------------------------------
845
		result = None
845
		result = None
846
		job = 'unknown'
846
		job = ''
847
		if self._current_job and 'job' in self._current_job:
847
		if self._current_job and 'job' in self._current_job:
848
			job = self._current_job['job']
848
			job = self._current_job['job']
849
		else:
849
		else:
850
			job = request.options.get('job','none')
850
			job = request.options.get('job','')
851
851
852
		count = request.options.get('count',0)
852
		count = request.options.get('count',0)
853
		result = 0 if count < 0 else []
853
		result = 0 if count < 0 else []
854
		if not job in INSTALLERS:
854
		if not job in INSTALLERS:
855
			MODULE.warn("   ?? Don't know a '%s' job" % job)
855
			# job empty: this is the first call I can't avoid
856
			if job != '':
857
				MODULE.warn("   ?? Don't know a '%s' job" % job)
856
		else:
858
		else:
857
			if not 'logfile' in INSTALLERS[job]:
859
			if not 'logfile' in INSTALLERS[job]:
858
				MODULE.warn("   ?? Job '%s' has no associated log file" % job)
860
				MODULE.warn("   ?? Job '%s' has no associated log file" % job)
 Lines 900-906    Link Here 
900
		job = request.options.get('job','')
902
		job = request.options.get('job','')
901
		result = {}
903
		result = {}
902
		if job in INSTALLERS:
904
		if job in INSTALLERS:
903
			result = INSTALLERS[job]
905
			# make a copy, not a reference!
906
			result = {}
907
			for arg in INSTALLERS[job]:
908
				result[arg] = INSTALLERS[job][arg]
909
				
904
			if 'statusfile' in INSTALLERS[job]:
910
			if 'statusfile' in INSTALLERS[job]:
905
				try:
911
				try:
906
					for line in open(INSTALLERS[job]['statusfile']):
912
					for line in open(INSTALLERS[job]['statusfile']):
 Lines 944-949    Link Here 
944
					result['label'] = result['purpose'] % result['detail']
950
					result['label'] = result['purpose'] % result['detail']
945
				else:
951
				else:
946
					result['label'] = result['purpose']
952
					result['label'] = result['purpose']
953
			# Affordance to reboot... hopefully this gets set before
954
			# we stop polling on this job status
955
			self.ucr.load()		# make it as current as possible
956
			result['reboot'] = self.ucr.is_true('update/reboot/required',False)
947
957
948
		# ----------- DEBUG -----------------
958
		# ----------- DEBUG -----------------
949
		MODULE.info("online/installer/status returns:")
959
		MODULE.info("online/installer/status returns:")
 Lines 972-984    Link Here 
972
			at the top of the file.
982
			at the top of the file.
973
		"""
983
		"""
974
		# ----------- DEBUG -----------------
984
		# ----------- DEBUG -----------------
975
		MODULE.info("online/installer/execute invoked with:")
985
		MODULE.warn("online/installer/execute invoked with:")
976
		pp = pprint.PrettyPrinter(indent=4)
986
		pp = pprint.PrettyPrinter(indent=4)
977
		st = pp.pformat(request.options).split("\n")
987
		st = pp.pformat(request.options).split("\n")
978
		for s in st:
988
		for s in st:
979
				MODULE.info("   << %s" % s)
989
				MODULE.warn("   << %s" % s)
980
		# -----------------------------------
990
		# -----------------------------------
981
		
991
		
992
		# Clean up any stored job details ... they're now obsolete.
993
		self._current_job = {}
994
		
982
		result = {}
995
		result = {}
983
		result['status'] = 0		# successful. If not: set result['message'] too.
996
		result['status'] = 0		# successful. If not: set result['message'] too.
984
		
997
		
 Lines 999-1009    Link Here 
999
			self.finished(request.id,result)
1012
			self.finished(request.id,result)
1000
			return
1013
			return
1001
		
1014
		
1002
		cmd = INSTALLERS[subject]['command']
1015
		try:
1003
		if cmd.find('%') != -1:
1016
			# Assemble the command line, now somewhat complicated:
1004
			cmd = cmd % request.options.get('detail','')
1017
			#
1005
		MODULE.info("   ++ Creating job: '%s'" % cmd)
1018
			#	(1)	take the 'command' entry from the INSTALLERS entry of this subject
1006
		self.__create_at_job(cmd,detail)
1019
			#	(2)	if it doesn't contain a percent sign -> ready.
1020
			#	(3)	if it contains a percent sign: we must format something:
1021
			#	(4)	if the subject is about 'component' we must get the 'defaultpackages'
1022
			#		entry from the UCR tuple named by 'detail' and use that.
1023
			#	(5)	if not, we can format the 'detail' field into the command.
1024
			cmd = '%s' % INSTALLERS[subject]['command']		# I need a copy of this string!
1025
			if cmd.find('%') != -1:
1026
				if subject == 'component':
1027
					# Strictly spoken, we can't arrive here if 'defaultpackages' is not set
1028
					ucrs = '%s/%s/defaultpackages' % (COMPONENT_BASE,detail)
1029
					pkgs = self.ucr.get(ucrs,'')
1030
					cmd = cmd % pkgs
1031
					MODULE.warn("  Resolution of default packages of the '%s' component:" % detail)
1032
					MODULE.warn("     UCRS = '%s'" % ucrs)
1033
					MODULE.warn("     PKGS = '%s'" % pkgs)
1034
					MODULE.warn("     CMD  = '%s'" % cmd)
1035
				else:
1036
					cmd = cmd % request.options.get('detail','')
1037
			MODULE.warn("   ++ Creating job: '%s'" % cmd)
1038
			self.__create_at_job(cmd,detail)
1039
		except Exception,ex:
1040
			MODULE.warn("   ERROR: %s" % str(ex))
1007
		
1041
		
1008
		# ----------- DEBUG -----------------
1042
		# ----------- DEBUG -----------------
1009
		MODULE.info("online/installer/execute returns:")
1043
		MODULE.info("online/installer/execute returns:")
 Lines 1289-1294    Link Here 
1289
		script = '''
1323
		script = '''
1290
#:started: %s
1324
#:started: %s
1291
#:detail: %s
1325
#:detail: %s
1326
#:command: %s
1292
dpkg-statoverride --add root root 0644 /usr/sbin/univention-management-console-web-server
1327
dpkg-statoverride --add root root 0644 /usr/sbin/univention-management-console-web-server
1293
dpkg-statoverride --add root root 0644 /usr/sbin/univention-management-console-server
1328
dpkg-statoverride --add root root 0644 /usr/sbin/univention-management-console-server
1294
dpkg-statoverride --add root root 0644 /usr/sbin/apache2
1329
dpkg-statoverride --add root root 0644 /usr/sbin/apache2
 Lines 1301-1307    Link Here 
1301
dpkg-statoverride --remove /usr/sbin/univention-management-console-server
1336
dpkg-statoverride --remove /usr/sbin/univention-management-console-server
1302
dpkg-statoverride --remove /usr/sbin/apache2
1337
dpkg-statoverride --remove /usr/sbin/apache2
1303
chmod +x /usr/sbin/univention-management-console-server /usr/sbin/univention-management-console-web-server /usr/sbin/apache2
1338
chmod +x /usr/sbin/univention-management-console-server /usr/sbin/univention-management-console-web-server /usr/sbin/apache2
1304
''' % (started,detail,command)
1339
''' % (started,detail,command,command)
1305
		p1 = subprocess.Popen( [ 'LC_ALL=C at now', ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True )
1340
		p1 = subprocess.Popen( [ 'LC_ALL=C at now', ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True )
1306
		(stdout,stderr) = p1.communicate( script )
1341
		(stdout,stderr) = p1.communicate( script )
1307
		
1342
		
(-)umc/js/online.js (-3 / +9 lines)
 Lines 93-99    Link Here 
93
		
93
		
94
		// waits for the Progress Page to be closed (automatically or by a close button)
94
		// waits for the Progress Page to be closed (automatically or by a close button)
95
		dojo.connect(this._progress,'stopWatching',dojo.hitch(this, function(tab) {
95
		dojo.connect(this._progress,'stopWatching',dojo.hitch(this, function(tab) {
96
			this._updates.refreshPage(true);
97
			this.hideChild(this._progress);
96
			this.hideChild(this._progress);
98
			this.showChild(this._updates);
97
			this.showChild(this._updates);
99
			this.showChild(this._components);
98
			this.showChild(this._components);
 Lines 101-106    Link Here 
101
			this.selectChild(tab);
100
			this.selectChild(tab);
102
		}));
101
		}));
103
		
102
		
103
		// waits for the Progress Page to notify us that a job is finished. This
104
		// should immediately refresh the 'Updates' and 'Components' pages.
105
		dojo.connect(this._progress,'jobFinished',dojo.hitch(this, function() {
106
			this._updates.refreshPage(true);
107
			this._components.refreshPage();
108
		}));
109
		
104
		// waits for the Progress Page to notify us that a job is running
110
		// waits for the Progress Page to notify us that a job is running
105
		dojo.connect(this._progress,'jobStarted',dojo.hitch(this, function() {
111
		dojo.connect(this._progress,'jobStarted',dojo.hitch(this, function() {
106
			this._switch_to_progress_page();
112
			this._switch_to_progress_page();
 Lines 238-244    Link Here 
238
					{
244
					{
239
						txt += "<tr>\n";
245
						txt += "<tr>\n";
240
						txt += "<td style='padding-left:1em;'>" + upd[i][0] + "</td>\n";
246
						txt += "<td style='padding-left:1em;'>" + upd[i][0] + "</td>\n";
241
						txt += "<td style='padding-left:1em;'>" + upd[i][1] + "</td>\n";
247
						txt += "<td style='padding-left:1em;padding-right:.5em;'>" + upd[i][1] + "</td>\n";
242
						txt += "</tr>\n";
248
						txt += "</tr>\n";
243
					}
249
					}
244
				}
250
				}
 Lines 249-255    Link Here 
249
					{
255
					{
250
						txt += "<tr>\n";
256
						txt += "<tr>\n";
251
						txt += "<td style='padding-left:1em;'>" + ins[i][0] + "</td>\n";
257
						txt += "<td style='padding-left:1em;'>" + ins[i][0] + "</td>\n";
252
						txt += "<td style='padding-left:1em;'>" + ins[i][1] + "</td>\n";
258
						txt += "<td style='padding-left:1em;padding-right:.5em;'>" + ins[i][1] + "</td>\n";
253
						txt += "</tr>\n";
259
						txt += "</tr>\n";
254
					}
260
					}
255
				}
261
				}
(-)umc/js/_online/ProgressPage.js (-4 / +26 lines)
 Lines 152-157    Link Here 
152
				
152
				
153
				msg += this._statusfile_data(data.result);
153
				msg += this._statusfile_data(data.result);
154
				
154
				
155
				// -------------- DEBUG ------------------
156
//				for (var v in this._last_job)
157
//				{
158
//					msg += ("<br/>&nbsp;&nbsp;&nbsp;" + v + "&nbsp;=&nbsp;'" + this._last_job[v] + "'");
159
//				}
160
				// ---------------------------------------
161
				
155
				this._head.set('content',msg);
162
				this._head.set('content',msg);
156
				this._pane.layout();
163
				this._pane.layout();
157
				
164
				
 Lines 178-184    Link Here 
178
	
185
	
179
	// takes a status structure as returned from the 'online/installer/status' call,
186
	// takes a status structure as returned from the 'online/installer/status' call,
180
	// extracts the fields that came directly from the status file (if any) and
187
	// extracts the fields that came directly from the status file (if any) and
181
	// formats them in a readable HTML fashion.
188
	// formats them into a one-liner. Returns an empty string if nothing matches.
182
	_statusfile_data: function(data) {
189
	_statusfile_data: function(data) {
183
		
190
		
184
		var txt = '';
191
		var txt = '';
 Lines 243-248    Link Here 
243
		{
250
		{
244
			if ((this._job_key != '') && (this._last_job))
251
			if ((this._job_key != '') && (this._last_job))
245
			{
252
			{
253
				// First thing to do: notify the Module that the job is finished. So it can already
254
				// refresh the 'Updates' and 'Components' pages before the user gets back there.
255
				this.jobFinished();
256
				
246
				// FIXME Manually making empty lines before and after this text; should better be done
257
				// FIXME Manually making empty lines before and after this text; should better be done
247
				//		by a style or a style class.
258
				//		by a style or a style class.
248
				var msg = "&nbsp;<br/>";
259
				var msg = "&nbsp;<br/>";
 Lines 256-266    Link Here 
256
				
267
				
257
				msg += this._statusfile_data(this._last_job);
268
				msg += this._statusfile_data(this._last_job);
258
				
269
				
270
				// -------------- DEBUG ------------------
271
//				for (var v in this._last_job)
272
//				{
273
//					msg += ("<br/>&nbsp;&nbsp;&nbsp;" + v + "&nbsp;=&nbsp;'" + this._last_job[v] + "'");
274
//				}
275
				// ---------------------------------------
276
				
259
				this._head.set('content',msg);
277
				this._head.set('content',msg);
260
				
278
				
261
				// for the last time: scroll log view to bottom and stop polling timer.
279
				this._log.stopWatching();		// now log is freely scrollable manually
262
				this._log.scrollToBottom();
263
				this._log.stopWatching();
264
				
280
				
265
				//alert("Watching is finished, job is '" + this._job_key + "'");
281
				//alert("Watching is finished, job is '" + this._job_key + "'");
266
				
282
				
 Lines 281-286    Link Here 
281
	jobStarted: function() {
297
	jobStarted: function() {
282
	},
298
	},
283
	
299
	
300
	// This function will be called when the already opened ProgressPage encounters
301
	// the end of the current job. The online Module listens here and will refresh
302
	// the 'Updates' and 'Components' pages.
303
	jobFinished: function() {
304
	},
305
	
284
	// online Module calls this when the ProgressPage is to be opened.
306
	// online Module calls this when the ProgressPage is to be opened.
285
	startWatching: function(args) {
307
	startWatching: function(args) {
286
		//alert("ProgressPage::startWatching()");
308
		//alert("ProgressPage::startWatching()");
(-)umc/js/_online/UpdatesPage.js (+8 lines)
 Lines 10-15    Link Here 
10
dojo.declare("umc.modules._online.UpdatesPage", umc.modules._online.Page, {
10
dojo.declare("umc.modules._online.UpdatesPage", umc.modules._online.Page, {
11
	
11
	
12
	i18nClass: 		'umc.modules.online',
12
	i18nClass: 		'umc.modules.online',
13
	_last_reboot:	false,
13
	
14
	
14
    postMixInProperties: function() {
15
    postMixInProperties: function() {
15
16
 Lines 507-512    Link Here 
507
			on = (on == 'true');
508
			on = (on == 'true');
508
		}
509
		}
509
		
510
		
511
		// pop a message up whenever the 'on' value changes
512
		if (on != this._last_reboot)
513
		{
514
			alert("Reboot affordance changed to " + on);
515
			this._last_reboot = on;
516
		}
517
		
510
		var pane = this._form.getChildren()[0].getChildren()[0];
518
		var pane = this._form.getChildren()[0].getChildren()[0];
511
		dojo.toggleClass(pane.domNode,'dijitHidden',! on);
519
		dojo.toggleClass(pane.domNode,'dijitHidden',! on);
512
		
520
		
(-)umc/js/_online/_LogViewer.js (-2 / +1 lines)
 Lines 186-193    Link Here 
186
	// job key can't be an argument here as we don't know it.
186
	// job key can't be an argument here as we don't know it.
187
	startWatching: function(interval) {
187
	startWatching: function(interval) {
188
		
188
		
189
		//alert("LogViewer::StartWatching(" + interval + ")");
190
		
191
		this._check_interval = interval;
189
		this._check_interval = interval;
192
		// clean up any stale display and states from last run
190
		// clean up any stale display and states from last run
193
		this.set('content',this._("... loading log file ..."));
191
		this.set('content',this._("... loading log file ..."));
 Lines 208-213    Link Here 
208
	// effectively stops the polling timer. Can be called from outside (if ProgressPage is being closed)
206
	// effectively stops the polling timer. Can be called from outside (if ProgressPage is being closed)
209
	// or from inside (as 'uninitialize' handler)
207
	// or from inside (as 'uninitialize' handler)
210
	stopWatching: function() {
208
	stopWatching: function() {
209
211
		this._check_interval = 0;
210
		this._check_interval = 0;
212
	},
211
	},
213
	
212
	

Return to bug 22898