def _fetch_file(self, key, url): try: # open the license file fp = util.urlopen(url) self._options[key] = ''.join(fp.readlines()).strip() except (urllib2.HTTPError, urllib2.URLError) as e: MODULE.warn('No information for %s available (%s): %s' % (key, e, url))
def _thread( request ): result = [] for ldap_dn in request.options: if request.flavor == 'users/self': ldap_dn = self._user_dn module = get_module( request.flavor, ldap_dn ) if module is None: MODULE.process( 'A module for the LDAP DN %s could not be found' % ldap_dn ) continue obj = module.get( ldap_dn ) if obj: props = obj.info for passwd in module.password_properties: if passwd in props: del props[ passwd ] props[ '$dn$' ] = obj.dn props[ '$options$' ] = {} for opt in module.get_options( udm_object = obj ): props[ '$options$' ][ opt[ 'id' ] ] = opt[ 'value' ] props[ '$policies$' ] = {} for policy in obj.policies: pol_mod = get_module( None, policy ) if pol_mod and pol_mod.name: props[ '$policies$' ][ pol_mod.name ] = policy props[ '$labelObjectType$' ] = module.title; result.append( props ) else: MODULE.process( 'The LDAP object for the LDAP DN %s could not be found' % ldap_dn ) return result
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 list_jobs(self,request): """ returns list of jobs for one printer. """ # ----------- DEBUG ----------------- MODULE.info("printers/jobs/query invoked with:") pp = pprint.PrettyPrinter(indent=4) st = pp.pformat(request.options).split("\n") for s in st: MODULE.info(" << %s" % s) # ----------------------------------- printer = request.options.get('printer','') result = self._job_list(printer) # ---------- DEBUG -------------- MODULE.info("printers/jobs/query returns:") pp = pprint.PrettyPrinter(indent=4) st = '' if len(result) > 5: tmp = result[0:5] MODULE.info(" >> %d entries, first 5 are:" % len(result)) st = pp.pformat(tmp).split("\n") else: st = pp.pformat(result).split("\n") for s in st: MODULE.info(" >> %s" % s) # -------------------------------- self.finished(request.id,result)
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 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 save( self, request ): """Saves the UCS Active Directory Connector configuration options: LDAP_Host: hostname of the AD server LDAP_Base: LDAP base of the AD server LDAP_BindDN: LDAP DN to use for authentication KerberosDomain: kerberos domain PollSleep: time in seconds between polls RetryRejected: how many time to retry a synchronisation MappingSyncMode: synchronisation mode MappingGroupLanguage: language of the AD server return: { 'success' : (True|False), 'message' : <details> } """ self.required_options( request, *map( lambda x: x[ 0 ], Instance.OPTION_MAPPING ) ) self.guessed_baseDN = None try: fn = '%s/.htaccess' % DIR_WEB_AD fd = open( fn, 'w' ) fd.write( 'require user %s\n' % self._username ) fd.close() os.chmod( fn, 0644 ) os.chown( fn, 0, 0 ) except Exception, e: message = _( 'An error occured while saving .htaccess (filename=%(fn)s ; exception=%(exception)s)') % { 'fn': fn, 'exception': e.__class__.__name__ } MODULE.process( 'An error occured while saving .htaccess (filename=%(fn)s ; exception=%(exception)s)' % { 'fn': fn, 'exception': e.__class__.__name__ } ) self.finished( request.id, { 'success' : False, 'message' : message } ) return
def _thread(request, obj, username, password): # 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 util.pre_save(values, orgValues) # on unjoined DC master the nameserver must be set to the external nameserver if newrole == 'domaincontroller_master' and not orgValues.get('joined'): for i in range(1,4): # overwrite these values only if they are set, because the UMC module # will save only changed values if values.get( 'dns/forwarder%d'%i ): values[ 'nameserver%d'%i ] = values.get( 'dns/forwarder%d'%i ) MODULE.info('saving profile values') util.write_profile(values) # unjoined DC master (that is not being converted to a basesystem) -> run the join script MODULE.info('runnning system setup join script') util.run_joinscript( self._progressParser, username, password ) # done :) self._finishedResult = True # we should do a cleanup now self._cleanup_required = True return True finally: obj._finishedLock.release()
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 install(self, package_manager, component_manager, add_component=True): try: # remove all existing component versions for iapp in self.versions: # dont remove yourself (if already added) if iapp is not self: component_manager.remove_app(iapp) # add the new repository component for the app ucr.load() is_master = ucr.get('server/role') in ('domaincontroller_master', 'domaincontroller_backup') # packages need to be installed on backup AND master systems to_install = self.get('defaultpackages') if is_master and self.get('defaultpackagesmaster'): to_install.extend(self.get('defaultpackagesmaster')) if add_component: component_manager.put_app(self) package_manager.update() # install + dist_upgrade package_manager.log('\n== INSTALLING %s AT %s ==\n' % (self.name, datetime.now())) package_manager.commit(install=to_install, dist_upgrade=True) # successful installation status = 200 except: MODULE.warn(traceback.format_exc()) status = 500 self._send_information('install', status) return status == 200
def colors( self, request ): """Returns a list of all existing colors.""" MODULE.info( 'MODULEID.colors: options: %s' % str( request.options ) ) allColors = set(map(lambda x: x['color'], Instance.entries)) allColors = map(lambda x: { 'id': x, 'label': x }, allColors) allColors.append({ 'id': 'None', 'label': _('All colors') }) MODULE.info( 'MODULEID.colors: result: %s' % str( allColors ) ) self.finished(request.id, allColors)
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 uninstall_dry_run(self, package_manager): MODULE.info('Invoke uninstall_dry_run') package_manager.reopen_cache() to_uninstall = package_manager.get_packages(self.get('defaultpackages')) for package in to_uninstall: package.mark_delete() packages = [pkg.name for pkg in package_manager.packages() if pkg.is_auto_removable] package_manager.reopen_cache() return packages
def _send_return( thread, result, request ): import traceback if not isinstance( result, BaseException ): MODULE.info( 'sending mail: completed successfully' ) self.finished( request.id, True ) else: msg = '%s\n%s: %s\n' % ( ''.join( traceback.format_tb( thread.exc_info[ 2 ] ) ), thread.exc_info[ 0 ].__name__, str( thread.exc_info[ 1 ] ) ) MODULE.process( 'sending mail:An internal error occurred: %s' % msg ) self.finished( request.id, False, msg, False )
def process_button(self): # if self._first_attempt_button: # self._first_attempt_button = False # raise UMC_Error(_('First try failed. Try again.')) MODULE.process('Generating new secret...') newkey_path = "/etc/openvpn/sitetosite.newkey" os.popen("openvpn --genkey --secret %s" % newkey_path) with open(newkey_path, 'r') as newkey_file: newkey=newkey_file.read().replace('\n', '<br />') return newkey
def _thread_finish_success( self, thread, result, request ): """This method is invoked when a threaded request function is finished. The result is send back to the client. If the result is an instance of BaseException an error is returned.""" if self._check_thread_error( thread, result, request ): return success, data = result MODULE.info( 'Got result from UVMMd: success: %s, data: %s' % ( success, data ) ) self.finished( request.id, { 'success' : success, 'data' : data } )
def _logstamp(self, fname): """ Logfile timestamp. Now a seperate function. """ try: st = stat(fname) if st: MODULE.info(" >> log file stamp = '%s'" % st[9]) return st[9] return 0 except: return 0
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 _check_thread_error( self, thread, result, request ): """Checks if the thread returned an exception. In that case in error response is send and the function returns True. Otherwise False is returned.""" if not isinstance( result, BaseException ): return False msg = '%s\n%s: %s\n' % ( ''.join( traceback.format_tb( thread.exc_info[ 2 ] ) ), thread.exc_info[ 0 ].__name__, str( thread.exc_info[ 1 ] ) ) MODULE.process( 'An internal error occurred: %s' % msg ) self.finished( request.id, None, msg, False ) return True
def calculateFractions( self ): MODULE.info( 'Calculating maximum value for fractions ...' ) for category in filter( lambda x: os.path.isdir( os.path.join( PATH_SETUP_SCRIPTS, x ) ), os.listdir( PATH_SETUP_SCRIPTS ) ): cat_path = os.path.join( PATH_SETUP_SCRIPTS, category ) for script in filter( lambda x: os.path.isfile( os.path.join( cat_path, x ) ), os.listdir( cat_path ) ): name = '%s/%s' % ( category, script ) if not name in self.fractions: self.fractions[ name ] = 1 self.current.max = sum( self.fractions.values() ) MODULE.info( 'Calculated a maximum value of %d' % self.current.max )
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 restart(self, request): """Restart apache, UMC Web server, and UMC server. """ # send a response immediately as it won't be sent after the server restarts self.finished(request.id, True) # enable server restart and trigger restart # (disable first to make sure the services are restarted) subprocess.call(CMD_DISABLE_EXEC) p = subprocess.Popen(CMD_ENABLE_EXEC_WITH_RESTART, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, err = p.communicate() MODULE.info("enabling server restart:\n%s" % out)
def _return( pid, status, bufstdout, bufstderr, request, fn ): success = True if status == 0: univention.config_registry.handler_set( [ u'connector/ad/ldap/certificate=%s' % fn ] ) message = _( 'Certificate has been uploaded successfully.' ) MODULE.info( 'Certificate has been uploaded successfully. status=%s\nSTDOUT:\n%s\n\nSTDERR:\n%s' % ( status, '\n'.join( bufstdout ), '\n'.join( bufstderr ) ) ) else: success = False message = _( 'Certificate upload or conversion failed.' ) MODULE.process( 'Certificate upload or conversion failed. status=%s\nSTDOUT:\n%s\n\nSTDERR:\n%s' % ( status, '\n'.join( bufstdout ), '\n'.join( bufstderr ) ) ) self.finished( request.id, [ { 'success' : success, 'message' : message } ] )
def _return( thread, result, request ): success = not result if result: message = _('Switching running state of Active Directory Connector failed.') MODULE.info( 'Switching running state of Active Directory Connector failed. exitcode=%s' % result ) else: if request.options.get( 'action' ) == 'start': message = _( 'UCS Active Directory Connector has been started.' ) else: message = _( 'UCS Active Directory Connector has been stopped.' ) self.finished( request.id, { 'success' : success, 'message' : message } )
def _finished( thread, result, request ): if self._check_thread_error( thread, result, request ): return success, data = result json = object2dict( data ) MODULE.info( 'New domain: success: %s, data: %s' % ( success, json ) ) if success: self.finished( request.id, json ) else: self.finished( request.id, None, message = str( data ), status = MODULE_ERR_COMMAND_FAILED )
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 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 _finished(thread, result): if isinstance(result, BaseException): MODULE.warn('Exception during %s %s: %s' % (function, application_id, str(result)))
def invoke(self, request): # ATTENTION!!!!!!! # this function has to stay compatible with the very first App Center installations (Dec 2012) # if you add new arguments that change the behaviour # you should add a new method (see invoke_dry_run) or add a function name (e.g. install-schema) # this is necessary because newer app center may talk remotely with older one # that does not understand new arguments and behaves the old way (in case of # dry_run: install application although they were asked to dry_run) host = request.options.get('host') function = request.options.get('function') send_as = function if function.startswith('install'): function = 'install' if function.startswith('update'): function = 'update' application_id = request.options.get('application') Application.all(only_local=True) # if not yet cached, cache. but use only local inis application = Application.find(application_id) if application is None: raise umcm.UMC_Error(_('Could not find an application for %s') % (application_id,)) force = request.options.get('force') only_dry_run = request.options.get('only_dry_run') dont_remote_install = request.options.get('dont_remote_install') only_master_packages = send_as.endswith('schema') MODULE.process('Try to %s (%s) %s on %s. Force? %r. Only master packages? %r. Prevent installation on other systems? %r. Only dry run? %r.' % (function, send_as, application_id, host, force, only_master_packages, dont_remote_install, only_dry_run)) # REMOTE invocation! if host and host != self.ucr.get('hostname'): try: client = Client(host, self.username, self.password) result = client.umc_command('appcenter/invoke', request.options).result except (ConnectionError, HTTPError) as exc: MODULE.error('Error during remote appcenter/invoke: %s' % (exc,)) result = { 'unreachable': [host], 'master_unreachable': True, 'serious_problems': True, 'software_changes_computed': True, # not really... } else: if result['can_continue']: def _thread_remote(_client, _package_manager): with _package_manager.locked(reset_status=True, set_finished=True): _package_manager.unlock() # not really locked locally, but busy, so "with locked()" is appropriate Application._query_remote_progress(_client, _package_manager) def _finished_remote(thread, result): if isinstance(result, BaseException): MODULE.warn('Exception during %s %s: %s' % (function, application_id, str(result))) thread = notifier.threads.Simple('invoke', notifier.Callback(_thread_remote, client, self.package_manager), _finished_remote) thread.run() self.finished(request.id, result) return # make sure that the application can be installed/updated can_continue = True delayed_can_continue = True serious_problems = False result = { 'install': [], 'remove': [], 'broken': [], 'unreachable': [], 'master_unreachable': False, 'serious_problems': False, 'hosts_info': {}, 'problems_with_hosts': False, 'serious_problems_with_hosts': False, 'invokation_forbidden_details': {}, 'invokation_warning_details': {}, 'software_changes_computed': False, } if not application: MODULE.process('Application not found: %s' % application_id) can_continue = False if can_continue and not only_master_packages: forbidden, warnings = application.check_invokation(function, self.package_manager) if forbidden: MODULE.process('Cannot %s %s: %r' % (function, application_id, forbidden)) result['invokation_forbidden_details'] = forbidden can_continue = False serious_problems = True if warnings: MODULE.process('Warning trying to %s %s: %r' % (function, application_id, forbidden)) result['invokation_warning_details'] = warnings if not force: # dont stop "immediately". # compute the package changes! delayed_can_continue = False result['serious_problems'] = serious_problems result['can_continue'] = can_continue try: if can_continue: if self._working(): # make it multi-tab safe (same session many buttons to be clicked) raise LockError() with self.package_manager.locked(reset_status=True): previously_registered_by_dry_run = False if can_continue and function in ('install', 'update'): remove_component = only_dry_run dry_run_result, previously_registered_by_dry_run = application.install_dry_run(self.package_manager, self.component_manager, remove_component=remove_component, username=self._username, password=self.password, only_master_packages=only_master_packages, dont_remote_install=dont_remote_install, function=function, force=force) result.update(dry_run_result) result['software_changes_computed'] = True serious_problems = bool(result['broken'] or result['master_unreachable'] or result['serious_problems_with_hosts']) if serious_problems or (not force and (result['unreachable'] or result['install'] or result['remove'] or result['problems_with_hosts'])): MODULE.process('Problems encountered or confirmation required. Removing component %s' % application.component_id) if not remove_component: # component was not removed automatically after dry_run if application.candidate: # operation on candidate failed. re-register original application application.register(self.component_manager, self.package_manager) else: # operation on self failed. unregister all application.unregister_all_and_register(None, self.component_manager, self.package_manager) can_continue = False elif can_continue and function in ('uninstall',) and not force: result['remove'] = application.uninstall_dry_run(self.package_manager) result['software_changes_computed'] = True can_continue = False can_continue = can_continue and delayed_can_continue and not only_dry_run result['serious_problems'] = serious_problems result['can_continue'] = can_continue if can_continue and not only_dry_run: def _thread(module, application, function): with module.package_manager.locked(set_finished=True): with module.package_manager.no_umc_restart(exclude_apache=True): if function in ('install', 'update'): # dont have to add component: already added during dry_run return application.install(module.package_manager, module.component_manager, add_component=only_master_packages, send_as=send_as, username=self._username, password=self.password, only_master_packages=only_master_packages, dont_remote_install=dont_remote_install, previously_registered_by_dry_run=previously_registered_by_dry_run) else: return application.uninstall(module.package_manager, module.component_manager, self._username, self.password) def _finished(thread, result): if isinstance(result, BaseException): MODULE.warn('Exception during %s %s: %s' % (function, application_id, str(result))) thread = notifier.threads.Simple('invoke', notifier.Callback(_thread, self, application, function), _finished) thread.run() else: self.package_manager.set_finished() # nothing to do, ready to take new commands self.finished(request.id, result) except LockError: # make it thread safe: another process started a package manager # this module instance already has a running package manager raise umcm.UMC_Error(_('Another package operation is in progress'))