Ejemplo n.º 1
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 _set_config_via_tool(self, app, set_vars):
     if not app.docker:
         return super(Configure, self)._set_config_via_tool(app, set_vars)
     if not app_is_running(app):
         self.warn('Cannot write settings while %s is not running' % app)
         return
     logfile_logger = get_logfile_logger('docker.configure')
     docker = self._get_docker(app)
     if not docker.execute('which', 'ucr',
                           _logger=logfile_logger).returncode == 0:
         self.warn(
             'ucr cannot be found, falling back to changing the database file directly'
         )
         self._set_config_directly(app, set_vars)
         return
     self.log('Setting registry variables for %s' % app.id)
     set_args = []
     unset_args = []
     for key, value in set_vars.items():
         if value is None:
             unset_args.append(key)
         else:
             set_args.append('%s=%s' % (key, value))
     if set_args:
         docker.execute('ucr', 'set', *set_args, _logger=logfile_logger)
     if unset_args:
         docker.execute('ucr', 'unset', *unset_args, _logger=logfile_logger)
Ejemplo n.º 3
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 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
    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)