View | Details | Raw Unified | Return to bug 43389
Collapse All | Expand All

(-)a/ucs-school-umc-exam/share/exam-and-room-cleanup (-20 / +12 lines)
Lines 33-49 import os Link Here
33
import grp
33
import grp
34
import shutil
34
import shutil
35
import traceback
35
import traceback
36
import httplib
37
import optparse
36
import optparse
38
import univention.debug as ud
37
import univention.debug as ud
39
import univention.config_registry
38
import univention.config_registry
40
import univention.uldap
39
import univention.uldap
41
import univention.admin.uldap
40
import univention.admin.uldap
42
from ucsschool.lib.schoolldap import SchoolSearchBase
41
from ucsschool.lib.schoolldap import SchoolSearchBase
43
from univention.lib.umc_connection import UMCConnection
42
from univention.lib.umc import Client, ConnectionError, HTTPError
44
from univention.admin.uexceptions import noObject
43
from univention.admin.uexceptions import noObject
45
from ldap.filter import escape_filter_chars
44
from ldap.filter import escape_filter_chars
46
from socket import error as SocketError
47
from ldap import LDAPError
45
from ldap import LDAPError
48
46
49
47
Lines 73-100 class ExamCleanupHelper(object): Link Here
73
71
74
	def get_UMCP_connection(self):
72
	def get_UMCP_connection(self):
75
		ud.debug(ud.MAIN, ud.INFO, 'Opening UMCP connection to %s with machine account' % (self.hostname,))
73
		ud.debug(ud.MAIN, ud.INFO, 'Opening UMCP connection to %s with machine account' % (self.hostname,))
76
		con = UMCConnection(self.hostname)
77
		username = '%s$' % self.hostname
78
		try:
74
		try:
79
			with open('/etc/machine.secret') as machine_file:
75
			client = Client(self.hostname)
80
				password = machine_file.readline().strip()
76
			client.authenticate_with_machine_account()
81
			con.auth(username, password)
77
		except (ConnectionError, HTTPError) as exc:
82
		except (OSError, IOError) as exc:
83
			ud.debug(ud.MAIN, ud.ERROR, 'Could not read /etc/machine.secret: %s' % exc)
84
			sys.exit(1)
85
		except (httplib.HTTPException, SocketError) as exc:
86
			ud.debug(ud.MAIN, ud.ERROR, 'Could not connect to UMC on %s: %s' % (self.hostname, exc))
78
			ud.debug(ud.MAIN, ud.ERROR, 'Could not connect to UMC on %s: %s' % (self.hostname, exc))
87
			sys.exit(1)
79
			sys.exit(1)
88
		return con
80
		return client
89
81
90
	def running_exam_iter(self):
82
	def running_exam_iter(self):
91
		ou_list = self.lo.search(filter='(objectClass=ucsschoolOrganizationalUnit)')
83
		ou_list = self.lo.search(filter='(objectClass=ucsschoolOrganizationalUnit)')
92
		for ou_dn, ou_attrs in ou_list:
84
		for ou_dn, ou_attrs in ou_list:
93
			ou_name = ou_attrs.get('ou')[0]
85
			ou_name = ou_attrs.get('ou')[0]
94
			try:
86
			try:
95
				room_list = self.umcp.request('computerroom/rooms', {'school': ou_name})
87
				room_list = self.umcp.umc_command('computerroom/rooms', {'school': ou_name}).result
96
			except httplib.HTTPException, ex:
88
			except (ConnectionError, HTTPError) as exc:
97
				ud.debug(ud.MAIN, ud.ERROR, 'Cannot get room list for OU %r:\n%s' % (ou_name, ex))
89
				ud.debug(ud.MAIN, ud.ERROR, 'Cannot get room list for OU %r:\n%s' % (ou_name, exc))
98
				continue
90
				continue
99
			for room in room_list:
91
			for room in room_list:
100
				ud.debug(ud.MAIN, ud.INFO, '%s: %r' % (ou_name, room))
92
				ud.debug(ud.MAIN, ud.INFO, '%s: %r' % (ou_name, room))
Lines 115-128 class ExamCleanupHelper(object): Link Here
115
				continue
107
				continue
116
108
117
			try:
109
			try:
118
				result = self.umcp.request(
110
				result = self.umcp.umc_command(
119
					'schoolexam/exam/finish',
111
					'schoolexam/exam/finish',
120
					{'exam': room.get('exam'), 'room': room.get('id')})
112
					{'exam': room.get('exam'), 'room': room.get('id')}).result
121
				ud.debug(ud.MAIN, ud.INFO, 'result of schoolexam/exam/finish: %r' % (result,))
