def find_candidate(self, app, prevent_docker=None): if prevent_docker is None: prevent_docker = ucr_is_true('appcenter/prudence/docker/%s' % app.id) if app.docker: prevent_docker = False app_version = LooseVersion(app.version) apps = list(reversed(self.get_all_apps_with_id(app.id))) not_permitted_app = None for _app in apps: if prevent_docker and _app.docker and not ( _app.docker_migration_works or _app.docker_migration_link): continue if _app <= app: continue if _app.required_app_version_upgrade: if LooseVersion( _app.required_app_version_upgrade) > app_version: continue if not _app.install_permissions_exist(): # do not consider app without permission... # ... until it is the only one (and then fail eventually...) if not_permitted_app is None: not_permitted_app = _app continue return _app if not_permitted_app: return not_permitted_app
def get_apps(cls): ret = [] apps = Apps().get_all_apps() blacklist = ucr_get('repository/app_center/blacklist') whitelist = ucr_get('repository/app_center/whitelist') if blacklist: blacklist = re.split('\s*,\s*', blacklist) if whitelist: whitelist = re.split('\s*,\s*', whitelist) for app in apps: if blacklist or whitelist: unlocalised_app = app.get_app_cache_obj().copy( locale='en').find_by_component_id(app.component_id) if cls._blacklist_includes_app( blacklist, unlocalised_app) and not cls._blacklist_includes_app( whitelist, unlocalised_app): continue if app.end_of_life and not app.is_installed(): continue if ucr_is_true('ad/member') and app.ad_member_issue_hide: continue if ucr_get('server/role') not in app.server_role: continue if app._docker_prudence_is_true(): _apps = [ _app for _app in Apps().get_all_apps_with_id(app.id) if _app.docker_migration_works or not _app.docker ] try: app = sorted(_apps)[-1] except IndexError: continue ret.append(app) return ret
def create(self, hostname, env): ports = [] for app_id, container_port, host_port, protocol in app_ports_with_protocol(): if app_id == self.app.id: port_definition = '%d:%d/%s' % (host_port, container_port, protocol) ports.append(port_definition) volumes = set(self.app.docker_volumes[:]) for app_volume in [self.app.get_data_dir(), self.app.get_conf_dir()]: app_volume = '%s:%s' % (app_volume, app_volume) volumes.add(app_volume) if self.app.host_certificate_access: cert_dir = '/etc/univention/ssl/%s.%s' % (ucr_get('hostname'), ucr_get('domainname')) cert_volume = '%s:%s:ro' % (cert_dir, cert_dir) volumes.add(cert_volume) volumes.add('/sys/fs/cgroup:/sys/fs/cgroup:ro') # systemd if ucr_is_true('appcenter/docker/container/proxy/settings', default=True): if os.path.isfile('/etc/apt/apt.conf.d/80proxy'): volumes.add('/etc/apt/apt.conf.d/80proxy:/etc/apt/apt.conf.d/80proxy:ro') # apt proxy env_file = self.ucr_filter_env_file(env) command = None if self.app.docker_script_init: command = shlex.split(self.app.docker_script_init) args = shlex.split(ucr_get(self.app.ucr_docker_params_key, '')) for tmpfs in ("/run", "/run/lock"): # systemd args.extend(["--tmpfs", tmpfs]) seccomp_profile = "/etc/docker/seccomp-systemd.json" args.extend(["--security-opt", "seccomp:%s" % seccomp_profile]) # systemd args.extend(["-e", "container=docker"]) # systemd container = create(self.image, command, hostname, ports, volumes, env_file, args) ucr_save({self.app.ucr_container_key: container}) self.container = container return container
def main(self, args): from univention.appcenter.actions import get_action if args.update: get_action('update').call() apps = args.app if not apps: apps = Apps().get_all_locally_installed_apps() for app in apps: self.debug('Checking %s' % app) if not app.is_installed(): continue upgrade_available = self._check_for_upgrades(app) if upgrade_available is True: ucr_save({app.ucr_upgrade_key: 'yes'}) elif upgrade_available is False: ucr_save({app.ucr_upgrade_key: None}) return any(ucr_is_true(app.ucr_upgrade_key) for app in apps)
def find_candidate(self, app, prevent_docker=None): if prevent_docker is None: prevent_docker = ucr_is_true('appcenter/prudence/docker/%s' % app.id) if app.docker: prevent_docker = False app_version = LooseVersion(app.version) apps = list(reversed(self.get_all_apps_with_id(app.id))) for _app in apps: if prevent_docker and _app.docker and not ( _app.docker_migration_works or _app.docker_migration_link): continue if _app <= app: break if _app.required_app_version_upgrade: if LooseVersion( _app.required_app_version_upgrade) > app_version: continue return _app
def sanitize_value(self, app, value): super(BoolSetting, self).sanitize_value(app, value) if isinstance(value, bool): return value return ucr_is_true(self.name, value=value)
def iter_upgradable_apps(self): for app in Apps().get_all_locally_installed_apps(): if ucr_is_true(app.ucr_upgrade_key): yield app
def _start_docker_image(self, app, hostdn, password, args): docker = self._get_docker(app) if not docker: return self.log('Verifying Docker registry manifest for app image %s' % docker.image) docker.verify() if args.pull_image: docker.pull() self.log('Initializing app image') hostname = explode_dn(hostdn, 1)[0] set_vars = (args.set_vars or {}).copy() after_image_configuration = {} for setting in app.get_settings(): if setting.should_go_into_image_configuration(app): if setting.name not in set_vars: set_vars[setting.name] = setting.get_initial_value(app) else: try: after_image_configuration[setting.name] = set_vars.pop( setting.name) except KeyError: after_image_configuration[ setting.name] = setting.get_initial_value(app) set_vars['docker/host/name'] = '%s.%s' % (ucr_get('hostname'), ucr_get('domainname')) set_vars['ldap/hostdn'] = hostdn if app.docker_env_ldap_user: set_vars[app.docker_env_ldap_user] = hostdn set_vars['server/role'] = app.docker_server_role set_vars['update/warning/releasenotes'] = 'no' ucr_keys_list = list(ucr_keys()) for var in [ 'nameserver.*', 'repository/online/server', 'repository/app_center/server', 'update/secure_apt', 'appcenter/index/verify', 'ldap/base', 'ldap/server.*', 'ldap/master.*', 'locale.*', 'domainname' ]: for key in ucr_keys_list: if re.match(var, key): set_vars[key] = ucr_get(key) if ucr_is_true('appcenter/docker/container/proxy/settings', default=True): if ucr_get('proxy/http'): set_vars['proxy/http'] = ucr_get('proxy/http') set_vars['http_proxy'] = ucr_get('proxy/http') if ucr_get('proxy/https'): set_vars['proxy/https'] = ucr_get('proxy/https') set_vars['https_proxy'] = ucr_get('proxy/https') if ucr_get('proxy/no_proxy'): set_vars['proxy/no_proxy'] = ucr_get('proxy/no_proxy') set_vars['no_proxy'] = ucr_get('proxy/no_proxy') set_vars['updater/identify'] = 'Docker App' database_connector = DatabaseConnector.get_connector(app) database_password_file = None if database_connector: try: database_password = database_connector.get_db_password() database_password_file = database_connector.get_db_password_file( ) if database_password: set_vars[ app. docker_env_database_host] = database_connector.get_db_host( ) db_port = database_connector.get_db_port() if db_port: set_vars[app.docker_env_database_port] = db_port set_vars[ app. docker_env_database_name] = database_connector.get_db_name( ) set_vars[ app. docker_env_database_user] = database_connector.get_db_user( ) if app.docker_env_database_password_file: set_vars[ app. docker_env_database_password_file] = database_password_file else: set_vars[ app. docker_env_database_password] = database_password autostart_variable = database_connector.get_autostart_variable( ) if autostart_variable: set_vars[autostart_variable] = 'no' except DatabaseError as exc: raise DatabaseConnectorError(str(exc)) container = docker.create(hostname, set_vars) self.log('Preconfiguring container %s' % container) autostart = 'yes' if not Start.call(app=app): raise DockerCouldNotStartContainer(str(Status.get_status(app))) time.sleep(3) if not docker.is_running(): dlogs = docker.dockerd_logs() clogs = docker.logs() inspect = docker.inspect_container() msg = """ The container for {app} could not be started! docker logs {container}: {clogs} dockerd logs: {dlogs} docker inspect: {state} {graphdriver}""".format(app=app, container=docker.container, clogs=clogs, dlogs=dlogs, state=inspect.get('State'), graphdriver=inspect.get('GraphDriver')) raise AppCenterErrorContainerStart(msg) # copy password files if os.path.isfile(app.secret_on_host): # we can not use docker-cp here, as we support read-only containers too :-( f_name = docker.path('/etc/machine.secret') f_dir = os.path.dirname(f_name) # if the container start takes a little longer the f_dir may not exist yet # so wait max 60s for i in xrange(0, 12): if os.path.isdir(f_dir): break time.sleep(5) try: with open(f_name, 'w+b') as f: os.chmod(f_name, 0o600) f.write(password) except Exception as exc: raise DockerCouldNotStartContainer( 'Could not copy machine.secret to container: %s (%s)' % (str(exc), docker.logs())) if database_password_file: docker.cp_to_container(database_password_file, database_password_file) # update timezone in container logfile_logger = get_logfile_logger('docker.base') docker.execute('rm', '-f', '/etc/timezone', '/etc/localtime', _logger=logfile_logger) docker.cp_to_container('/etc/timezone', '/etc/timezone', _logger=logfile_logger) docker.cp_to_container('/etc/localtime', '/etc/localtime', _logger=logfile_logger) # configure app after_image_configuration.update(set_vars) configure = get_action('configure') configure.call(app=app, autostart=autostart, run_script='no', set_vars=after_image_configuration)
def test_install(self, app): return not app.docker or ucr_is_true('appcenter/docker', True)
if master_version is None: raise KeyError except KeyError: print('App "{}" is not installed on DC master.'.format(app_name)) sys.exit(2) ret = LooseVersion(app.version) > LooseVersion(master_version) if '-v' in sys.argv: print('Version of app "{}" on this host: "{}"'.format( app_name, app.version)) print('Version of app "{}" on DC master: "{}"'.format( app_name, master_version)) if ret: print( 'Error: local version of app "{}" higher than DC masters versions!' .format(app_name)) else: print( 'OK: local version of app "{}" is lower or equal to that of the DC master.' .format(app_name)) ucrv = 'ucsschool/join/ignore-version-mismatch/{}/{}'.format( master_version, app.version) if ucr_is_true(ucrv): if '-v' in sys.argv: print('Ignoring version mismatch, because "{}" is set.'.format(ucrv)) sys.exit(0) sys.exit(int(ret))
def _start_docker_image(self, app, hostdn, password, args): docker = self._get_docker(app) if not docker: return self.log('Verifying Docker registry manifest for app image %s' % docker.image) docker.verify() if args.pull_image: self.log('Downloading app image %s' % docker.image) if not docker.pull(): raise DockerImagePullFailed(docker.image) self.log('Initializing app image') hostname = explode_dn(hostdn, 1)[0] set_vars = (args.set_vars or {}).copy() after_image_configuration = {} for setting in app.get_settings(): if setting.should_go_into_image_configuration(app): if setting.name not in set_vars: set_vars[setting.name] = setting.get_initial_value() else: try: after_image_configuration[setting.name] = set_vars.pop( setting.name) except KeyError: pass set_vars['docker/host/name'] = '%s.%s' % (ucr_get('hostname'), ucr_get('domainname')) set_vars['ldap/hostdn'] = hostdn if app.docker_env_ldap_user: set_vars[app.docker_env_ldap_user] = hostdn set_vars['server/role'] = app.docker_server_role set_vars['update/warning/releasenotes'] = 'no' ucr_keys_list = list(ucr_keys()) for var in [ 'nameserver.*', 'repository/online/server', 'repository/app_center/server', 'update/secure_apt', 'appcenter/index/verify', 'ldap/master.*', 'locale.*', 'domainname' ]: for key in ucr_keys_list: if re.match(var, key): set_vars[key] = ucr_get(key) if ucr_is_true('appcenter/docker/container/proxy/settings', default=True): if ucr_get('proxy/http'): set_vars['proxy/http'] = ucr_get('proxy/http') set_vars['http_proxy'] = ucr_get('proxy/http') if ucr_get('proxy/https'): set_vars['proxy/https'] = ucr_get('proxy/https') set_vars['https_proxy'] = ucr_get('proxy/https') if ucr_get('proxy/no_proxy'): set_vars['proxy/no_proxy'] = ucr_get('proxy/no_proxy') set_vars['no_proxy'] = ucr_get('proxy/no_proxy') set_vars['updater/identify'] = 'Docker App' database_connector = DatabaseConnector.get_connector(app) database_password_file = None if database_connector: try: database_password = database_connector.get_db_password() database_password_file = database_connector.get_db_password_file( ) if database_password: set_vars[ app. docker_env_database_host] = database_connector.get_db_host( ) db_port = database_connector.get_db_port() if db_port: set_vars[app.docker_env_database_port] = db_port set_vars[ app. docker_env_database_name] = database_connector.get_db_name( ) set_vars[ app. docker_env_database_user] = database_connector.get_db_user( ) if app.docker_env_database_password_file: set_vars[ app. docker_env_database_password_file] = database_password_file else: set_vars[ app. docker_env_database_password] = database_password autostart_variable = database_connector.get_autostart_variable( ) if autostart_variable: set_vars[autostart_variable] = 'no' except DatabaseError as exc: raise DatabaseConnectorError(str(exc)) container = docker.create(hostname, set_vars) self.log('Preconfiguring container %s' % container) autostart = 'yes' if not Start.call(app=app): raise DockerCouldNotStartContainer() time.sleep(3) if not docker.is_running(): dlogs = docker.dockerd_logs() clogs = docker.logs() inspect = docker.inspect_container() msg = """ The container for {app} could not be started! docker logs {container}: {clogs} dockerd logs: {dlogs} docker inspect: {state} {graphdriver}""".format(app=app, container=docker.container, clogs='\n'.join(clogs), dlogs='\n'.join(dlogs), state=inspect.get('State'), graphdriver=inspect.get('GraphDriver')) raise AppCenterErrorContainerStart(msg) if password: with open(docker.path('/etc/machine.secret'), 'w+b') as f: f.write(password) docker.cp_to_container('/etc/timezone', '/etc/timezone') docker.cp_to_container('/etc/localtime', '/etc/localtime') if database_password_file: docker.cp_to_container(database_password_file, database_password_file) after_image_configuration.update(set_vars) configure = get_action('configure') configure.call(app=app, autostart=autostart, run_script='no', set_vars=after_image_configuration)