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

Collapse All | Expand All

(-)umc/python/online/__init__.py (-32 / +100 lines)
 Lines 44-49    Link Here 
44
from string import join
44
from string import join
45
from subprocess import Popen
45
from subprocess import Popen
46
from hashlib import md5
46
from hashlib import md5
47
from copy import deepcopy
47
48
48
from univention.management.console.log import MODULE
49
from univention.management.console.log import MODULE
49
from univention.management.console.protocol.definitions import *
50
from univention.management.console.protocol.definitions import *
 Lines 104-111    Link Here 
104
		'logfile':		'/var/log/univention/updater.log',
105
		'logfile':		'/var/log/univention/updater.log',
105
		'statusfile':	'/var/lib/univention-updater/univention-updater.status'
106
		'statusfile':	'/var/lib/univention-updater/univention-updater.status'
106
	},
107
	},
107
	# no API available, and no wrapper-wrapper too (or at least, didn't find one).
108
	# *** 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'?
109
	#					here must contain the list of DEFAULTPACKAGES!
109
	# cmd = '/usr/share/univention-updater/univention-updater-umc-univention-install %s' % (' '.join(pkglist))
110
	# cmd = '/usr/share/univention-updater/univention-updater-umc-univention-install %s' % (' '.join(pkglist))
110
	'component': {
111
	'component': {
111
		'purpose':		_("Install component '%s'"),
112
		'purpose':		_("Install component '%s'"),
 Lines 843-864    Link Here 
843
				MODULE.info("   << %s" % s)
844
				MODULE.info("   << %s" % s)
844
		# -----------------------------------
845
		# -----------------------------------
845
		result = None
846
		result = None
846
		job = 'unknown'
847
		job = ''
847
		if self._current_job and 'job' in self._current_job:
848
		if self._current_job and 'job' in self._current_job:
848
			job = self._current_job['job']
849
			job = self._current_job['job']
849
		else:
850
		else:
850
			job = request.options.get('job','none')
851
			job = request.options.get('job','')
851
852
852
		count = request.options.get('count',0)
853
		count = request.options.get('count',0)
853
		result = 0 if count < 0 else []
854
		result = 0 if count < 0 else []
854
		if not job in INSTALLERS:
855
		if not job in INSTALLERS:
855
			MODULE.warn("   ?? Don't know a '%s' job" % job)
856
			# job empty: this is the first call I can't avoid
857
			if job != '':
858
				MODULE.warn("   ?? Don't know a '%s' job" % job)
856
		else:
859
		else:
857
			if not 'logfile' in INSTALLERS[job]:
860
			if not 'logfile' in INSTALLERS[job]:
858
				MODULE.warn("   ?? Job '%s' has no associated log file" % job)
861
				MODULE.warn("   ?? Job '%s' has no associated log file" % job)
859
			else:
862
			else:
860
				fname = INSTALLERS[job]['logfile']
863
				fname = INSTALLERS[job]['logfile']
861
				result = self._logview(fname, count)
864
				if count < 0:
865
					result = self._logstamp(fname)
866
				else:
867
					# don't read complete file if we have an 'ignore' count
868
					if (count == 0) and (self._current_job['lines']):
869
						count = -self._current_job['lines']
870
					result = self._logview(fname, count)
862
				
871
				
863
		# again debug, shortened
872
		# again debug, shortened
864
		if isinstance(result,int):
873
		if isinstance(result,int):
 Lines 900-906    Link Here 
900
		job = request.options.get('job','')
909
		job = request.options.get('job','')
901
		result = {}
910
		result = {}
902
		if job in INSTALLERS:
911
		if job in INSTALLERS:
903
			result = INSTALLERS[job]
912
			# make a copy, not a reference!
913
#			result = {}
914
#			for arg in INSTALLERS[job]:
915
#				result[arg] = INSTALLERS[job][arg]
916
			result = deepcopy(INSTALLERS[job])
917
				
904
			if 'statusfile' in INSTALLERS[job]:
918
			if 'statusfile' in INSTALLERS[job]:
905
				try:
919
				try:
906
					for line in open(INSTALLERS[job]['statusfile']):
920
					for line in open(INSTALLERS[job]['statusfile']):
 Lines 944-949    Link Here 
944
					result['label'] = result['purpose'] % result['detail']
958
					result['label'] = result['purpose'] % result['detail']
945
				else:
959
				else:
946
					result['label'] = result['purpose']
960
					result['label'] = result['purpose']
961
			# Affordance to reboot... hopefully this gets set before
962
			# we stop polling on this job status
963
			self.ucr.load()		# make it as current as possible
964
			result['reboot'] = self.ucr.is_true('update/reboot/required',False)
947
965
948
		# ----------- DEBUG -----------------
966
		# ----------- DEBUG -----------------
949
		MODULE.info("online/installer/status returns:")
967
		MODULE.info("online/installer/status returns:")
 Lines 979-984    Link Here 
979
				MODULE.info("   << %s" % s)
997
				MODULE.info("   << %s" % s)
980
		# -----------------------------------
998
		# -----------------------------------
981
		
999
		
1000
		# Clean up any stored job details ... they're now obsolete.
1001
		self._current_job = {}
1002
				
982
		result = {}
1003
		result = {}
983
		result['status'] = 0		# successful. If not: set result['message'] too.
1004
		result['status'] = 0		# successful. If not: set result['message'] too.
984
		
1005
		
 Lines 999-1010    Link Here 
999
			self.finished(request.id,result)
1020
			self.finished(request.id,result)
1000
			return
1021
			return
1001
		
1022
		
1002
		cmd = INSTALLERS[subject]['command']
1023
		# We want to limit the amount of logfile data being transferred
1003
		if cmd.find('%') != -1:
1024
		# to the frontend. So we remember the line count of the associated
1004
			cmd = cmd % request.options.get('detail','')
1025
		# log file.
1005
		MODULE.info("   ++ Creating job: '%s'" % cmd)
1026
		if 'logfile' in INSTALLERS[subject]:
1006
		self.__create_at_job(cmd,detail)
1027
			fname = INSTALLERS[subject]['logfile']
1028
			count = 0
1029
			try:
1030
				file = open(fname,'r')
1031
				count = 0
1032
				for line in file:
1033
					count += 1
1034
			finally:
1035
				if file != None:
1036
					file.close()
1037
			self._current_job['lines'] = count
1007
		
1038
		
1039
		try:
1040
			# Assemble the command line, now somewhat complicated:
1041
			#
1042
			#	(1)	take the 'command' entry from the INSTALLERS entry of this subject
1043
			#	(2)	if it doesn't contain a percent sign -> ready.
1044
			#	(3)	if it contains a percent sign: we must format something:
1045
			#	(4)	if the subject is about 'component' we must get the 'defaultpackages'
1046
			#		entry from the UCR tuple named by 'detail' and use that.
1047
			#	(5)	if not, we can format the 'detail' field into the command.
1048
			# cmd = '%s' % INSTALLERS[subject]['command']		# I need a copy of this string!
1049
			cmd = INSTALLERS[subject]['command']
1050
			if cmd.find('%') != -1:
1051
				if subject == 'component':
1052
					# Strictly spoken, we can't arrive here if 'defaultpackages' is not set
1053
					ucrs = '%s/%s/defaultpackages' % (COMPONENT_BASE,detail)
1054
					pkgs = self.ucr.get(ucrs,'')
1055
					cmd = cmd % pkgs
1056
					MODULE.info("  Resolution of default packages of the '%s' component:" % detail)
1057
					MODULE.info("     UCRS = '%s'" % ucrs)
1058
					MODULE.info("     PKGS = '%s'" % pkgs)
1059
					MODULE.info("     CMD  = '%s'" % cmd)
1060
				else:
1061
					cmd = cmd % request.options.get('detail','')
1062
			MODULE.info("   ++ Creating job: '%s'" % cmd)
1063
			self.__create_at_job(cmd,detail)
1064
		except Exception,ex:
1065
			MODULE.warn("   ERROR: %s" % str(ex))
1066
		
1008
		# ----------- DEBUG -----------------
1067
		# ----------- DEBUG -----------------
1009
		MODULE.info("online/installer/execute returns:")
1068
		MODULE.info("online/installer/execute returns:")
1010
		pp = pprint.PrettyPrinter(indent=4)
1069
		pp = pprint.PrettyPrinter(indent=4)
 Lines 1243-1271    Link Here 
1243
#
1302
#
1244
# ------------------------------------------------------------------------------
1303
# ------------------------------------------------------------------------------
1245
1304
1305
	def _logstamp(self,fname):
1306
		""" Logfile timestamp. Now a seperate function.
1307
		"""
1308
		try:
1309
			st = stat(fname)
1310
			if st:
1311
				MODULE.info("   >> log file stamp = '%s'" % st[9])
1312
				return st[9]
1313
			return 0
1314
		except:
1315
			return 0
1316
		
1246
	def _logview(self,fname,count):
1317
	def _logview(self,fname,count):
1247
		"""Contains all functions needed to view or 'tail' an arbitrary text file.
1318
		""" Contains all functions needed to view or 'tail' an arbitrary text file.
1248
		Argument 'count' can have different values:
1319
			Argument 'count' can have different values:
1249
		< 0 ... return Unix timestamp of log file, to avoid fetching unchanged file.
1320
			< 0 ... ignore this many lines, return the rest of the file
1250
		0 ..... return the whole file, splitted into lines.
1321
			0 ..... return the whole file, splitted into lines.
1251
		> 0 ... return the last 'count' lines of the file. (a.k.a. tail -n <count>)"""
1322
			> 0 ... return the last 'count' lines of the file. (a.k.a. tail -n <count>)
1323
		"""
1252
		lines = []
1324
		lines = []
1253
		if count < 0:
1254
			try:
1255
				st = stat(fname)
1256
				if st:
1257
					MODULE.info("   >> log file stamp = '%s'" % st[9])
1258
					return st[9]
1259
				return 0
1260
			except:
1261
				return 0
1262
		try:
1325
		try:
1263
			file = open(fname,'r')
1326
			file = open(fname,'r')
1264
			for line in file:
1327
			for line in file:
1265
				l = line.rstrip()
1328
				if (count < 0):
1266
				lines.append(l)
1329
					count += 1
1267
				if (count) and (len(lines) > count):
1330
				else:
1268
					lines.pop(0)
1331
					l = line.rstrip()
1332
					lines.append(l)
1333
					if (count > 0) and (len(lines) > count):
1334
						lines.pop(0)
1269
		finally:
1335
		finally:
1270
			if file != None:
1336
			if file != None:
1271
				file.close()
1337
				file.close()
 Lines 1289-1294    Link Here 
1289
		script = '''
1355
		script = '''
1290
#:started: %s
1356
#:started: %s
1291
#:detail: %s
1357
#:detail: %s
1358
#:command: %s
1292
dpkg-statoverride --add root root 0644 /usr/sbin/univention-management-console-web-server
1359
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
1360
dpkg-statoverride --add root root 0644 /usr/sbin/univention-management-console-server
1294
dpkg-statoverride --add root root 0644 /usr/sbin/apache2
1361
dpkg-statoverride --add root root 0644 /usr/sbin/apache2
 Lines 1301-1307    Link Here 
1301
dpkg-statoverride --remove /usr/sbin/univention-management-console-server
1368
dpkg-statoverride --remove /usr/sbin/univention-management-console-server
1302
dpkg-statoverride --remove /usr/sbin/apache2
1369
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
1370
chmod +x /usr/sbin/univention-management-console-server /usr/sbin/univention-management-console-web-server /usr/sbin/apache2
1304
''' % (started,detail,command)
1371
''' % (started,detail,command,command)
1305
		p1 = subprocess.Popen( [ 'LC_ALL=C at now', ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True )
1372
		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 )
1373
		(stdout,stderr) = p1.communicate( script )
1307
		
1374
		
 Lines 1330-1336    Link Here 
1330
						cmd = INSTALLERS[inst]['command'].split('%')[0]
1397
						cmd = INSTALLERS[inst]['command'].split('%')[0]
1331
						MODULE.info("   ++ Checking for '%s'" % cmd)
1398
						MODULE.info("   ++ Checking for '%s'" % cmd)
1332
						if cmd in atout:
1399
						if cmd in atout:
1333
							self._current_job = {}
1400
# cleaning up is done in 'run_installer()'
1401
#							self._current_job = {}
1334
							self._current_job['job'] = inst				# job key
1402
							self._current_job['job'] = inst				# job key
1335
							self._current_job['running'] = True			# currently running: we have found it per 'at' job
1403
							self._current_job['running'] = True			# currently running: we have found it per 'at' job
1336
							self._current_job['time'] = int(time())		# record the last time we've seen this job
1404
							self._current_job['time'] = int(time())		# record the last time we've seen this job
(-)umc/js/online.js (-3 / +17 lines)
 Lines 93-106    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);
100
			this.showChild(this._settings);
99
			this.showChild(this._settings);
100
			
101
			// Revert to the 'Updates' page if the installer action encountered
102
			// the 'reboot' affordance.
103
			if (! tab)
104
			{
105
				tab = this._updates;
106
			}
101
			this.selectChild(tab);
107
			this.selectChild(tab);
102
		}));
