コード例 #1
0
    def _remove_cleanup_app(self, path):
        """Stop and remove a cleanup app.
        """
        name = os.path.basename(path)

        if name.startswith('.'):
            _LOGGER.warning('Ignore %s', name)
            return

        cleaning_link = os.path.join(self.tm_env.cleaning_dir, name)
        app_path = os.path.join(self.tm_env.cleanup_apps_dir, name)

        _LOGGER.info('Removing cleanup app %s -> %s', cleaning_link, app_path)

        if os.path.exists(cleaning_link):
            _LOGGER.debug('Removing cleanup link %s', cleaning_link)
            fs.rm_safe(cleaning_link)
            self._refresh_supervisor()
            _LOGGER.debug('Waiting on %s not being supervised', app_path)
            supervisor.ensure_not_supervised(app_path)
        else:
            _LOGGER.debug('Cleanup link %s does not exist', cleaning_link)

        _LOGGER.debug('Removing app directory %s', app_path)
        fs.rmtree_safe(app_path)
コード例 #2
0
ファイル: kt_split.py プロジェクト: ywong587/treadmill
def validate_as_file(encoded_keytabs, basedir):
    """
    validate keytab by given encoded data

    return keytab files validated
    """
    temp_dir = tempfile.mkdtemp(dir=basedir)
    try:
        for encoded in encoded_keytabs:
            test_file = os.path.join(temp_dir, _NAME)
            keytabs2.write_keytab(
                test_file,
                encoded,
            )

            try:
                subproc.check_call(
                    ['kt_split', '--dir={}'.format(basedir), test_file])
            except subproc.CalledProcessError:
                raise keytabs2.KeytabLockerError(
                    'wrong keytab data: {}'.format(encoded))

        for kt_file in os.listdir(basedir):
            full_path = os.path.join(basedir, kt_file)
            # we ignore temp_dir in basedir
            if os.path.isdir(full_path):
                continue

            yield full_path

    finally:
        fs.rmtree_safe(temp_dir)
コード例 #3
0
    def put(self, rsrc_id, rsrc_data):
        """Request creation/update of a resource.

        :param `str` rsrc_id:
            Unique identifier for the requested resource.
        :param `str` rsrc_data:
            (New) Parameters for the requested resource.
        """
        req_dir = self._req_dirname(rsrc_id)
        fs.mkdir_safe(req_dir)

        with io.open(os.path.join(req_dir, REQ_FILE), 'w') as f:
            if os.name == 'posix':
                os.fchmod(f.fileno(), 0o644)
            yaml.dump(rsrc_data,
                      explicit_start=True,
                      explicit_end=True,
                      default_flow_style=False,
                      stream=f)

        req_uuid_file = os.path.join(req_dir, self._REQ_UID_FILE)
        try:
            with io.open(req_uuid_file) as f:
                svc_req_uuid = f.read().strip()
        except IOError as err:
            if err.errno == errno.ENOENT:
                svc_req_uuid = None
            else:
                raise

        with lc.LogContext(_LOGGER, rsrc_id):
            if svc_req_uuid is None:
                try:
                    # New request
                    svc_req_uuid = self._serviceinst.clt_new_request(
                        rsrc_id, req_dir)
                    # Write down the UUID
                    with io.open(req_uuid_file, 'w') as f:
                        f.write(svc_req_uuid)
                        os.fchmod(f.fileno(), 0o644)

                except OSError:
                    # Error registration failed, delete the request.
                    _LOGGER.exception('Unable to submit request')
                    fs.rmtree_safe(req_dir)

            else:
                self._serviceinst.clt_update_request(svc_req_uuid)
コード例 #4
0
    def start(self):
        """Start watchdog."""
        _LOGGER.info('Setting up kernel watchdog at %s', self.root)

        # set up clean base directory
        fs.rmtree_safe(self.root)
        fs.mkdir_safe(self.root)
        fs.mkdir_safe(self.script_directory)
        fs.mkdir_safe(self.test_directory)

        # set up configuration
        config = _JINJA2_ENV.get_template(
            'kernel-watchdog-conf'
        ).render(
            test_directory=self.test_directory
        )
        with io.open(self.config_file, 'w') as fd:
            fd.write(config)

        # set up custom tests
        for name in self.tests:
            test_script = os.path.join(self.script_directory, name)
            # test script
            with io.open(test_script, 'w') as fd:
                fd.write(self.tests[name])
                os.fchmod(fd.fileno(), 0o755)
            # custom test
            custom_test = _JINJA2_ENV.get_template(
                'kernel-watchdog-test'
            ).render(
                name=name,
                command=test_script,
                reboot=self.reboot_script
            )
            with io.open(
                os.path.join(self.test_directory, name), 'w'
            ) as fd:
                fd.write(custom_test)
                os.fchmod(fd.fileno(), 0o755)

        _LOGGER.info('Starting up kernel watchdog')
        subproc.exec_fghack(self.start_command)