113
				ud.debug(ud.MAIN, ud.INFO, 'result of schoolexam/exam/finish: %r' % (result,))
122
			except httplib.HTTPException, ex:
114
			except (ConnectionError, HTTPError) as exc:
123
				ud.debug(
115
				ud.debug(
124
					ud.MAIN, ud.ERROR,
116
					ud.MAIN, ud.ERROR,
125
					'Cannot stop exam %r in room %r:\n%s' % (room.get('exam'), room.get('id'), ex))
117
					'Cannot stop exam %r in room %r:\n%s' % (room.get('exam'), room.get('id'), exc))
126
				continue
118
				continue
127
119
128
	def remove_exam_user(self):
120
	def remove_exam_user(self):
(-)a/ucs-school-umc-exam/umc/python/schoolexam/__init__.py (-25 / +32 lines)
Lines 52-58 Link Here
52
from univention.management.console.modules.schoolexam import util
52
from univention.management.console.modules.schoolexam import util
53
53
54
from univention.lib.i18n import Translation
54
from univention.lib.i18n import Translation
55
from univention.lib.umc_connection import UMCConnection
55
from univention.lib.umc import Client, ConnectionError, HTTPError
56
56
57
from ucsschool.lib.schoolldap import LDAP_Connection, SchoolBaseModule, SchoolSearchBase, SchoolSanitizer
57
from ucsschool.lib.schoolldap import LDAP_Connection, SchoolBaseModule, SchoolSearchBase, SchoolSanitizer
58
from ucsschool.lib import internetrules
58
from ucsschool.lib import internetrules
Lines 215-231 def _thread(): Link Here
215
						os.chown(itarget, 0, 0)
215
						os.chown(itarget, 0, 0)
216
216
217
			# open a new connection to the master UMC
217
			# open a new connection to the master UMC
218
			connection = UMCConnection.get_machine_connection()
218
			try:
219
			if not connection:
219
				master = ucr['ldap/master']
220
				MODULE.error('Could not connect to UMC on %s' % (ucr.get('ldap/master')))
220
				client = Client(master)
221
				client.authenticate_with_machine_account()
222
			except (ConnectionError, HTTPError) as exc:
223
				MODULE.error('Could not connect to UMC on %s: %s' % (master, exc))
221
				raise UMC_Error(_('Could not connect to master server %s.') % ucr.get('ldap/master'))
224
				raise UMC_Error(_('Could not connect to master server %s.') % ucr.get('ldap/master'))
222
225
223
			# mark the computer room for exam mode
226
			# mark the computer room for exam mode
224
			progress.component(_('Preparing the computer room for exam mode...'))
227
			progress.component(_('Preparing the computer room for exam mode...'))
225
			connection.request('schoolexam-master/set-computerroom-exammode', dict(
228
			client.umc_command('schoolexam-master/set-computerroom-exammode', dict(
226
				school=request.options['school'],
229
				school=request.options['school'],
227
				roomdn=request.options['room'],
230
				roomdn=request.options['room'],
228
			))
231
			)).result  # FIXME: no error handling
229
			progress.add_steps(5)
232
			progress.add_steps(5)
230
233
231
			# read all recipients and fetch all user objects
234
			# read all recipients and fetch all user objects
Lines 254-266 def _thread(): Link Here
254
			for iuser in users:
257
			for iuser in users:
255
				progress.info('%s, %s (%s)' % (iuser.lastname, iuser.firstname, iuser.username))
258
				progress.info('%s, %s (%s)' % (iuser.lastname, iuser.firstname, iuser.username))
256
				try:
259
				try:
257
					ires = connection.request('schoolexam-master/create-exam-user', dict(
260
					ires = client.umc_command('schoolexam-master/create-exam-user', dict(
258
						school=request.options['school'],
261
						school=request.options['school'],
259
						userdn=iuser.dn
262
						userdn=iuser.dn
260
					))
263
					)).result
261
					examUsers.add(ires.get('examuserdn'))
264
					examUsers.add(ires.get('examuserdn'))
262
					MODULE.info('Exam user has been created: %s' % ires.get('examuserdn'))
265
					MODULE.info('Exam user has been created: %s' % ires.get('examuserdn'))
263
				except (HTTPException, SocketError) as exc:
266
				except (ConnectionError, HTTPError) as exc:
264
					MODULE.warn('Could not create exam user account for %r: %s' % (iuser.dn, exc))
267
					MODULE.warn('Could not create exam user account for %r: %s' % (iuser.dn, exc))
265
268
266
				# indicate the the user has been processed
269
				# indicate the the user has been processed