108
		}));
103
		
109
		
110
		// waits for the Progress Page to notify us that a job is finished. This
111
		// should immediately refresh the 'Updates' and 'Components' pages.
112
		dojo.connect(this._progress,'jobFinished',dojo.hitch(this, function() {
113
			this._updates.refreshPage(true);
114
			this._components.refreshPage();
115
		}));
116
		
104
		// waits for the Progress Page to notify us that a job is running
117
		// waits for the Progress Page to notify us that a job is running
105
		dojo.connect(this._progress,'jobStarted',dojo.hitch(this, function() {
118
		dojo.connect(this._progress,'jobStarted',dojo.hitch(this, function() {
106
			this._switch_to_progress_page();
119
			this._switch_to_progress_page();
 Lines 210-215    Link Here 
210
		
223
		
211
		this.hideChild(this._details);
224
		this.hideChild(this._details);
212
		this.hideChild(this._progress);
225
		this.hideChild(this._progress);
226
		
213
	},
227
	},
214
	
228
	
215
	// Seperate function that can be called the same way as _call_installer:
229
	// Seperate function that can be called the same way as _call_installer:
 Lines 238-244    Link Here 
238
					{
252
					{
239
						txt += "<tr>\n";
253
						txt += "<tr>\n";
240
						txt += "<td style='padding-left:1em;'>" + upd[i][0] + "</td>\n";
254
						txt += "<td style='padding-left:1em;'>" + upd[i][0] + "</td>\n";
241
						txt += "<td style='padding-left:1em;'>" + upd[i][1] + "</td>\n";
255
						txt += "<td style='padding-left:1em;padding-right:.5em;'>" + upd[i][1] + "</td>\n";
242
						txt += "</tr>\n";
256
						txt += "</tr>\n";
243
					}
257
					}
244
				}
258
				}
 Lines 249-255    Link Here 
249
					{
263
					{
250
						txt += "<tr>\n";
264
						txt += "<tr>\n";
251
						txt += "<td style='padding-left:1em;'>" + ins[i][0] + "</td>\n";
265
						txt += "<td style='padding-left:1em;'>" + ins[i][0] + "</td>\n";
252
						txt += "<td style='padding-left:1em;'>" + ins[i][1] + "</td>\n";
266
						txt += "<td style='padding-left:1em;padding-right:.5em;'>" + ins[i][1] + "</td>\n";
253
						txt += "</tr>\n";
267
						txt += "</tr>\n";
254
					}
268
					}
255
				}
269
				}
