def partitions_info(self, request): result = {} message = None try: fs = fstab.File() mt = mtab.File() except IOError as error: MODULE.error("Could not open %s" % error.filename) message = _("Could not open %s") % error.filename request.status = MODULE_ERR else: partition = fs.find(spec=request.options["partitionDevice"]) if partition: mounted_partition = mt.get(partition.spec) if mounted_partition: result["mountPoint"] = mounted_partition.mount_point result["filesystem"] = mounted_partition.type result["options"] = mounted_partition.options request.status = SUCCESS else: request.status = MODULE_ERR message = _("This partition is currently not mounted") else: request.status = MODULE_ERR message = _("No partition found") self.finished(request.id, result, message)
def getUserAndMailbox(userdn): co, lo, pos = getCoLoPos() server = univention.admin.modules.get("asterisk/server") univention.admin.modules.init(lo, pos, server) objs = server.lookup(co, lo, None) checkServers = [] for obj in objs: checkServers.append({ "label": obj["commonName"], }) MODULE.error('User: server: %s' % len(checkServers)) if len(checkServers) >0 : co, lo = getCoLo() user = getUser(co, lo, userdn) mailbox = user.get("mailbox") if mailbox: mailbox = getMailbox(co, lo, mailbox) return user, mailbox elif len(checkServers) == 0 : MODULE.error('Fehler gefunden!') mailbox = "KeinServer" user = "******" return user, mailbox
def partitions_query(self, request): result = [] message = None try: fs = fstab.File() mt = mtab.File() except IOError as error: MODULE.error("Could not open %s" % error.filename) message = _("Could not open %s") % error.filename request.status = MODULE_ERR else: partitions = fs.get(["xfs", "ext3", "ext2"], False) # TODO: ext4? for partition in partitions: list_entry = {} list_entry["partitionDevice"] = partition.spec list_entry["mountPoint"] = partition.mount_point list_entry["partitionSize"] = None list_entry["freeSpace"] = None list_entry["inUse"] = None mounted_partition = mt.get(partition.spec) if mounted_partition: partition_info = df.DeviceInfo(partition.mount_point) list_entry["partitionSize"] = tools.block2byte(partition_info.size(), "GB", 1) list_entry["freeSpace"] = tools.block2byte(partition_info.free(), "GB", 1) if "usrquota" in mounted_partition.options: list_entry["inUse"] = True else: list_entry["inUse"] = False result.append(list_entry) request.status = SUCCESS self.finished(request.id, result, message)
def get_fqdn(nameserver): # register nameserver resolver = _get_dns_resolver(nameserver) # perform a reverse lookup try: reverse_address = dns.reversename.from_address(nameserver) MODULE.info('Found reverse address: %s' % (reverse_address, )) reverse_lookup = resolver.query(reverse_address, 'PTR') if not len(reverse_lookup): return None fqdn = reverse_lookup[0] parts = [i for i in fqdn.target.labels if i] domain = '.'.join(parts) return domain except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.NoNameservers) as exc: MODULE.warn('Lookup for nameserver %s failed: %s %s' % (nameserver, type(exc).__name__, exc)) except dns.exception.Timeout as exc: MODULE.warn('Lookup for nameserver %s timed out: %s' % (nameserver, exc)) except dns.exception.DNSException as exc: MODULE.error('DNS Exception: %s' % (traceback.format_exc())) return None
def updates_available(self, request): """ Asks if there are package updates available. (don't get confused by the name of the UniventionUpdater function that is called here.) This is a seperate call since it can take an amount of time, thus being invoked by a seperate button (and not in the background) """ # ----------- DEBUG ----------------- MODULE.info("updater/updates/available invoked with:") pp = pprint.PrettyPrinter(indent=4) st = pp.pformat(request.options).split("\n") for s in st: MODULE.info(" << %s" % s) # ----------------------------------- result = False what = "starting" try: # be as current as possible. what = "reinitializing UniventionUpdater" self.uu.ucr_reinit() what = "reloading registry" self.ucr.load() what = "checking update availability" result = self.uu.component_update_available() except Exception, ex: typ = str(type(ex)).strip("<>") msg = "[while %s] [%s] %s" % (what, typ, str(ex)) # result['message'] = msg # result['status'] = 1 MODULE.error(msg)
def request( self, command, **kwargs ): MODULE.info( 'Sending request %s to UVMM daemon ...' % command ) try: request = eval( 'protocol.Request_%s()' % command ) except NameError, AttributeError: MODULE.error( 'Failed to create request %s' % command ) raise UVMM_Error( _( 'The given UVMM command is not known' ) )
def error_handling(self, request, method, etype, exc, etraceback): if self.__handler: self.__handler._Base__requests[request.id] = (request, method) self.__handler._Base__error_handling(request, method, etype, exc, etraceback) return trace = ''.join(traceback.format_exception(etype, exc, etraceback)) MODULE.error('The init function of the module failed\n%s: %s' % ( exc, trace, )) from ..error import UMC_Error if not isinstance(exc, UMC_Error): error = _('The initialization of the module failed: %s') % ( trace, ) exc = UMC_Error(error, status=MODULE_ERR_INIT_FAILED) etype = UMC_Error resp = Response(request) resp.status = exc.status resp.message = str(exc) resp.result = exc.result resp.headers = exc.headers self.response(resp)
def request(self, command, **kwargs): MODULE.info('Sending request %s to UVMM daemon ...' % command) try: request = eval('protocol.Request_%s()' % command) except NameError, AttributeError: MODULE.error('Failed to create request %s' % command) raise UVMM_Error(_('The given UVMM command is not known'))
def _thread(request): message = None success = True result = [] partition = request.options['partitionDevice'] unicode_user = request.options['user'] user = unicode_user.encode('utf-8') size_soft = request.options['sizeLimitSoft'] size_hard = request.options['sizeLimitHard'] file_soft = request.options['fileLimitSoft'] file_hard = request.options['fileLimitHard'] self._check_error(request, partition) failed = tools.setquota(partition, user, tools.byte2block(size_soft), tools.byte2block(size_hard), file_soft, file_hard) if failed: MODULE.error('Failed to modify quota settings for user %s ' 'on partition %s' % (user, partition)) message = _('Failed to modify quota settings for user %s on ' 'partition %s') % (user, partition) request.status = MODULE_ERR self.finished(request.id, None, message) message = _('Successfully set quota settings') return {'result': result, 'message': message, 'success': success}
def _thread(request): message = None success = True result = [] partition = request.options['partitionDevice'] unicode_user = request.options['user'] user = unicode_user.encode('utf-8') size_soft = request.options['sizeLimitSoft'] size_hard = request.options['sizeLimitHard'] file_soft = request.options['fileLimitSoft'] file_hard = request.options['fileLimitHard'] self._check_error(request, partition) failed = tools.setquota(partition, user, tools.byte2block(size_soft), tools.byte2block(size_hard), file_soft, file_hard) if failed: MODULE.error('Failed to modify quota settings for user %s ' 'on partition %s' % (user, partition)) message = _('Failed to modify quota settings for user %s on ' 'partition %s') % (user, partition) request.status = MODULE_ERR self.finished(request.id, None, message) message = _('Successfully set quota settings') return {'result': result, 'message': message, 'success': success}
def startDemoServer(self, allowed_clients=[]): if not self.connected(): MODULE.error('%s: not connected - skipping startDemoServer' % (self.ipAddress, )) return self._core.stopDemoServer() self._core.startDemoServer(ITALC_VNC_PORT, ITALC_DEMO_PORT) self.allowClients(allowed_clients)
def denyClients(self): if not self.connected(): MODULE.error('%s: not connected - skipping denyClients' % (self.ipAddress, )) return for client in self._allowedClients[:]: self._core.demoServerUnallowHost(client.ipAddress) self._allowedClients.remove(client)
def ucr_try_int(variable, default): try: return int(ucr.get(variable, default)) except ValueError: MODULE.error( 'UCR variables %s is not a number, using default: %s' % (variable, default)) return default
def startDemoClient(self, server, fullscreen=True): if not self.connected(): MODULE.error('%s: not connected - skipping startDemoClient' % (self.ipAddress, )) return self._core.stopDemo() self._core.unlockScreen() self._core.unlockInput() self._core.startDemo(server.ipAddress, ITALC_DEMO_PORT, fullscreen)
def allowClients(self, clients): if not self.connected(): MODULE.error('%s: not connected - skipping allowClients' % (self.ipAddress, )) return self.denyClients() for client in clients: self._core.demoServerAllowHost(client.ipAddress) self._allowedClients.append(client)
def load(self): for plugin in self.plugins: try: self.modules[plugin] = Plugin(plugin) except ImportError as exc: MODULE.error('Could not load plugin %r: %r' % (plugin, exc)) raise self.modules = OrderedDict( sorted(self.modules.items(), key=lambda t: t[0]))
def getServer(dn): co, lo, pos = getCoLoPos() server = univention.admin.modules.get("asterisk/server") univention.admin.modules.init(lo, pos, server) obj = server.object(co, lo, None, dn) MODULE.error("server dn: %s" % dn) obj.open() return obj
def powerOn(self): # do not use the italc trick # if self._core and self.macAddress: # self._core.powerOnComputer( self.macAddress ) if self.macAddress: subprocess.Popen(['/usr/bin/wakeonlan', self.macAddress]) else: MODULE.error('%s: no MAC address set - skipping powerOn' % (self.ipAddress, ))
def connect(self): # Create a connection to the pkgdb try: self.dbConnection = updb.open_database_connection(self.ucr, pkgdbu=True) except pgdb.InternalError as ex: MODULE.error('Could not establish connection to the PostgreSQL server: %s' % (ex,)) raise UMC_Error(_('Could not establish connection to the database.\n\n%s') % (_server_not_running_msg(),)) else: self.cursor = self.dbConnection.cursor()
def lockInput(self, value): if not self.connected(): MODULE.error('%s: not connected - skipping lockInput' % (self.ipAddress, )) return if value: self._core.lockInput() else: self._core.unlockInput()
def get(self, request): """get a specific item of self.data""" try: item = self.data[request.options['item']] except IndexError: MODULE.error('A invalid item was accessed.') raise UMC_Error(_('The item %d does not exists.') % (request.options['item'], ), status=400) self.finished(request.id, self.data[item])
def init(self): MODULE.info("Initializing 'updater' module (PID = %d)" % (getpid(), )) self._current_job = '' self._logfile_start_line = 0 self._serial_file = Watched_File(COMPONENTS_SERIAL_FILE) self._updates_serial = Watched_Files(UPDATE_SERIAL_FILES) try: self.uu = UniventionUpdater(False) except Exception as exc: # FIXME: let it raise MODULE.error("init() ERROR: %s" % (exc, ))
def check_domain_is_higher_or_equal_version(address, username, password): with _temporary_password_file(password) as password_file: try: master_ucs_version = subprocess.check_output(['univention-ssh', password_file, '%s@%s' % (username, address), 'echo $(/usr/sbin/ucr get version/version)-$(/usr/sbin/ucr get version/patchlevel)'], stderr=subprocess.STDOUT).rstrip() except subprocess.CalledProcessError: MODULE.error('Failed to retrieve UCS version: %s' % (traceback.format_exc())) return nonmaster_ucs_version = '{}-{}'.format(UCR.get('version/version'), UCR.get('version/patchlevel')) if LooseVersion(nonmaster_ucs_version) > LooseVersion(master_ucs_version): raise UMC_Error(_('The UCS version of the domain you are trying to join ({}) is lower than the local one ({}). This constellation is not supported.').format(master_ucs_version, nonmaster_ucs_version))
def _thread(request, obj): # acquire the lock until the scripts have been executed self._finishedResult = False obj._finishedLock.acquire() try: subfolders = { 'network': ['30_net'], 'certificate': ['40_ssl'], 'languages': ['15_keyboard', '20_language', '35_timezone'], }.get(request.flavor) self._progressParser.reset(subfolders) if request.flavor == 'setup': # adjust progress fractions for setup wizard with pre-configurred settings fractions = self._progressParser.fractions fractions['05_role/10role'] = 0 fractions['10_basis/12domainname'] = 0 fractions['10_basis/14ldap_basis'] = 0 fractions['90_postjoin/10admember'] = 0 self._progressParser.calculateFractions() MODULE.info('saving profile values') util.write_profile(values) if not values: MODULE.error('No property "values" given for save().') return False # in case of changes of the IP address, restart UMC server and web server # for this we ignore changes of virtual or non-default devices # ... no need to restart the UMC server if cleanup scripts are run anyway restart = False if not run_hooks: MODULE.info('Check whether ip addresses have been changed') for ikey, ival in values.iteritems(): if RE_IPV4.match(ikey) or RE_IPV6_DEFAULT.match(ikey) or RE_SSL.match(ikey): restart = True break MODULE.info('Restart servers: %s' % restart) # on a joined system or on a basesystem, we can run the setup scripts MODULE.info('runnning system setup scripts (flavor %r)' % (request.flavor,)) util.run_scripts(self._progressParser, restart, subfolders, lang=str(self.locale), args=script_args) # run cleanup scripts and appliance hooks if needed if run_hooks: util.cleanup(with_appliance_hooks=True) # done :) self._finishedResult = True return True finally: obj._finishedLock.release()
def groups_add(self, request): if not type(request.options) == list: raise UMC_OptionTypeError( _('Options have to be given as list of dictionarys.')) messages = [] for group in request.options: options = None groupname = None users = None command = ['/usr/sbin/groupadd'] exit_code = None try: if not type(group) == dict: raise ValueError(_('Invalid optiontype.')) options = group.get('object', {}) if not type(options) == dict: raise ValueError(_('Invalid optiontype.')) groupname = options.get('groupname') users = options.get('users') if not groupname is not None: raise ValueError(_('Groupname is required.')) if not type(groupname) == str: raise ValueError(_('Groupname has to be given as string.')) self.validate_name(groupname) command += [groupname] # execute "groupadd" exit_code = self.process(command) if exit_code == 9: raise ValueError( _('Groupname "%s" is already in use.') % groupname) if exit_code: MODULE.error('Processing "%s" failed and returned %s' % (str(command), str(exit_code))) raise CreatingError( _('Could not create group. See log for more information.' )) if users is not None: if not type(users) == list: raise ModifyError(_('Users have to be given as list.')) if self.process( ['/usr/bin/gpasswd', '-M', ','.join(users), groupname]): raise ModifyError(_('Could not set list of users.')) except (ValueError, CreatingError, ModifyError) as e: messages += [str(e)] if type(e) == ModifyError: self.process(['/usr/sbin/groupdel', groupname]) else: messages += [''] self.finished(request.id, messages)
def _createProjectDir(self): '''Create project directory in the senders home.''' if not self.sender: return self._create_project_dir(self.sender, self.sender_projectdir) if not self.sender_projectdir: MODULE.error( 'ERROR: Sender information is not specified, cannot create project dir in the sender\'s home!' )
def rules_get(self, iterator): """Returns the specified rules requests.options = [ <string>, ] """ def get_address_type(address): if backend.REGEX_RULE_ADDRESS.match(address): return address else: return u'specific' def get_address_value(address): if backend.REGEX_RULE_ADDRESS.match(address): return None else: return address # Try to load firewall configuration try: firewall = backend.Firewall() except backend.Error as e: message = _(u"Could not load firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) for identifier in iterator: try: rule = firewall.rules[identifier] entry = { u'identifier': rule.identifier, u'protocol': rule.protocol, u'portStart': rule.port[0], u'portEnd': (rule.port[1] - 1), u'addressType': get_address_type(rule.address), u'addressValue': get_address_value(rule.address), u'packageName': rule.package, u'action': rule.action.lower(), u'description': self._get_description(rule.description), } except (backend.Error, KeyError) as e: message = _(u"Could not get firewall rule") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) else: yield entry
def test_connection(self): # test if connection is still active try: self.cursor.execute('SELECT TRUE') except pgdb.OperationalError as ex: MODULE.error('Connection to the PostgreSQL server lost: %s' % (ex,)) self.dbConnection = None try: self.connect() except UMC_Error: raise UMC_Error(_('Connection to the dabase lost.\n\n%s') % (_server_not_running_msg(),))
def _thread_finished(self, thread, thread_result, request): if not isinstance(thread_result, BaseException): request.status = SUCCESS self.finished(request.id, {'objects': thread_result['result'], 'success': thread_result['success']}, thread_result['message']) else: message = str(thread_result) + '\n' + '\n'.join(thread.trace) MODULE.error('An internal error occurred: %s' % message) request.status = MODULE_ERR self.finished(request.id, None, message)
def lang_timezones(self, request): '''Return a list of all available time zones.''' try: file = open('/lib/univention-installer/locale/timezone') except: MODULE.error( 'Cannot find locale data for timezones in /lib/univention-installer/locale' ) self.finished(request.id, None) return timezones = [ i.strip('\n') for i in file if not i.startswith('#') ] self.finished(request.id, timezones)
def init(self): os.umask( 0o022 ) # umc umask is too restrictive for app center as it creates a lot of files in docker containers self.ucr = ucr_instance() self.update_applications_done = False install_opener(self.ucr) self._is_working = False try: self.package_manager = PackageManager( info_handler=MODULE.process, step_handler=None, error_handler=MODULE.warn, lock=False, ) except SystemError as exc: MODULE.error(str(exc)) raise umcm.UMC_Error(str(exc), status=500) self.package_manager.set_finished( ) # currently not working. accepting new tasks get_package_manager._package_manager = self.package_manager # build cache _update_modules() get_action('list').get_apps() # not initialize here: error prone due to network errors and also kinda slow self._uu = None self._cm = None # in order to set the correct locale locale.setlocale(locale.LC_ALL, str(self.locale)) try: log_to_logfile() except IOError: pass # connect univention.appcenter.log to the progress-method handler = ProgressInfoHandler(self.package_manager) handler.setLevel(logging.INFO) get_base_logger().addHandler(handler) percentage = ProgressPercentageHandler(self.package_manager) percentage.setLevel(logging.DEBUG) get_base_logger().getChild('actions.install.progress').addHandler( percentage) get_base_logger().getChild('actions.upgrade.progress').addHandler( percentage) get_base_logger().getChild('actions.remove.progress').addHandler( percentage)
def _createCacheDir(self): '''Create cache directory.''' # create project cache directory MODULE.info('creating project cache dir: %s' % self.cachedir) try: os.makedirs(self.cachedir, 0o700) os.chown(self.cachedir, 0, 0) except (OSError, IOError) as exc: if exc.errno == errno.EEXIST: MODULE.info('cache dir %s exists.' % self.cachedir) else: MODULE.error('Failed to create cachedir: %s' % (exc, ))
def cleanup(): # write header before executing scripts f = open(LOG_FILE, 'a') f.write('\n\n=== Cleanup (%s) ===\n\n' % timestamp()) f.flush() ucr = univention.config_registry.ConfigRegistry() ucr.load() # The browser was only started, if system/setup/boot/start is true if ucr.is_true('system/setup/boot/start', False): MODULE.info('Appliance mode: try to shut down the browser') try: fpid = open(PATH_BROWSER_PID) strpid = fpid.readline().strip() pid = int(strpid) p = psutil.Process(pid) p.kill() except IOError: MODULE.warn('cannot open browser PID file: %s' % PATH_BROWSER_PID) except ValueError: MODULE.error('browser PID is not a number: "%s"' % strpid) except psutil.NoSuchProcess: MODULE.error('cannot kill process with PID: %s' % pid) # Maybe the system-setup CMD tool was started for p in psutil.process_iter(): if p.name == 'python2.6' and '/usr/share/univention-system-setup/univention-system-setup' in p.cmdline: p.kill() # unset the temporary interface if set for var in ucr.keys(): if RE_IPV4_TYPE.match(var) and ucr.get( var) == 'appliance-mode-temporary': f.write('unset %s' % var) keys = [var] for k in ['netmask', 'address', 'broadcast', 'network']: keys.append(var.replace('/type', '/%s' % k)) univention.config_registry.handler_unset(keys) # Shut down temporary interface subprocess.call( ['ifconfig', var.split('/')[1].replace('_', ':'), 'down']) # force a restart of UMC servers and apache subprocess.call(CMD_DISABLE_EXEC, stdout=f, stderr=f) subprocess.call(CMD_ENABLE_EXEC_WITH_RESTART, stdout=f, stderr=f) f.write('\n=== DONE (%s) ===\n\n' % timestamp()) f.flush() f.close() return True
def lang_timezones(self, request): '''Return a list of all available time zones.''' try: file = open('/usr/share/univention-system-setup/locale/timezone') except EnvironmentError: MODULE.error('Cannot find locale data for timezones in /usr/share/univention-system-setup/locale') self.finished(request.id, None) return timezones = [i.strip('\n') for i in file if not i.startswith('#')] self.finished(request.id, timezones)
def _get_all(self, klass, school, filter_str, lo): if school: schools = [School.cache(school)] else: schools = School.from_binddn(lo) objs = [] for school in schools: try: objs.extend(klass.get_all(lo, school.name, filter_str=filter_str, easy_filter=True)) except noObject as exc: MODULE.error('Could not get all objects of %r: %r' % (klass.__name__, exc)) return [obj.to_dict() for obj in objs]
def users_put(self, object): """ modify a local user """ response = [] errors = { # no information about returncodes, yet } try: success = True message = '' # Username username = object.get('$username$') new_username = object.get('username') pwoptions = {} cmd = ['/usr/sbin/usermod'] cmd += self._get_common_args( object, pwoptions ) # Change username if username != new_username: cmd += ['-l', new_username] # Account deactivation if pwoptions.get('lock'): cmd.append('-L') elif object.get('unlock'): cmd.append('-U') # Password password = object.get('password') self._change_user_password(username, password, pwoptions) # Execute if len(cmd) > 1: cmd.append(username) returncode = self.process(cmd) if returncode != 0: MODULE.error("cmd '%s' failed with returncode %d" % (' '.join(map(str, cmd)) returncode)) error = errors.get( returncode, _('unknown error with statuscode %d occurred') % (returncode) ) raise ValueError( error ) except ValueError as e: success = False message = '%s%s' % ('%s: ' % username if isinstance(username, basestring) else '', e,) MODULE.info( 'luga.users_edit: results: %s' % (message,) ) return {'message': message, 'success': success}
def users_add(self, object): """ add a local user """ errors = { 1: _('could not update password file'), 2: _('invalid command syntax'), 3: _('invalid argument to option'), 4: _('UID already in use (and no -o)'), 6: _('specified group doesnt exist'), 9: _('username already in use'), 10: _('could not update group file'), 12: _('could not create home directory'), 13: _('could not create mail spool'), } try: success = True message = '' # Username username = object.get('username') pwoptions = {} cmd = ['/usr/sbin/useradd', '-r'] if username == object.get('group'): object['create_usergroup'] = True cmd.append('-U') else: cmd.append('-N') cmd += self._get_common_args( object, pwoptions ) # Execute cmd.append(username) returncode = self.process(cmd) if 0 != returncode: MODULE.error("cmd '%s' failed with returncode %d" % (' '.join(map(str, cmd)), returncode)) error = errors.get( returncode, _('unknown error with statuscode %d occurred') % (returncode) ) raise ValueError( error ) # Change Password + options password = object.get('password') self._change_user_password(username, password, pwoptions) except ValueError as e: success = False message = '%s%s' % ('%s: ' % username if isinstance(username, basestring) else '', e,) MODULE.info( 'luga.users_add: results: %s' % (message,) ) return {'message': message, 'success': success}
def list_objects(container, object_type=None, ldap_connection=None, ldap_position=None): """Yields UDM objects""" try: result = ldap_connection.search(base=container, scope='one') except (LDAPError, udm_errors.ldapError): raise except udm_errors.noObject: raise ObjectDoesNotExist(container) except udm_errors.ldapTimeout: raise SearchTimeoutError() except udm_errors.ldapSizelimitExceeded: raise SearchLimitReached() except udm_errors.base as exc: UDM_Error(exc).reraise() for dn, attrs in result: modules = udm_modules.objectType(None, ldap_connection, dn, attrs) if not modules: MODULE.warn('Could not identify LDAP object %r' % (dn,)) continue if object_type == '$containers$' and not udm_modules.childs(modules[0]): continue if len(modules) > 1: MODULE.warn('Found multiple object types for %r: %r' % (dn, modules)) MODULE.info('dn: %r, attrs: %r' % (dn, attrs)) for mod in modules: module = UDM_Module(mod) if module.module: break if not module.module: MODULE.process('The UDM module %r could not be found. Ignoring LDAP object %r' % (modules[0], dn)) continue if module.superordinate_names: for superordinate in module.superordinate_names: so_module = UDM_Module(superordinate) so_obj = so_module.get(container) try: yield (module, module.get(dn, so_obj, attributes=attrs)) except BaseException: try: yield (module, module.get(dn, so_obj)) except (UDM_Error, udm_errors.base): MODULE.error('Could not load object %r (%r) exception: %s' % (dn, module.module, traceback.format_exc())) break else: try: yield (module, module.get(dn, attributes=attrs)) except BaseException: try: yield (module, module.get(dn)) except (UDM_Error, udm_errors.base): MODULE.error('Could not load object %r (%r) exception: %s' % (dn, module.module, traceback.format_exc()))
def net_dhclient(self, request): '''Request a DHCP address. Expects as options a dict containing the key "interface" and optionally the key "timeout" (in seconds).''' interface = request.options.get('interface') timeout = request.options.get('timeout', 45) if not interface: message = 'No property "interface" given for dhclient().' MODULE.error(message) self.finished(request.id, None, success=False, message=message) return res = util.dhclient(interface, timeout) self.finished(request.id, res)
def lang_keymaps(self, request): '''Return a list of all available keyboard layouts.''' try: file = open('/lib/univention-installer/locale/all-kmaps') except: MODULE.error( 'Cannot find locale data for keymaps in /lib/univention-installer/locale' ) self.finished(request.id, None) return r = csv.reader(file, delimiter=':') keymaps = [ { 'label': i[0], 'id': i[1] } for i in r if not i[0].startswith('#') ] self.finished(request.id, keymaps)
def net_dhclient(self, request): '''Request a DHCP address. Expects as options a dict containing the key "interface" and optionally the key "timeout" (in seconds).''' interface = request.options.get('interface') timeout = request.options.get('timeout', 45) if not interface: message = 'No property "interface" given for dhclient().' MODULE.error(message) self.finished(request.id, None, success = False, message = message) return res = util.dhclient(interface, timeout) self.finished(request.id, res)
def cleanup(): # write header before executing scripts f = open(LOG_FILE, 'a') f.write('\n\n=== Cleanup (%s) ===\n\n' % timestamp()) f.flush() ucr = univention.config_registry.ConfigRegistry() ucr.load() # The browser was only started, if system/setup/boot/start is true if ucr.is_true('system/setup/boot/start', False): MODULE.info('Appliance mode: try to shut down the browser') try: fpid = open(PATH_BROWSER_PID) strpid = fpid.readline().strip() pid = int(strpid) p = psutil.Process(pid) p.kill() except IOError: MODULE.warn('cannot open browser PID file: %s' % PATH_BROWSER_PID) except ValueError: MODULE.error('browser PID is not a number: "%s"' % strpid) except psutil.NoSuchProcess: MODULE.error('cannot kill process with PID: %s' % pid) # Maybe the system-setup CMD tool was started for p in psutil.process_iter(): if p.name == 'python2.6' and '/usr/share/univention-system-setup/univention-system-setup' in p.cmdline: p.kill() # unset the temporary interface if set for var in ucr.keys(): if RE_IPV4_TYPE.match(var) and ucr.get(var) == 'appliance-mode-temporary': f.write('unset %s' % var) keys = [var] for k in ['netmask', 'address', 'broadcast', 'network']: keys.append(var.replace('/type', '/%s' % k)) univention.config_registry.handler_unset(keys) # Shut down temporary interface subprocess.call(['ifconfig', var.split('/')[1].replace('_', ':'), 'down']) # force a restart of UMC servers and apache subprocess.call( CMD_DISABLE_EXEC, stdout = f, stderr = f ) subprocess.call( CMD_ENABLE_EXEC_WITH_RESTART, stdout = f, stderr = f ) f.write('\n=== DONE (%s) ===\n\n' % timestamp()) f.flush() f.close() return True
def restart(self, request): MODULE.error(str(request.arguments)) if self.permitted('services/restart', request.options): message = {} message['success'] = _('Successfully restarted') message['failed'] = _('Restarting the following services failed:') cb = notifier.Callback(self._service_changed, request, message) func = notifier.Callback(self._run_it, request.options, 'restart') thread = notifier.threads.Simple('services', func, cb) thread.run() else: message = _('You are not permitted to run this command.') request.status = MODULE_ERR self.finished(request.id, None, message)
def _check_error(self, request, partition_name): # TODO message = None try: fs = fstab.File() mt = mtab.File() except IOError as error: MODULE.error('Could not open %s' % error.filename) message = _('Could not open %s') % error.filename partition = fs.find(spec = partition_name) if partition: mounted_partition = mt.get(partition.spec) if mounted_partition: if 'usrquota' not in mounted_partition.options: MODULE.error('The following partition is mounted ' 'without quota support: %s' % partition_name) message = _('The following partition is mounted mounted ' 'without quota support: %s') % partition_name else: MODULE.error('The following partition is ' 'currently not mounted: %s' % partition_name) message = _('The following partition is currently ' 'not mounted: %s') % partition_name else: MODULE.error('No partition found (%s)' % partition_name) message = _('No partition found (%s)') % partition_name if message: request.status = MODULE_ERR self.finished(request.id, None, message)
def kill(self, request): failed = [] message = '' signal = request.options.get('signal', 'SIGTERM') pidList = request.options.get('pid', []) for pid in pidList: try: process = psutil.Process(int(pid)) if signal == 'SIGTERM': process.kill(15) elif signal == 'SIGKILL': process.kill(9) except psutil.NoSuchProcess, error: failed.append(pid) MODULE.error(str(error))
def genConfigs(server): ucr.load() MODULE.error('### server: %s' % server) co = server.co lo = server.lo configs = { 'sip.conf': genSipconf(co, lo, server), 'voicemail.conf': genVoicemailconf(co, lo, server), 'queues.conf': genQueuesconf(co, lo, server), 'musiconhold.conf': genMusiconholdconf(co, lo, server), 'extensions.conf': genExtensionsconf(co, lo, server), } return configs
def groups_add(self, request): if not type(request.options) == list: raise UMC_OptionTypeError(_('Options have to be given as list of dictionarys.')) messages = [] for group in request.options: options = None groupname = None users = None command = ['/usr/sbin/groupadd'] exit_code = None try: if not type(group) == dict: raise ValueError(_('Invalid optiontype.')) options = group.get('object', {}) if not type(options) == dict: raise ValueError(_('Invalid optiontype.')) groupname = options.get('groupname') users = options.get('users') if not groupname is not None: raise ValueError(_('Groupname is required.')) if not type(groupname) == str: raise ValueError(_('Groupname has to be given as string.')) self.validate_name(groupname) command += [groupname] # execute "groupadd" exit_code = self.process(command) if exit_code == 9: raise ValueError(_('Groupname "%s" is already in use.') % groupname) if exit_code: MODULE.error('Processing "%s" failed and returned %s' % (str(command), str(exit_code))) raise CreatingError(_('Could not create group. See log for more information.')) if users is not None: if not type(users) == list: raise ModifyError(_('Users have to be given as list.')) if self.process(['/usr/bin/gpasswd', '-M', ','.join(users), groupname]): raise ModifyError(_('Could not set list of users.')) except (ValueError, CreatingError, ModifyError) as e: messages += [str(e)] if type(e) == ModifyError: self.process(['/usr/sbin/groupdel', groupname]) else: messages += [''] self.finished(request.id, messages)
def dump_data(self): # we could return infos we have in this object itself. # but dont be too clever here. just dump # everything we have in LDAP. try: _lo = uldap.getMachineConnection() data = _lo.search('objectClass=univentionLicense') del _lo # just one license (should be always the case) # return the dictionary without the dn data = ldif.CreateLDIF(data[0][0], data[0][1]) return data except Exception as e: # no udm, no ldap, malformed return value, whatever MODULE.error('getting License from LDAP failed: %s' % e) return None
def process(self, args, stdin=None): """ process a shell command :param list args: list of command and arguments :param str stdin: stdin input :returns: int returncode """ try: args = map(lambda a: str(a).encode('utf-8'), args) p = Popen( args = args, stderr = PIPE, stdin = PIPE ) (stdout, stderr) = p.communicate(stdin) MODULE.debug('%s: stdout=%s; stderr=%s' % (' '.join(args)), stdout, stderr ) except OSError as e: MODULE.error( 'Command failed: %s\nException: %s' % (args, str(e)) ) raise ValueError( _('Command failed') ) return p.returncode
def users_remove(self, object, options={}): """ remove a list of local users param request.options = [ { username: <string>, force: <bool>, remove: <bool> }, ...] force: force removal of files, even if not owned by user remove: remove home directory and mail spool # TODO: message could be a dict with success and message """ errors = { 1: _('could not update password file'), 2: _('invalid command syntax'), 6: _('specified user doesnt exist'), 8: _('user currently logged in'), 10: _('could not update group file'), 12: _('could not remove home directory or mail spool') } try: success = True message = '' cmd = ['/usr/sbin/userdel'] username = object if options.get('force'): cmd.append('-f') if options.get('remove'): cmd.append('-r') cmd.append(username) returncode = self.process(cmd) if returncode != 0: MODULE.error("cmd '%s' failed with returncode %d" % (' '.join(map(str, cmd)), returncode)) error = errors.get( returncode, _('unknown error with statuscode %d occurred') % (returncode) ) raise ValueError( error ) except ValueError as e: success = False message = '%s%s' % ('%s: ' % username if isinstance(username, basestring) else '', e,) return {'message': message, 'success': success}
def init(self): try: if self.init_called: MODULE.warn("init() called multiple times!") return self.init_called = True MODULE.info("Initializing 'updater' module (PID = %d, LANG = '%s')" % (getpid(), self.locale)) self.uu = UniventionUpdater(False) self.ucr = univention.config_registry.ConfigRegistry() self.ucr.load() self._changes = {} # collects changed UCR vars, for committing the corresponding files self._current_job = {} # remembers last seen status of an installer job self._serial_file = Watched_File(COMPONENTS_SERIAL_FILE) self._updates_serial = Watched_Files(UPDATE_SERIAL_FILES) except Exception, ex: MODULE.error("init() ERROR: %s" % str(ex))
def lang_countrycodes(self, request): '''Return a list of all countries with their two letter chcountry codes.''' try: file = open('/lib/univention-installer/locale/country_codes') except: MODULE.error( 'Cannot find locale data for keymaps in /lib/univention-installer/locale' ) self.finished(request.id, None) return r = csv.reader(file, delimiter=':') countries = [ { 'label': i[0], 'id': i[1] } for i in r if not i[0].startswith('#') ] # add the value from ucr value to the list # this is required because invalid values will be unset in frontend # Bug #26409 tmpUCR = univention.config_registry.ConfigRegistry() tmpUCR.load() ssl_country = tmpUCR.get('ssl/country') if ssl_country not in [ i['id'] for i in countries ]: countries.append( {'label': ssl_country, 'id': ssl_country} ) self.finished(request.id, countries)
def get_system_info(self, request): MANUFACTURER = request.options['manufacturer'].encode( 'utf-8' ) MODEL = request.options['model'].encode( 'utf-8' ) COMMENT = request.options['comment'].encode( 'utf-8' ) SYSTEM_INFO_CMD = ( '/usr/bin/univention-system-info', '-m', MANUFACTURER, '-t', MODEL, '-c', COMMENT, '-s', request.options.get('ticket', ''), '-u', ) (exitcode, stdout, stderr, ) = self._call(SYSTEM_INFO_CMD) if exitcode: MODULE.error('Execution of univention-system-info failed: %s' % stdout) result = None request.status = MODULE_ERR else: result = {} for line in stdout.splitlines(): try: info, value = line.split(':') result[info] = value except: pass if result['mem']: match = self.mem_regex.match(result['mem']) if match: try: converted_mem = (float(match.groups()[0]) / 1048576) result['mem'] = '%.2f GB' % converted_mem result['mem'] = request['mem'].replace('.', ',') except: pass if result['Temp']: del result['Temp'] # remove unnecessary entry request.status = SUCCESS self.finished(request.id, result)
def groups_remove(self, request): if not type(request.options) == list: raise UMC_OptionTypeError(_('Options have to be given as list of strings.')) messages = [] user_cache = self._parse_users() for group in request.options: identifier = group.get('object', '').replace('<', '<') # frontend converts '<' to '<' for some reasons (undo that) gid = None primary_users = [] command = ['/usr/sbin/groupdel'] exit_code = None try: if not type(identifier) == str: raise ValueError(_('ID has to be given as string.')) # iterate over all users to check if one of them has the group as primary group for cached_user in user_cache: if cached_user['gid'] == gid: primary_users += [cached_user['username']] if primary_users: # users found wich have the group as primary group? raise ModifyError(_('Can not remove the primary group of user(s): %s.') % ', '.join(primary_users)) command += [identifier] # execute "groupdel" exit_code = self.process(command) if exit_code == 6: raise ModifyError(_('Group "%s" does not exist.') % identifier) if exit_code: raise ModifyError(_('Could not delete group "%s". See log for more informaton.') % identifier) MODULE.error('Processing "%s" failed and returned %s' % (str(command), str(exit_code))) except (ValueError, ModifyError) as e: messages += ['%s: %s' % (identifier, str(e))] else: messages += [''] self.finished(request.id, messages)
def create(self, request): server = getServer(request.options["server"]) MODULE.error('### request: %s' % request) MODULE.error('### self: %s' % self) MODULE.error('### values: %s' % request.options.get('values', {})) log = openLog(server["commonName"]) createConfigs(log, server) closeLog(log) self.finished(request.id, True)
def _thread(request, obj): # acquire the lock until the scripts have been executed self._finishedResult = False obj._finishedLock.acquire() try: self._progressParser.reset() # write the profile file and run setup scripts orgValues = util.load_values() util.pre_save(values, orgValues) MODULE.info('saving profile values') util.write_profile(values) if not values: MODULE.error( 'No property "values" given for save().' ) return False # in case of changes of the IP address, restart UMC server and web server # for this we ignore changes of virtual or non-default devices MODULE.info('Check whether ip addresses have been changed') restart = False for ikey, ival in values.iteritems(): if RE_IPV4.match(ikey) or RE_IPV6_DEFAULT.match(ikey) or RE_SSL.match(ikey): restart = True break MODULE.info('Restart servers: %s' % restart) # on a joined system or on a basesystem, we can run the setup scripts MODULE.info('runnning system setup scripts') util.run_scripts( self._progressParser, restart ) # done :) self._finishedResult = True return True finally: obj._finishedLock.release()
def get_available_locales(pattern, category='language_en'): '''Return a list of all available locales.''' try: fsupported = open('/usr/share/i18n/SUPPORTED') flanguages = open('/lib/univention-installer/locale/languagelist') except: MODULE.error( 'Cannot find locale data for languages in /lib/univention-installer/locale' ) return # get all locales that are supported rsupported = csv.reader(fsupported, delimiter=' ') supportedLocales = { 'C': True } for ilocale in rsupported: # we only support UTF-8 if ilocale[1] != 'UTF-8': continue # get the locale m = RE_LOCALE.match(ilocale[0]) if m: supportedLocales[m.groups()[0]] = True category = {'langcode': 0, 'language_en': 1, 'language': 2, 'countrycode': 4, 'fallbacklocale': 5}.get(category, 1) # open all languages rlanguages = csv.reader(flanguages, delimiter=';') locales = [] for ilang in rlanguages: if ilang[0].startswith('#'): continue if not pattern.match(ilang[category]): continue # each language might be spoken in several countries ipath = '/lib/univention-installer/locale/short-list/%s.short' % ilang[0] if os.path.exists(ipath): try: # open the short list with countries belonging to the language fshort = open(ipath) rshort = csv.reader(fshort, delimiter='\t') # create for each country a locale entry for jcountry in rshort: code = '%s_%s' % (ilang[0], jcountry[0]) if code in supportedLocales: locales.append({ 'id': '%s.UTF-8:UTF-8' % code, 'label': '%s (%s)' % (ilang[1], jcountry[2]) }) continue except Exception: pass # get the locale code code = ilang[0] if code.find('_') < 0 and code != 'C': # no underscore -> we need to build the locale ourself code = '%s_%s' % (ilang[0], ilang[4]) # final entry if code in supportedLocales: locales.append({ 'id': '%s.UTF-8:UTF-8' % code, 'label': ilang[1] }) return locales
def groups_put(self, request): if not type(request.options) == list: raise UMC_OptionTypeError(_('Options have to be given as list of dictionarys.')) messages = [] for group in request.options: group_index = None command = ['/usr/sbin/groupmod'] options = None identifier = None groupname = None users = None exit_code = None try: if not type(group) == dict: raise ValueError(_('Invalid optiontype.')) options = group.get('object', {}) if not type(options) == dict: raise ValueError(_('Invalid opiontype.')) identifier = options.get('$groupname$') groupname = options.get('groupname') gid = options.get('gid') users = options.get('users') if not identifier: raise ValueError(_('No group has been specified.')) if not type(identifier) == str: raise ValueError(_('ID has to be given as string.')) command += [identifier] if groupname is None and gid is None and users is None and administrators is None: raise ModifyError(_('No changes have been made.')) # first try to set new list of users, if given, with "gpasswd" if users is not None: if self.process(['/usr/bin/gpasswd', '-M', ','.join(users), identifier]): raise ModifyError(_('Could not modify list of users.')) # collect arguements for "groupmod" command if groupname is not None: self.validate_name(groupname) command += ['-n', groupname] if gid is not None: if not type(gid) == int: raise ValueError(_('"Group ID has to be given as string.')) command += ['-g', '%s' % gid] # exceute "groupmod" exit_code = self.process(command) if exit_code == 3: raise ValueError(_('"%s" is no valid Group ID. Group IDs may only consit of digits.') % gid) if exit_code == 4: raise ValueError(_('Group ID "%s" is already in use.') % gid) if exit_code == 6: raise ModifyError(_('Group "%s" does not exist.') % identifier) if exit_code == 9: raise ValueError(_('Groupname "%s" is already in use.') % groupname) if exit_code: MODULE.error('Processing "%s" failed and returned %s' % (str(command), str(exit_code))) raise ModifyError(_('Could not modify group. See log for more information.')) except (ValueError, ModifyError) as e: messages += [str(e)] else: messages += [''] self.finished(request.id, messages)