def _unregister_app(self, app, args, lo=None, pos=None, delay=False):
		if lo is None:
			lo, pos = self._get_ldap_connection(args, allow_machine_connection=True)
		updates = {}
		for key in ucr_keys():
			if key.startswith('appcenter/apps/%s/' % app.id):
				updates[key] = None
			if re.match('ucs/web/overview/entries/[^/]+/%s/' % app.id, key):
				updates[key] = None
			if re.match('appreport/%s/' % app.id, key):
				updates[key] = None
		if app.docker and not app.plugin_of:
			try:
				from univention.appcenter.actions.service import Service
			except ImportError:
				# univention-appcenter-docker is not installed
				pass
			else:
				try:
					init_script = Service.get_init(app)
					os.unlink(init_script)
					self._call_script('/usr/sbin/update-rc.d', os.path.basename(init_script), 'remove')
				except OSError:
					pass
		ldap_object = get_app_ldap_object(app, lo, pos)
		if ldap_object:
			self.log('Removing localhost from LDAP object')
			ldap_object.remove_localhost()
		if not delay:
			ucr_save(updates)
			self._reload_apache()
		return updates
	def _unregister_component_dict(self, app):
		ret = {}
		ucr_base_key = app.ucr_component_key
		for key in ucr_keys():
			if key == ucr_base_key or key.startswith('%s/' % ucr_base_key):
				self.debug('Removing %s' % key)
				ret[key] = None
		return ret
示例#3
0
    def _register_overview_variables(self, app):
        updates = {}
        if app.ucs_overview_category is not False:
            for key in ucr_keys():
                if re.match('ucs/web/overview/entries/[^/]+/%s/' % app.id,
                            key):
                    updates[key] = None
        if app.ucs_overview_category and app.web_interface:
            self.log('Setting overview variables')
            registry_key = 'ucs/web/overview/entries/%s/%s/%%s' % (
                app.ucs_overview_category, app.id)
            port_http = app.web_interface_port_http
            port_https = app.web_interface_port_https
            if app.auto_mod_proxy:
                # the port in the ini is not the "public" port!
                # the web interface lives behind our apache with its
                # default ports. but we need to respect disabled ports
                port_http = 80
                port_https = 443
                if app.web_interface_port_http == 0:
                    port_http = None
                if app.web_interface_port_https == 0:
                    port_https = None

            label = app.get_localised(
                'web_interface_name') or app.get_localised('name')
            label_de = app.get_localised(
                'web_interface_name', 'de') or app.get_localised('name', 'de')
            variables = {
                'icon':
                os.path.join('/univention/js/dijit/themes/umc/icons/scalable',
                             app.logo_name),
                'port_http':
                str(port_http or ''),
                'port_https':
                str(port_https or ''),
                'label':
                label,
                'label/de':
                label_de,
                'description':
                app.get_localised('description'),
                'description/de':
                app.get_localised('description', 'de'),
                'link':
                app.web_interface,
                'background-color':
                app.background_color,
            }
            if app.web_interface_link_target != 'useportaldefault':
                variables['link-target'] = app.web_interface_link_target
            for key, value in variables.items():
                updates[registry_key % key] = value
        return updates
示例#4
0
def app_ports():
	'''Returns a list for ports of an App:
	[(app_id, container_port, host_port), ...]'''
	ret = []
	for key in ucr_keys():
		match = re.match(r'^appcenter/apps/(.*)/ports/(\d*)', key)
		if match:
			try:
				ret.append((match.groups()[0], int(match.groups()[1]), int(ucr_get(key))))
			except ValueError:
				pass
	return sorted(ret)
	def _register_app_report_variables(self, app):
		updates = {}
		for key in ucr_keys():
			if re.match('appreport/%s/' % app.id, key):
				updates[key] = None
		registry_key = 'appreport/%s/%%s' % app.id
		anything_set = False
		for key in ['object_type', 'object_filter', 'object_attribute', 'attribute_type', 'attribute_filter']:
			value = getattr(app, 'app_report_%s' % key)
			if value:
				anything_set = True
			updates[registry_key % key] = value
		if anything_set:
			updates[registry_key % 'report'] = 'yes'
		return updates
    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 _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)