def _sanitize(self, value, name, further_args):
		app = Apps.find_by_string(value)
		if not app:
			self.raise_validation_error(_("Could not find an application for %s") % (value, ))
		app_version = app.version
		if not app.is_installed() and not app.install_permissions_exist():
			apps = Apps().get_all_apps_with_id(app.id)
			apps = [_app for _app in apps if not _app.install_permissions]
			if apps:
				for _app in apps:
					if _app.version == app_version:
						app = _app
						break
				else:
					app = sorted(apps)[-1]
		return app
Beispiel #2
0
 def _install_master_packages(self, app, unregister_if_uninstalled=False):
     old_app = Apps().find(app.id)
     was_installed = old_app.is_installed()
     if self._register_component(app):
         update_packages()
     ret = self._install_packages(app.default_packages_master)
     if was_installed:
         if old_app != app:
             self.log('Re-registering component for %s' % old_app)
             if self._register_component(old_app):
                 update_packages()
     elif unregister_if_uninstalled:
         self.log('Unregistering component for %s' % app)
         if self._unregister_component(app):
             update_packages()
     return ret
Beispiel #3
0
 def main(self, args):
     apps = args.app
     real_apps = []
     for app in apps:
         _apps = Apps().get_all_apps_with_id(app.id)
         if app._docker_prudence_is_true():
             _apps = [_app for _app in _apps if not _app.docker]
             if _apps:
                 app = sorted(_apps)[-1]
                 self.warn(
                     'Using %s instead of %s because docker is to be ignored'
                     % (app, args.app))
             else:
                 raise InstallNonDockerVersionError(args.app)
         if not app.install_permissions_exist():
             _apps = [
                 _app for _app in _apps if not _app.install_permissions
             ]
             if _apps:
                 app = sorted(_apps)[-1]
                 self.warn(
                     'Using %s instead of %s because of lacking install permissions'
                     % (app, args.app))
             else:
                 raise InstallWithoutPermissionError()
         real_apps.append(app)
     args.app = real_apps
     return self.do_it(args)
 def _list(self, pattern):
     ret = []
     for app in self.get_apps():
         versions = []
         installations = {}
         if pattern:
             if not fnmatch(app.id, pattern):
                 continue
         app = Apps().find(app.id, latest=True)
         for _app in Apps().get_all_apps_with_id(app.id):
             ldap_obj = get_app_ldap_object(_app)
             servers = ldap_obj.installed_on_servers()
             versions.append(_app.version)
             installations[_app.version] = servers
         ret.append((app, versions, installations))
     return ret
Beispiel #5
0
 def test_upgrade(self, app):
     if app.required_app_version_upgrade:
         required_version = LooseVersion(app.required_app_version_upgrade)
         installed_app = Apps().find(app.id)
         installed_version = LooseVersion(installed_app.version)
         if required_version > installed_version:
             return {'required_version': app.required_app_version_upgrade}
 def _get_docker(cls, app):
     if not app.docker:
         return
     if app.plugin_of:
         app = Apps().find(app.plugin_of)
         return cls._get_docker(app)
     return Docker(app, cls.logger)
Beispiel #7
0
	def main(self, args):
		if not args.apps:
			args.apps = Apps().get_all_locally_installed_apps()
		self.logfile_logger = get_logfile_logger('update-certificates')
		for app in args.apps:
			self.log('updating certificates for {0}'.format(app))
			self.update_certificates(app)