コード例 #5
0
def create_supervision_tree(tm_env, container_dir, root_dir, app,
                            cgroups_path):
    """Creates s6 supervision tree."""
    uniq_name = appcfg.app_unique_name(app)
    ctl_uds = os.path.join(os.sep, 'run', 'tm_ctl')
    tombstone_ctl_uds = os.path.join(ctl_uds, 'tombstone')

    sys_dir = os.path.join(container_dir, 'sys')

    try:
        old_system_services = [
            svc_name for svc_name in os.listdir(sys_dir)
            if (not svc_name.startswith('.')
                and os.path.isdir(os.path.join(sys_dir, svc_name)))
        ]
    except FileNotFoundError:
        old_system_services = []

    new_system_services = [svc_def.name for svc_def in app.system_services]

    for svc_name in set(old_system_services) - set(new_system_services):
        _LOGGER.info('Removing old system service: %s', svc_name)
        fs.rmtree_safe(os.path.join(sys_dir, svc_name))

    sys_scandir = supervisor.create_scan_dir(
        sys_dir,
        finish_timeout=6000,
        wait_cgroups=cgroups_path,
    )
    for svc_def in app.system_services:
        if svc_def.restart is not None:
            monitor_policy = {
                'limit': svc_def.restart.limit,
                'interval': svc_def.restart.interval,
                'tombstone': {
                    'uds': False,
                    'path': tm_env.services_tombstone_dir,
                    'id': '{},{}'.format(uniq_name, svc_def.name)
                }
            }
        else:
            monitor_policy = None

        supervisor.create_service(
            sys_scandir,
            name=svc_def.name,
            app_run_script=svc_def.command,
            userid='root',
            environ_dir=os.path.join(container_dir, _CONTAINER_ENV_DIR),
            environ={envvar.name: envvar.value
                     for envvar in svc_def.environ},
            environment=app.environment,
            downed=svc_def.downed,
            trace=None,
            monitor_policy=monitor_policy)
    sys_scandir.write()

    services_dir = os.path.join(container_dir, 'services')
    services_scandir = supervisor.create_scan_dir(services_dir,
                                                  finish_timeout=5000)

    for svc_def in app.services:

        if svc_def.restart is not None:
            monitor_policy = {
                'limit': svc_def.restart.limit,
                'interval': svc_def.restart.interval,
                'tombstone': {
                    'uds': True,
                    'path': tombstone_ctl_uds,
                    'id': '{},{}'.format(uniq_name, svc_def.name)
                }
            }
        else:
            monitor_policy = None

        if svc_def.trace is not None:
            trace = {
                'instanceid': app.name,
                'uniqueid': app.uniqueid,
                'service': svc_def.name,
                'path': os.path.join(ctl_uds, 'appevents')
            }
        else:
            trace = None

        logger_template = getattr(svc_def, 'logger', 's6.app-logger.run')
        _LOGGER.info('Using logger: %s', logger_template)

        supervisor.create_service(
            services_scandir,
            name=svc_def.name,
            app_run_script=svc_def.command,
            userid=svc_def.proid,
            environ_dir='/' + _CONTAINER_ENV_DIR,
            environ={envvar.name: envvar.value
                     for envvar in svc_def.environ},
            environment=app.environment,
            downed=svc_def.downed,
            trace=trace if svc_def.trace else None,
            log_run_script=logger_template,
            monitor_policy=monitor_policy)
    services_scandir.write()

    # Bind the service directory in the container volume
    fs.mkdir_safe(os.path.join(root_dir, 'services'))
    fs_linux.mount_bind(root_dir,
                        os.path.join(os.sep, 'services'),
                        source=os.path.join(container_dir, 'services'),
                        recursive=False,
                        read_only=False)

    # Bind the ctrl directory in the container volume which has all the
    # unix domain sockets to communicate outside the container to treadmill
    fs.mkdir_safe(os.path.join(root_dir, 'run', 'tm_ctl'))
    fs_linux.mount_bind(root_dir,
                        os.path.join(os.sep, 'run', 'tm_ctl'),
                        source=tm_env.ctl_dir,
                        recursive=False,
                        read_only=False)
コード例 #6
0
ファイル: _base_service.py プロジェクト: ywong587/treadmill
    def _on_created(self, impl, filepath):
        """Private handler for request creation events.
        """
        # Avoid triggering on changes to the service directory itself.
        if filepath == self._rsrc_dir:
            return False

        req_id = os.path.basename(filepath)

        # Avoid triggerring on temporary files
        if req_id[0] == '.':
            return False

        req_file = os.path.join(filepath, REQ_FILE)
        rep_file = os.path.join(filepath, REP_FILE)

        try:
            with io.open(req_file) as f:
                req_data = yaml.load(stream=f)

        except IOError as err:
            if (err.errno == errno.ENOENT or
                    err.errno == errno.ENOTDIR):
                _LOGGER.exception('Removing invalid request: %r', req_id)
                try:
                    fs.rm_safe(filepath)
                except OSError as rm_err:
                    if rm_err.errno == errno.EISDIR:
                        fs.rmtree_safe(filepath)
                    else:
                        raise
                return False
            raise

        # TODO: We should also validate the req_id format
        with lc.LogContext(_LOGGER, req_id,
                           adapter_cls=lc.ContainerAdapter) as log:

            log.debug('created %r: %r', req_id, req_data)

            try:
                # TODO: We should also validate the req_id format
                utils.validate(req_data, impl.PAYLOAD_SCHEMA)
                res = impl.on_create_request(req_id, req_data)

            except exc.InvalidInputError as err:
                log.error('Invalid request data: %r: %s', req_data, err)
                res = {'_error': {'input': req_data, 'why': str(err)}}

            except Exception as err:  # pylint: disable=W0703
                log.exception('Unable to process request: %r %r:',
                              req_id, req_data)
                res = {'_error': {'input': req_data, 'why': str(err)}}

        if res is None:
            # Request was not actioned
            return False

        fs.write_safe(
            rep_file,
            lambda f: yaml.dump(
                res, explicit_start=True, explicit_end=True,
                default_flow_style=False, stream=f
            ),
            mode='w',
            permission=0o644
        )

        # Return True if there were no error
        return not bool(res.get('_error', False))