Lines 332-362 def _thread(): Link Here
332
			#   second step: adjust room settings
335
			#   second step: adjust room settings
333
			progress.component(_('Prepare room settings'))
336
			progress.component(_('Prepare room settings'))
334
			try:
337
			try:
335
				userConnection = UMCConnection('localhost', username=self.username, password=self.password)
338
				user_client = Client(None, self.username, self.password)
336
			except (HTTPException, SocketError) as exc:
339
			except (ConnectionError, HTTPError) as exc:
340
				MODULE.warn('Authentication failed: %s' % (exc,))
337
				raise UMC_Error(_('Could not connect to local UMC server.'))
341
				raise UMC_Error(_('Could not connect to local UMC server.'))
338
342
339
			room = request.options['room']
343
			room = request.options['room']
340
			MODULE.info('Acquire room: %s' % (room,))
344
			MODULE.info('Acquire room: %s' % (room,))
341
			userConnection.request('computerroom/room/acquire', dict(
345
			user_client.umc_command('computerroom/room/acquire', dict(
342
				room=request.options['room'],
346
				room=request.options['room'],
343
			))
347
			)).result
344
			progress.add_steps(1)
348
			progress.add_steps(1)
345
			MODULE.info('Adjust room settings:\n%s' % '\n'.join(['  %s=%s' % (k, v) for k, v in request.options.iteritems()]))
349
			MODULE.info('Adjust room settings:\n%s' % '\n'.join(['  %s=%s' % (k, v) for k, v in request.options.iteritems()]))
346
			userConnection.request('computerroom/exam/start', dict(
350
			user_client.umc_command('computerroom/exam/start', dict(
347
				room=room,
351
				room=room,
348
				examDescription=request.options['name'],
352
				examDescription=request.options['name'],
349
				exam=directory,
353
				exam=directory,
350
				examEndTime=request.options.get('examEndTime'),
354
				examEndTime=request.options.get('examEndTime'),
351
			))
355
			)).result
352
			progress.add_steps(4)
356
			progress.add_steps(4)
353
			userConnection.request('computerroom/settings/set', dict(
357
			user_client.umc_command('computerroom/settings/set', dict(
354
				room=room,
358
				room=room,
355
				internetRule=request.options['internetRule'],
359
				internetRule=request.options['internetRule'],
356
				customRule=request.options.get('customRule'),
360
				customRule=request.options.get('customRule'),
357
				shareMode=request.options['shareMode'],
361
				shareMode=request.options['shareMode'],
358
				printMode='default',
362
				printMode='default',
359
			))
363
			)).result
360
			progress.add_steps(5)
364
			progress.add_steps(5)
361
365
362
		def _finished(thread, result, request):
366
		def _finished(thread, result, request):
Lines 441-459 def _thread(): Link Here
441
			progress.add_steps(10)
445
			progress.add_steps(10)
442
446
443
			# open a new connection to the master UMC
447
			# open a new connection to the master UMC
444
			connection = UMCConnection.get_machine_connection()
448
			master = ucr['ldap/master']
445
			if not connection:
449
			try:
446
				MODULE.error('Could not connect to UMC on %s' % (ucr.get('ldap/master')))
450
				client = Client(master)
447
				raise UMC_Error(_('Could not connect to master server %s.') % ucr.get('ldap/master'))
451
				client.authenticate_with_machine_account()
452
			except (ConnectionError, HTTPError) as exc:
453
				MODULE.error('Could not connect to UMC on %s: %s' % (master, exc))
454
				raise UMC_Error(_('Could not connect to master server %s.') % (master,))
448
455
449
			school = SchoolSearchBase.getOU(request.options['room'])
456
			school = SchoolSearchBase.getOU(request.options['room'])
450
457
451
			# unset exam mode for the given computer room
458
			# unset exam mode for the given computer room
452
			progress.component(_('Configuring the computer room...'))
459
			progress.component(_('Configuring the computer room...'))
453
			connection.request('schoolexam-master/unset-computerroom-exammode', dict(
460
			client.umc_command('schoolexam-master/unset-computerroom-exammode', dict(
454
				roomdn=request.options['room'],
461
				roomdn=request.options['room'],
455
				school=school,
462
				school=school,
456
			))
463
			)).result
457
			progress.add_steps(5)
464
			progress.add_steps(5)
458
465
459
			# delete exam users accounts
466
			# delete exam users accounts
Lines 476-485 def _thread(): Link Here
476
							shutil.rmtree(iuser.unixhome, ignore_errors=True)
483
							shutil.rmtree(iuser.unixhome, ignore_errors=True)
