Bug 48245 - UCS@school role attribute: 'SchoolDCSlave' object does not support item assignment
UCS@school role attribute: 'SchoolDCSlave' object does not support item assig...
Product: UCS@school
Classification: Unclassified
Component: Import scripts
UCS@school 4.3
Other Linux
: P5 normal (vote)
: UCS@school 4.3 v6-errata
Assigned To: Ole Schwiegert
Jürn Brodersen
Depends on:
Blocks: 48226
  Show dependency treegraph
Reported: 2018-11-30 12:17 CET by Valentin Heidelberger
Modified: 2018-12-12 17:24 CET (History)
6 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 5: Major Usability: Impairs usability in key scenarios
Who will be affected by this bug?: 2: Will only affect a few installed domains
How will those affected feel about the bug?: 4: A User would return the product
User Pain: 0.229
Enterprise Customer affected?:
School Customer affected?: Yes
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Note You need to log in before you can comment on or make changes to this bug.
Description Valentin Heidelberger univentionstaff 2018-11-30 12:17:29 CET
With UCS@school 4.3 v4 a role attribute for all UCS@school objects was added. To use this a UCR variable must be activated: ucsschool/feature/roles=yes

If this feature is activated and one tries to create a school with a school server, that already exists as a computer object, in a multi server environment the UMC throws a traceback. Despite of the error and the wizard not closing, the school is still silently created but without a school server, even though this is a required field.

The error does not appear, if the school server, does not have a computer object by the same name.

To reproduce:
- UCS@school multi server environment installed
- Join UCS slave to the domain
- ucr set ucsschool/feature/roles=yes
- Create new school via UMC "Schulen" module
- Specify name of slave as school server

Interner Server-Fehler in "schoolwizards/schools/add (schoolwizards/schools)".
Request: schoolwizards/schools/add (schoolwizards/schools)

Traceback (most recent call last):
  File "/usr/lib/pymodules/python2.7/univention/management/console/base.py", line 253, in execute
    function.__func__(self, request, *args, **kwargs)
  File "/usr/lib/pymodules/python2.7/univention/management/console/modules/schoolwizards/__init__.py", line 122, in _decorated
    ret = func(self, request, *a, **kw)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/schoolldap.py", line 145, in wrapper_func
    return func(*args, **kwargs)
  File "/usr/lib/pymodules/python2.7/univention/management/console/modules/schoolwizards/__init__.py", line 208, in _create_obj
    if obj.create(ldap_user_write, validate=False):
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 458, in create
    success = self.create_without_hooks(lo, validate)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/school.py", line 435, in create_without_hooks
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/school.py", line 326, in add_host_to_dc_group
    dc['ucsschool_roles'] = [create_ucsschool_role_string(role_dc_slave_edu, self.name)]
TypeError: 'SchoolDCSlave' object does not support item assignment
Comment 1 Valentin Heidelberger univentionstaff 2018-11-30 12:26:50 CET
The script migrate_ucsschool_roles that was introduced with bug 45379 succeeds in adding the ucsschoolRole attribute to existing school server slaves:

ucsschoolRole: dc_slave_edu_secondary:school:s1

This can be used for a workaround that I tested successfully:
- temporarily unset ucsschool/feature/roles
- create the school with the school server
- set the UCRV to yes again
- use the migration script to add the attribute:
/usr/share/ucs-school-import/scripts/migrate_ucsschool_roles --schools <school OU> --servers-school 

to actually apply the changes:
/usr/share/ucs-school-import/scripts/migrate_ucsschool_roles --schools <school OU> --servers-school --modify
Comment 2 Valentin Heidelberger univentionstaff 2018-11-30 17:10:55 CET
I have a few customers who'll need this feature soon, which is why I increased the user pain.

Also the workaround from the last comment, seemingly requires the user to log out and in again to the UMC. Just setting the variable without that still causes a traceback and wrong school creation in my test env.
Comment 3 Ole Schwiegert univentionstaff 2018-12-11 09:12:41 CET
This problem originates from an undiscovered mistake I made a while ago when creating the new create_ou script:

if ucr.is_true('ucsschool/feature/roles') and dc:
  dc['ucsschool_roles'] = [create_ucsschool_role_string(role_dc_slave_edu,self.name)]

has to be

if ucr.is_true('ucsschool/feature/roles') and dc:
  dc.ucsschool_roles = [create_ucsschool_role_string(role_dc_slave_edu,self.name)]

After fixing this though, a new error occured that I could not figure out on first glance:

KeyError                                  Traceback (most recent call last)
<ipython-input-12-31801ced9006> in <module>()
----> 1 dc.modify(lo)

/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.pyc in modify(self, lo, validate, move_if_necessary)
    515 		'''
    516                 self.call_hooks('pre', 'modify')
--> 517                 success = self.modify_without_hooks(lo, validate, move_if_necessary)
    518                 if success:
    519                         self.call_hooks('post', 'modify')

/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.pyc in modify_without_hooks(self, lo, validate, move_if_necessary)
    538                 try:
    539                         old_attrs = deepcopy(udm_obj.info)
--> 540                         self.modify_without_hooks_roles(udm_obj)
    541                         self.do_modify(udm_obj, lo)
    542                         # get it fresh from the database

/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.pyc in modify_without_hooks_roles(self, udm_obj)
   1081                 if not ucr.is_true('ucsschool/feature/roles'):
   1082                         return
-> 1083                 old_schools = set(self.get_schools_from_udm_obj(udm_obj))
   1084                 cur_schools = self.get_schools()
   1085                 new_schools = set(cur_schools) - old_schools

/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.pyc in get_schools_from_udm_obj(self, udm_obj)
   1007                 else:
   1008                         try:
-> 1009                                 return udm_obj.info['school']
   1010                         except KeyError as exc:
   1011                                 logger.exception('KeyError in RoleSupportMixin.get_schools_from_udm_obj(%r): %s', udm_obj, exc)

KeyError: 'school'

It seems that for the role feature it is somehow required for the DC udm object to posess the school property which is not present yet. The SchoolDCSlave object has the school set, but upon modification it seems to be accessed before it was saved into the underlying udm object.
Comment 4 Daniel Tröder univentionstaff 2018-12-11 15:53:16 CET
You'll have to do the same as was done in groups.py for ComputerRoom:

--- a/ucs-school-lib/python/models/computer.py
+++ b/ucs-school-lib/python/models/computer.py
@@ -80,6 +80,10 @@ class SchoolDCSlave(RoleSupportMixin, SchoolDC):
        groups = Groups(_('Groups'))
        ucsschool_roles = Roles(_('Roles'), aka=['Roles'])
+       def get_schools_from_udm_obj(self, udm_obj):
+               # fixme: no idea how to find out old school
+               return self.school
Comment 5 Ole Schwiegert univentionstaff 2018-12-12 10:16:26 CET
Aye that solved the problem!

Package: ucs-school-lib
Version: 11.0.1-29A~
Branch: ucs_4.3-0
Scope: ucs-school-4.3
Comment 6 Jürn Brodersen univentionstaff 2018-12-12 11:59:28 CET
What I tested:
Created a school with an existing dc object using create_ou:
  No error, role is set -> OK

Comment 7 Sönke Schwardt-Krummrich univentionstaff 2018-12-12 17:24:15 CET
UCS@school 4.3 v6 has been released.


If this error occurs again, please clone this bug.