def get_apps(no_cache=False):
    if no_cache:
        AppCache().clear_cache()
    get = get_action('get')
    return [
        get.to_dict(app) for app in Apps().get_all_apps()
        if app.is_ucs_component()
    ]
 def _get_installations(self, app, hosts, app_ldap_objects):
     ret = {}
     local_ucs_version = ucr_get('version/version')
     for host in hosts:
         candidate = self._find_latest_app_version(app)
         role = host.info.get('serverRole')[0]
         description = host.info.get('description')
         remote_ucs_version = host.info.get('operatingSystemVersion')
         is_local = host.info.get('fqdn') == get_local_fqdn()
         if remote_ucs_version:
             remote_ucs_version = re.sub('.*([0-9]+\.[0-9]+).*', '\\1',
                                         remote_ucs_version)
         ip = host.info.get('ip')  # list
         version = None
         update_available = None
         for app_obj in app_ldap_objects:
             app_obj_version = app_obj.info.get('version')
             app_obj_id = app_obj.info.get('id')[:-len(app_obj_version) - 1]
             if app_obj_id == app.id:
                 if host.info.get('fqdn') in app_obj.info.get('server', []):
                     version = app_obj_version
                     break
         if local_ucs_version != remote_ucs_version:
             # unable to compute directly... better treat as not available
             update_available = False
         elif version:
             remote_app = Apps().find(app.id, app_version=version)
             if remote_app:
                 prevent_docker = None
                 if not is_local:
                     prevent_docker = True
                 candidate = Apps().find_candidate(
                     remote_app,
                     prevent_docker=prevent_docker) or remote_app
                 update_available = remote_app < candidate
         ret[host['name']] = {
             'ucs_version': remote_ucs_version,
             'version': version,
             'update_available': update_available,
             'candidate_version': candidate.version,
             'description': description,
             'ip': ip,
             'role': role,
         }
     return ret
Beispiel #10
0
 def _sanitize(self, value, name, further_args):
     app_id = value
     app_version = None
     if '=' in value:
         app_id, app_version = tuple(value.split('=', 1))
     app = Apps().find(app_id, app_version=app_version)
     if not app.is_installed() and not app.install_permissions_exist():
         apps = Apps().get_all_apps_with_id(app.id)
         apps = [_app for _app in apps if not _app.install_permissions]
         if apps:
             if app_version:
                 for _app in apps:
                     if _app.version == app_version:
                         app = _app
                         break
             else:
                 app = sorted(apps)[-1]
     return app
Beispiel #11
0
def app_is_running(app):
	from univention.appcenter.app_cache import Apps
	if isinstance(app, basestring):
		app = Apps().find(app)
	if app:
		if not app.docker:
			return False
		if not app.is_installed():
			return False
		try:
			from univention.appcenter.docker import Docker
		except ImportError:
			return None
		else:
			docker = Docker(app)
			return docker.is_running()
	else:
		return None
Beispiel #12
0
 def _install_master_packages(self,
                              app,
                              percentage_end=100,
                              unregister_if_uninstalled=False):
     old_app = Apps().find(app.id)
     was_installed = old_app.is_installed()
     self._register_component(app)
     ret = self._install_packages(app.default_packages_master,
                                  percentage_end)
     if was_installed:
         if old_app != app:
             self.log('Re-registering component for %s' % old_app)
             self._register_component(old_app)
             self._apt_get_update()
     elif unregister_if_uninstalled:
         self.log('Unregistering component for %s' % app)
         self._unregister_component(app)
         self._apt_get_update()
     return ret