(-)umc/js/_online/ProgressPage.js (-8 / +71 lines)
 Lines 75-80    Link Here 
75
    		region:		'bottom',
75
    		region:		'bottom',
76
    		onClick:	dojo.hitch(this, function() {
76
    		onClick:	dojo.hitch(this, function() {
77
    			var tab = '';
77
    			var tab = '';
78
    			// Especially for the 'install a component' functionality: if we encounter
79
    			// that the 'reboot required' flag has been set we don't want to switch
80
    			// back to the 'Components' grid but rather to the 'Updates' page. We will
81
    			// request this by unsetting the _last_tab property, so the switching
82
    			// logic will revert to the first tab of our tab set.
83
    			if (this._reboot_required)
84
    			{
85
    				//alert("Resetting return tab to 'Updates'");
86
    				this.last_tab = null;
87
    			}
78
    			if (this.last_tab)
88
    			if (this.last_tab)
79
    			{
89
    			{
80
    				tab = this.last_tab;
90
    				tab = this.last_tab;
 Lines 152-164    Link Here 
152
				
162
				
153
				msg += this._statusfile_data(data.result);
163
				msg += this._statusfile_data(data.result);
154
				
164
				
165
				// -------------- DEBUG ------------------
166
//				for (var v in this._last_job)
167
//				{
168
//					msg += ("<br/>&nbsp;&nbsp;&nbsp;" + v + "&nbsp;=&nbsp;'" + this._last_job[v] + "'");
169
//				}
170
				// ---------------------------------------
171
				
155
				this._head.set('content',msg);
172
				this._head.set('content',msg);
156
				this._pane.layout();
157
				
173
				
158
				if (! data.result['running'])
174
				if (! data.result['running'])
159
				{
175
				{
160
					this._allow_close(true);		// does the rest.
176
					this._allow_close(true);		// does the rest.
161
				}
177
				}
178
179
				this._pane.layout();
162
			}
180
			}
163
		}
181
		}
164
182
 Lines 178-184    Link Here 
178
	
196
	
179
	// takes a status structure as returned from the 'online/installer/status' call,
197
	// 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
198
	// extracts the fields that came directly from the status file (if any) and
181
	// formats them in a readable HTML fashion.
199
	// formats them into a one-liner. Returns an empty string if nothing matches.
200
	//
201
	// FOR TEST: now includes the 'reboot' flag if it is present.
182
	_statusfile_data: function(data) {
202
	_statusfile_data: function(data) {
183
		
203
		
184
		var txt = '';
204
		var txt = '';
 Lines 193-198    Link Here 
193
			}
213
			}
194
		}
214
		}