477
484
478
							# remove LDAP user entry
485
							# remove LDAP user entry
479
							connection.request('schoolexam-master/remove-exam-user', dict(
486
							client.umc_command('schoolexam-master/remove-exam-user', dict(
480
								userdn=iuser.dn,
487
								userdn=iuser.dn,
481
								school=school,
488
								school=school,
482
							))
489
							)).result
483
							MODULE.info('Exam user has been removed: %s' % iuser.dn)
490
							MODULE.info('Exam user has been removed: %s' % iuser.dn)
484
						else:
491
						else:
485
							MODULE.process('Cannot remove the user account %s as it is registered for the running exam "%s", as well' % (iuser.dn, parallelUsers[iuser.username]))
492
							MODULE.process('Cannot remove the user account %s as it is registered for the running exam "%s", as well' % (iuser.dn, parallelUsers[iuser.username]))
(-)a/ucs-school-umc-installer/umc/python/schoolinstaller/__init__.py (-12 / +10 lines)
Lines 44-50 Link Here
44
import fcntl
44
import fcntl
45
import select
45
import select
46
import errno
46
import errno
47
from httplib import HTTPException
48
47
49
import notifier
48
import notifier
50
import notifier.threads
49
import notifier.threads
Lines 53-59 Link Here
53
import ldap
52
import ldap
54
53
55
from univention.lib.package_manager import PackageManager
54
from univention.lib.package_manager import PackageManager
56
from univention.lib.umc_connection import UMCConnection
55
from univention.lib.umc import Client, ConnectionError, HTTPError, Forbidden
57
from univention.admin.uexceptions import noObject
56
from univention.admin.uexceptions import noObject
58
from univention.management.console.base import Base, UMC_Error
57
from univention.management.console.base import Base, UMC_Error
59
from univention.management.console.log import MODULE
58
from univention.management.console.log import MODULE
Lines 135-144 def get_master_dns_lookup(): Link Here
135
	return ''
134
	return ''
136
135
137
136
138
def umc(username, password, master, path='', options=None, flavor=None, command='command'):
137
def umc(username, password, master, path, options=None, flavor=None):
139
	connection = UMCConnection(master, username, password, error_handler=MODULE.warn)
138
	MODULE.info('Executing on %r: %r %r flavor=%r options=%r' % (master, path, flavor, options))
140
	MODULE.info('Executing on %r: %r %r flavor=%r options=%r' % (master, command, path, flavor, options))
139
	client = Client(master, username, password)
141
	return connection.request(path or '', options, flavor, command=command)
140
	return client.umc_command(path, options, flavor)
142
141
143
142
144
def create_ou_local(ou, display_name):
143
def create_ou_local(ou, display_name):
Lines 165-171 def create_ou_remote(master, username, password, ou, display_name, educational_s Link Here
165
		options['dc_name_administrative'] = administrative_slave
164
		options['dc_name_administrative'] = administrative_slave
166
	try:
165
	try:
167
		umc(username, password, master, 'schoolwizards/schools/create', [{'object': options}], 'schoolwizards/schools')
166
		umc(username, password, master, 'schoolwizards/schools/create', [{'object': options}], 'schoolwizards/schools')
168
	except (EnvironmentError, HTTPException) as exc:
167
	except (ConnectionError, HTTPError) as exc:
169
		raise SchoolInstallerError('Failed creating OU: %s' % (exc,))
168
		raise SchoolInstallerError('Failed creating OU: %s' % (exc,))
170
169
171
170
Lines 457-467 def get_metainfo_master(self): Link Here
457
456
458
	def _umc_master(self, username, password, master, uri, data=None):
457
	def _umc_master(self, username, password, master, uri, data=None):
459
		try:
458
		try:
460
			try:
459
			return umc(username, password, master, uri, data)
461
				return umc(username, password, master, uri, data)
460
		except Forbidden:
462
			except NotImplementedError:
461
			raise SchoolInstallerError(_('Make sure ucs-school-umc-installer is installed on the DC Master and all join scripts are executed.'))
463
				raise HTTPException(_('Make sure ucs-school-umc-installer is installed on the DC Master and all join scripts are executed.'))
462
		except (ConnectionError, HTTPError) as exc:
464
		except (EnvironmentError, HTTPException) as exc:
465
			raise SchoolInstallerError(_('Could not connect to the DC Master %s: %s') % (master, exc))  # TODO: set status, message, result
463
			raise SchoolInstallerError(_('Could not connect to the DC Master %s: %s') % (master, exc))  # TODO: set status, message, result
466
464
467
	@sanitize(
465
	@sanitize(

Return to bug 43389