Beispiel #13
0
	def invoke_docker(self, function, app, force, values, progress):
		if function == 'upgrade':
			app = Apps().find_candidate(app)
		serious_problems = False
		progress.title = _('%s: Running tests') % (app.name,)
		errors, warnings = app.check(function)
		can_continue = force  # "dry_run"
		if errors:
			MODULE.process('Cannot %s %s: %r' % (function, app.id, errors))
			serious_problems = True
			can_continue = False
		if warnings:
			MODULE.process('Warning trying to %s %s: %r' % (function, app.id, warnings))
		result = {
			'serious_problems': serious_problems,
			'invokation_forbidden_details': errors,
			'invokation_warning_details': warnings,
			'can_continue': can_continue,
			'software_changes_computed': False,
		}
		if can_continue:
			with self.locked():
				kwargs = {'noninteractive': True, 'skip_checks': ['shall_have_enough_ram', 'shall_only_be_installed_in_ad_env_with_password_service', 'must_not_have_concurrent_operation']}
				if function == 'install':
					progress.title = _('Installing %s') % (app.name,)
					kwargs['set_vars'] = values
				elif function == 'uninstall':
					progress.title = _('Uninstalling %s') % (app.name,)
				elif function == 'upgrade':
					progress.title = _('Upgrading %s') % (app.name,)
				action = get_action(function)
				handler = UMCProgressHandler(progress)
				handler.setLevel(logging.INFO)
				action.logger.addHandler(handler)
				try:
					result['success'] = action.call(app=app, username=self.username, password=self.password, **kwargs)
				except AppCenterError as exc:
					raise umcm.UMC_Error(str(exc), result=dict(
						display_feedback=True,
						title='%s %s' % (exc.title, exc.info)))
				finally:
					action.logger.removeHandler(handler)
		return result
	def _register_installed_apps_in_ucr(self):
		installed_codes = []
		for app in Apps().get_all_apps():
			if app.is_installed():
				installed_codes.append(app.code)
		with catch_stdout(self.logger):
			ucr_save({
				'appcenter/installed': '-'.join(installed_codes),
				'repository/app_center/installed': '-'.join(installed_codes),  # to be deprecated
			})
	def _upgrade_docker(self, app, args):
		install = get_action('install')()
		action_args = install._build_namespace(_namespace=args, app=app, set_vars=self._get_configure_settings(self.old_app, filter_action=False), send_info=False, skip_checks=['must_not_be_installed'])
		if install.call_with_namespace(action_args):
			app_cache = Apps()
			for _app in app_cache.get_all_apps():
				if _app.plugin_of == app.id and _app.is_installed():
					_app = app_cache.find(_app.id, latest=True)
					if _app.docker:
						_old_app = self.old_app
						self._upgrade_docker(_app, args)
						self.old_app = _old_app
			remove = get_action('remove')()
			action_args = remove._build_namespace(_namespace=args, app=self.old_app, send_info=False, skip_checks=['must_not_be_depended_on'])
			remove._remove_app(self.old_app, action_args)
			if remove._unregister_component(self.old_app):
				update_packages()
			self._call_join_script(app, args)  # run again in case remove() called an installed unjoin script
			self.old_app = app
Beispiel #16
0
	def _candidate_dict(cls, app):
		ret = {}
		if app.is_installed():
			candidate = Apps().find_candidate(app)
		else:
			candidate = None
		if candidate:
			ret['update_available'] = True
			ret['candidate_docker'] = candidate.docker
			ret['candidate_version'] = candidate.version
			ret['candidate_component_id'] = candidate.component_id
			ret['candidate_readme_update'] = candidate.readme_update
			ret['candidate_readme_post_update'] = candidate.readme_post_update
			ret['candidate_needs_install_permissions'] = not candidate.install_permissions_exist()
			ret['candidate_install_permissions_message'] = candidate.install_permissions_message
		else:
			ret['update_available'] = False  # TODO: ucr.is_true(app.ucr_upgrade_key); Bug#39916
			ret['candidate_needs_install_permissions'] = not app.install_permissions_exist()
			ret['candidate_install_permissions_message'] = app.install_permissions_message
		return ret
Beispiel #17
0
def get_default_values(app):
    from univention.appcenter.ini_parser import IniSectionAttribute
    from univention.appcenter.settings import BoolSetting, FileSetting, IntSetting, ListSetting, PasswordFileSetting, PasswordSetting, StatusSetting, StringSetting, UDMListSetting
    for kls in [
            StringSetting, IntSetting, BoolSetting, ListSetting,
            UDMListSetting, FileSetting, PasswordFileSetting, PasswordSetting,
            StatusSetting
    ]:
        if 'default_for_testing' not in kls._attrs:
            attr = IniSectionAttribute()
            attr.name = 'default_for_testing'
            kls._attrs['default_for_testing'] = attr
    app = FindApps().find(app)
    app = FindApps().find_candidate(app) or app
    ret = {}
    for setting in app.get_settings():
        value = setting.default_for_testing
        if value is not None:
            ret[setting.name] = setting.sanitize_value(app, value)
    return ret