195
		
215
		
216
		if (data['reboot'])
217
		{
218
			txt += ' [REBOOT] ';
219
			if (! this._reboot_required)		// not set or not true
220
			{
221
				//alert("Setting REBOOT from _statusfile_data");
222
				this._reboot_required = true;
223
			}
224
		}
225
		
196
		if (txt != '')
226
		if (txt != '')
197
		{
227
		{
198
			txt = "(" + this._("Current status file content") + ":" + txt + ")<br/>";
228
			txt = "(" + this._("Current status file content") + ":" + txt + ")<br/>";
 Lines 243-248    Link Here 
243
		{
273
		{
244
			if ((this._job_key != '') && (this._last_job))
274
			if ((this._job_key != '') && (this._last_job))
245
			{
275
			{
276
				// First thing to do: notify the Module that the job is finished. So it can already
277
				// refresh the 'Updates' and 'Components' pages before the user gets back there.
278
				this.jobFinished();
279
				
246
				// FIXME Manually making empty lines before and after this text; should better be done
280
				// FIXME Manually making empty lines before and after this text; should better be done
247
				//		by a style or a style class.
281
				//		by a style or a style class.
248
				var msg = "&nbsp;<br/>";
282
				var msg = "&nbsp;<br/>";
 Lines 256-273    Link Here 
256
				
290
				
257
				msg += this._statusfile_data(this._last_job);
291
				msg += this._statusfile_data(this._last_job);
258
				
292
				
293
				// -------------- DEBUG ------------------
294
//				for (var v in this._last_job)
295
//				{
296
//					msg += ("<br/>&nbsp;&nbsp;&nbsp;" + v + "&nbsp;=&nbsp;'" + this._last_job[v] + "'");
297
//				}
298
				// ---------------------------------------
299
				
259
				this._head.set('content',msg);
300
				this._head.set('content',msg);
260
				
301
				
261
				// for the last time: scroll log view to bottom and stop polling timer.
302
				this._log.stopWatching();		// now log is freely scrollable manually
262
				this._log.scrollToBottom();
263
				this._log.stopWatching();
264
				
303
				
265
				//alert("Watching is finished, job is '" + this._job_key + "'");
304
				//alert("Watching is finished, job is '" + this._job_key + "'");
266
				
305
				
306
				if ((this._last_job) && (this._last_job['reboot']))
307
				{
308
					var reb = this._last_job['reboot'];
309
					if (typeof(reb) == 'string')
310
					{
311
						reb = (reb == 'true');
312
					}
313
					if ((! this._reboot_required) || (reb != this._reboot_required))
314
					{
315
						//alert("setting REBOOT from _allow_close()");
316
						this._reboot_required = reb;
317
					}
318
				}
319
				
267
				this._last_job = null;	// can be deleted, but this._job_key should be retained!
320
				this._last_job = null;	// can be deleted, but this._job_key should be retained!
268
			}
321
			}
269
		}
322
		}
270
		this._pane.layout();
271
	},
323
	},