Beispiel #18
0
 def test_upgrade(self, apps):
     current_ram = get_current_ram_available()
     required_ram = 0
     for app in apps:
         required_ram += app.min_physical_ram
         installed_app = Apps().find(app.id)
         # is already installed, just a minor version upgrade
         #   RAM "used" by this installed app should count
         #   as free. best approach: subtract it
         required_ram -= installed_app.min_physical_ram
     if current_ram < required_ram:
         return {'minimum': required_ram, 'current': current_ram}
 def _appcenter_caches(self, args):
     if args.appcenter_server:
         return [AppCenterCache(server=args.appcenter_server)]
     else:
         ret = []
         servers = set()
         for appcenter_cache in Apps().get_appcenter_caches():
             server = appcenter_cache.get_server()
             if server not in servers:
                 servers.add(server)
                 ret.append(appcenter_cache)
         return ret
    def get_blocking_apps(cls, ucs_version):
        ''' checks if update is possible for this app '''
        ucs_version = UCS_Version(ucs_version + '-0')
        next_minor = '%(major)d.%(minor)d' % ucs_version
        next_version = '%(major)d.%(minor)d-%(patchlevel)d' % ucs_version
        current_version = UCS_Version(ucr_get('version/version') + '-0')
        current_minor = '%(major)d.%(minor)d' % current_version

        # if this is just a patchlevel update, everything is fine
        if current_minor >= next_minor:
            return {}

        # first, update the local cache and get current apps
        update = get_action('update')
        update.logger = get_logfile_logger('update-check')
        update.call()
        current_cache = Apps(locale='en')

        # get apps in next version
        with TemporaryDirectory() as tempdir:
            update.call(ucs_version=next_minor,
                        cache_dir=tempdir,
                        just_get_cache=True)
            next_cache = AppCenterCache.build(ucs_versions=next_minor,
                                              server=default_server(),
                                              locale='en',
                                              cache_dir=tempdir)
            next_apps = next_cache.get_every_single_app()

        # check apps
        blocking_apps = dict()
        for app in current_cache.get_all_locally_installed_apps():
            if not cls.app_can_update(app, next_version, next_apps):
                cls.debug('app %s is not available for %s' %
                          (app.id, next_version))
                blocking_apps[app.component_id] = app.name
            else:
                cls.debug('app %s is available for %s' %
                          (app.id, next_version))
        return blocking_apps
Beispiel #21
0
 def _update_apps(self, args):
     self.log(
         'Updating all installed Apps to use the new App Center server')
     logfile_logger = get_logfile_logger('dev-use-test-appcenter')
     for app in Apps().get_all_locally_installed_apps():
         self.log('Updating %s' % app)
         register = get_action('register')
         # we should only use ['component'] in container_mode()
         # and None otherwise, because it is more correct. however,
         # this would require credentials (for potential schema updates etc)
         register.call(apps=[app], register_task=['component'])
         if app.docker and not container_mode():
             try:
                 from univention.appcenter.docker import Docker
             except ImportError:
                 # should not happen
                 self.log('univention-appcenter-docker is not installed')
                 continue
             start = get_action('start')
             start.call(app=app)
             docker = Docker(app, self.logger)
             self.log('Updating container... (checking for appbox)')
             if docker.execute('which', 'univention-app').returncode == 0:
                 self.log(
                     '... setting the new App Center inside the container')
                 returncode = docker.execute(
                     'univention-install',
                     '-y',
                     'univention-appcenter-dev',
                     _logger=logfile_logger).returncode
                 if returncode != 0:
                     self.warn(
                         'univention-install univention-appcenter-dev failed!'
                     )
                 if args.revert:
                     returncode = docker.execute(
                         'univention-app',
                         'dev-use-test-appcenter',
                         '--revert',
                         _logger=logfile_logger).returncode
                 else:
                     returncode = docker.execute(
                         'univention-app',
                         'dev-use-test-appcenter',
                         '--appcenter-host',
                         args.appcenter_host,
                         _logger=logfile_logger).returncode
                 if returncode != 0:
                     self.fatal(
                         'univention-app dev-use-test-appcenter failed!')
             else:
                 self.log('... nothing to do here')
 def main(self, args):
     reload_package_manager()
     apps = args.apps
     if not apps:
         self.debug('No apps given. Using all')
         apps = Apps().get_all_apps()
     self._register_component_for_apps(apps, args)
     self._register_files_for_apps(apps, args)
     self._register_host_for_apps(apps, args)
     self._register_app_for_apps(apps, args)
     self._register_database_for_apps(apps, args)
     self._register_attributes_for_apps(apps, args)
     self._register_installed_apps_in_ucr()
Beispiel #23
0
 def _candidate_dict(cls, app):
     ret = {}
     candidate = Apps().find_candidate(app)
     if candidate:
         ret['update_available'] = True
         ret['candidate_docker'] = candidate.docker
         ret['candidate_version'] = candidate.version
         ret['candidate_component_id'] = candidate.component_id
         ret['candidate_readme_update'] = candidate.readme_update
         ret['candidate_readme_post_update'] = candidate.readme_post_update
     else:
         ret['update_available'] = False  # TODO: ucr.is_true(app.ucr_upgrade_key); Bug#39916
     return ret
Beispiel #24
0
 def _install_packages_dry_run(self, app, args, with_dist_upgrade):
     original_app = Apps().find(app.id)
     if original_app.is_installed():
         was_installed = True
     else:
         was_installed = False
     self.log('Dry run for %s' % app)
     if self._register_component(app):
         self.debug('Updating packages')
         update_packages()
     self.debug('Component %s registered' % app.component_id)
     pkgs = self._get_packages_for_dry_run(app, args)
     self.debug('Dry running with %r' % pkgs)
     ret = install_packages_dry_run(pkgs)
     if with_dist_upgrade:
         upgrade_ret = dist_upgrade_dry_run()
         ret['install'] = sorted(
             set(ret['install']).union(set(upgrade_ret['install'])))
         ret['remove'] = sorted(
             set(ret['remove']).union(set(upgrade_ret['remove'])))
         ret['broken'] = sorted(
             set(ret['broken']).union(set(upgrade_ret['broken'])))
     if args.install_master_packages_remotely:
         # TODO: should test remotely
         self.log('Not testing package changes of remote packages!')
         pass
     if args.dry_run or ret['broken']:
         if was_installed:
             if self._register_component(original_app):
                 self.debug('Updating packages')
                 update_packages()
             self.debug('Component %s reregistered' %
                        original_app.component_id)
         else:
             if self._unregister_component(app):
                 self.debug('Updating packages')
                 update_packages()
             self.debug('Component %s unregistered' % app.component_id)
     return ret
 def buy(self, application):
     app = Apps().find(application)
     if not app or not app.shop_url:
         return None
     ret = {}
     ret['key_id'] = self.ucr.get('license/uuid')
     ret['ucs_version'] = self.ucr.get('version/version')
     ret['app_id'] = app.id
     ret['app_version'] = app.version
     # ret['locale'] = locale.getlocale()[0] # done by frontend
     ret['user_count'] = None  # FIXME: get users and computers from license
     ret['computer_count'] = None
     return ret
Beispiel #26
0
 def test_install(self, app):
     conflictedapps = set()
     apps_cache = Apps()
     # check ConflictedApps
     for _app in apps_cache.get_all_apps():
         if not _app._allowed_on_local_server():
             # cannot be installed, continue
             continue
         if _app.id in app.conflicted_apps or app.id in _app.conflicted_apps:
             if _app.is_installed():
                 conflictedapps.add(_app.id)
             elif _app in self.other_apps(app):
                 conflictedapps.add(_app.id)
     # check port conflicts
     ports = []
     for i in app.ports_exclusive:
         ports.append(i)
     for i in app.ports_redirection:
         ports.append(i.split(':', 1)[0])
     for app_id, container_port, host_port in app_ports():
         if app_id != app.id and str(host_port) in ports:
             conflictedapps.add(app_id)
     for _app in self.other_apps(app):
         other_ports = set()
         for i in _app.ports_exclusive:
             other_ports.add(i)
         for i in _app.ports_redirection:
             other_ports.add(i.split(':', 1)[0])
         if other_ports.intersection(ports):
             conflictedapps.add(_app.id)
     if conflictedapps:
         conflictedapps = [
             apps_cache.find(app_id) for app_id in conflictedapps
         ]
         return [{
             'id': _app.id,
             'name': _app.name
         } for _app in conflictedapps if _app]