272
	
324
	
273
	// gives a means to restart polling after reauthentication
325
	// gives a means to restart polling after reauthentication
 Lines 281-289    Link Here 
281
	jobStarted: function() {
333
	jobStarted: function() {
282
	},
334
	},
283
	
335
	
336
	// This function will be called when the already opened ProgressPage encounters
337
	// the end of the current job. The online Module listens here and will refresh
338
	// the 'Updates' and 'Components' pages.
339
	jobFinished: function() {
340
	},
341
	
284
	// online Module calls this when the ProgressPage is to be opened.
342
	// online Module calls this when the ProgressPage is to be opened.
285
	startWatching: function(args) {
343
	startWatching: function(args) {
286
		//alert("ProgressPage::startWatching()");
344
		
345
		// ensure a clean look (and not some stale text from last job)
346
		this._head.set('content',this._("... loading job data ..."));
347
287
		dojo.mixin(this,args);						// as simple as possible.
348
		dojo.mixin(this,args);						// as simple as possible.
288
		this._allow_close(false);					// forbid closing this tab.
349
		this._allow_close(false);					// forbid closing this tab.
289
		this._log.startWatching(this._interval);	// start logfile tail
350
		this._log.startWatching(this._interval);	// start logfile tail
 Lines 291-300    Link Here 
291
	
352
	
292
	// online Module listens to this event to close the page
353
	// online Module listens to this event to close the page
293
	// and reopen the named tab.
354
	// and reopen the named tab.
355
	//
356
	// This is a good place to reset the log viewer contents too.
294
	stopWatching: function(tab) {
357
	stopWatching: function(tab) {
295
		this._job_key = '';
358
		this._job_key = '';
296
		this._last_job = null;
359
		this._last_job = null;
297
		this._log.stopWatching();
360
		this._log.stopWatching(true);
298
	},
361
	},
299
	
362
	
300
	// lets the timer loop stop when the module is closed.
363
	// lets the timer loop stop when the module is closed.
(-)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 (-3 / +10 lines)
 Lines 186-196    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 ..."));
192
		
194
		this._first_call = 3;
193
		this._first_call = 3;
195
		this._last_stamp = 0;
194
		this._last_stamp = 0;
196
		
195
		
 Lines 207-214    Link Here 
207
	
206
	
208
	// effectively stops the polling timer. Can be called from outside (if ProgressPage is being closed)
207
	// effectively stops the polling timer. Can be called from outside (if ProgressPage is being closed)
209
	// or from inside (as 'uninitialize' handler)
208
	// or from inside (as 'uninitialize' handler)
210
	stopWatching: function() {
209
	//
210
	// Argument 'clean' = TRUE -> also clean up display buffer contents.
211
	stopWatching: function(clean) {
212
211
		this._check_interval = 0;
213
		this._check_interval = 0;
214
		
215
		if ((typeof(clean) != 'undefined') && (clean))
216
		{
217
			this.set('content',this._("... loading log file ..."));
218
		}
212
	},
219
	},
213
	
220
	
214
	uninitialize: function() {
221
	uninitialize: function() {

Return to bug 22898