Beispiel #27
0
    def test_install(self, app):
        unmet_apps = []

        apps_cache = Apps()
        # RequiredApps
        for _app in apps_cache.get_all_apps():
            if _app.id in app.required_apps:
                if not _app.is_installed():
                    unmet_apps.append({
                        'id': _app.id,
                        'name': _app.name,
                        'in_domain': False
                    })

        # RequiredAppsInDomain
        domain = get_action('domain')
        apps = [
            apps_cache.find(app_id) for app_id in app.required_apps_in_domain
        ]
        apps_info = domain.to_dict(apps)
        for _app in apps_info:
            if not _app:
                continue
            if not _app['is_installed_anywhere']:
                local_allowed = _app['id'] not in app.conflicted_apps
                unmet_apps.append({
                    'id': _app['id'],
                    'name': _app['name'],
                    'in_domain': True,
                    'local_allowed': local_allowed
                })
        unmet_apps = [
            unmet_app for unmet_app in unmet_apps
            if unmet_app['id'] not in (_app.id
                                       for _app in self.other_apps(app))
        ]
        if unmet_apps:
            return unmet_apps
Beispiel #28
0
    def test_remove(self, app):
        depending_apps = []

        apps_cache = Apps()
        # RequiredApps
        for _app in apps_cache.get_all_apps():
            if app.id in _app.required_apps and _app.is_installed():
                depending_apps.append({'id': _app.id, 'name': _app.name})

        # RequiredAppsInDomain
        apps = [
            _app for _app in apps_cache.get_all_apps()
            if app.id in _app.required_apps_in_domain
        ]
        if apps:
            domain = get_action('domain')
            self_info = domain.to_dict([app])[0]
            hostname = ucr_get('hostname')
            if not any(
                    inst['version']
                    for host, inst in self_info['installations'].iteritems()
                    if host != hostname):
                # this is the only installation
                apps_info = domain.to_dict(apps)
                for _app in apps_info:
                    if _app['is_installed_anywhere']:
                        depending_apps.append({
                            'id': _app['id'],
                            'name': _app['name']
                        })

        depending_apps = [
            depending_app for depending_app in depending_apps
            if depending_app['id'] not in (_app.id
                                           for _app in self.other_apps(app))
        ]
        if depending_apps:
            return depending_apps
Beispiel #29
0
 def _get_app_network(self):
     _logger.debug('Getting network for %s' % self.app)
     network = ucr_get(self.app.ucr_ip_key)
     if network and '/' in network:
         _logger.debug('Found %s' % network)
         try:
             network = IPv4Network(u'%s' % (network, ), False)
         except ValueError as exc:
             _logger.warn('Error using the network %s: %s' % (network, exc))
             return None
         else:
             return network
     docker0_net = IPv4Network(
         u'%s' %
         (ucr_get('appcenter/docker/compose/network', '172.16.1.1/16'), ),
         False)
     gateway, netmask = docker0_net.exploded.split('/',
                                                   1)  # '172.16.1.1', '16'
     used_docker_networks = []
     for _app in Apps().get_all_apps(
     ):  # TODO: find container not managed by the App Center?
         if _app.id == self.app.id:
             continue
         ip = ucr_get(_app.ucr_ip_key)
         try:
             app_network = IPv4Network(u'%s' % (ip, ), False)
         except ValueError as exc:
             continue
         else:
             used_docker_networks.append(app_network)
     prefixlen_diff = 24 - int(netmask)
     if prefixlen_diff <= 0:
         _logger.warn(
             'Cannot get a subnet big enough'
         )  # maybe I could... but currently, I only work with 24-netmasks
         return None
     for network in docker0_net.subnets(
             prefixlen_diff
     ):  # 172.16.1.1/24, 172.16.2.1/24, ..., 172.16.255.1/24
         _logger.debug('Testing %s' % network)
         if IPv4Address(u'%s' % (gateway, )) in network:
             _logger.debug('Refusing due to "main subnet"')
             continue
         if any(
                 app_network.overlaps(network)
                 for app_network in used_docker_networks):
             _logger.debug('Refusing due to range already used')
             continue
         return network
     _logger.warn('Cannot find any viable subnet')
Beispiel #30
0
def get_requested_apps():
    ret = []
    try:
        with open(APPCENTER_FILE) as f:
            for line in f:
                app = Apps().find(line.strip())
                if app:
                    ret.append(app)
                else:
                    pass
                    #utils.fail('Error finding %s' % (line,))
    except EnvironmentError:
        pass
        #utils.fail('Error reading %s: %s' % (APPCENTER_FILE, exc))
    return ret