Exemplo n.º 1
0
    def __exit__(self, *args, **kwargs):
        try:
            inflight = sys.exc_info()

            for worker in self.workers:
                if worker.is_alive():
                    worker.terminate()

            with Timeout(seconds=self.grace_period):
                try:
                    while self._started:
                        self.queue.receive()(self)
                except Exception:
                    if inflight[1]:
                        log.critical(
                            'Some workers failed to gracefully shut down, but in-flight exception taking precedence'
                        )
                        reraise(*inflight)
                    raise self.Exception(
                        'Some workers failed to gracefully shut down')

        finally:
            for worker in self.workers:
                if not worker.is_alive():
                    continue

                if sys.version_info >= (3, 7):
                    worker.kill()
                elif hasattr(signal, 'SIGKILL'):
                    os.kill(worker.pid, signal.SIGKILL)
                else:
                    worker.terminate()
Exemplo n.º 2
0
 def handler(signum, frame):
     assert signum == signal.SIGALRM
     if current.thread_id != threading.current_thread().ident:
         log.critical('Using both alarms and threading in the same process, this is unsupported')
         raise ValueError('Timeout originates from a different thread')
     current.triggered = True
     Timeout.bind()
     current.handler(signum, frame)
Exemplo n.º 3
0
    def __call__(self, caller):
        _, exception, trace = sys.exc_info()
        if exception:
            log.critical("Exception in flight, '{}' ignored".format(
                self.exc_info[1]))
            return

        reraise(*self.exc_info)
Exemplo n.º 4
0
 def current(cls):
     for element in cls._process_to_timeout_map[os.getpid()]:
         if element.triggered:
             continue
         if element.thread_id != threading.current_thread().ident:
             log.critical('Using both alarms and threading in the same process, this is unsupported')
             raise ValueError('Timeout originates from a different thread')
         return element
     return None
Exemplo n.º 5
0
    def send_signal(self, sig):
        if self.returncode is not None:
            return

        if sig not in [signal.SIGTERM, signal.SIGKILL]:
            raise ValueError(
                'Mock Popen object cannot handle signal {}'.format(sig))
        log.critical('Mock process {} send signal {}'.format(self.pid, sig))
        self.returncode = -1
Exemplo n.º 6
0
    def __exit__(self, *args, **kwargs):
        if not self.queue:
            TaskPool.Process.working = False
            try:
                if self._teardown_args[0]:
                    self._teardown_args[0](*self._teardown_args[1],
                                           **self._teardown_args[2])
            finally:
                TaskPool.Process.queue = None
                TaskPool.Process.name = None
            return

        from six import reraise
        try:
            inflight = sys.exc_info()

            for worker in self.workers:
                if worker.is_alive():
                    worker.terminate()

            with Timeout(seconds=self.grace_period):
                try:
                    while self._started:
                        self.queue.receive()(self)
                except Exception:
                    if inflight[1]:
                        log.critical(
                            'Some workers failed to gracefully shut down, but in-flight exception taking precedence'
                        )
                        reraise(*inflight)
                    raise self.Exception(
                        'Some workers failed to gracefully shut down')

        finally:
            for worker in self.workers:
                if not worker.is_alive():
                    continue

                if sys.version_info >= (3, 7):
                    worker.kill()
                elif hasattr(signal, 'SIGKILL'):
                    try:
                        os.kill(worker.pid, signal.SIGKILL)
                    except OSError as e:
                        log.warn('Failed to terminate worker ' +
                                 str(worker.pid) + ' with error ' + str(e))
                else:
                    worker.terminate()

            self.queue.close()
            self.queue = None
            self.workers = []
Exemplo n.º 7
0
    def install(self):
        AutoInstall.register(self)
        if self.is_cached():
            return

        # Make sure that setuptools are installed, since setup.py relies on it
        if self.name != 'setuptools':
            AutoInstall.install('setuptools')

        if not self.archives():
            raise ValueError('No archives for {}-{} found'.format(
                self.pypi_name, self.version))
        archive = self.archives()[-1]

        try:
            install_location = os.path.dirname(self.location)
            shutil.rmtree(self.location, ignore_errors=True)

            log.warning('Installing {}...'.format(archive))
            archive.download()

            temp_location = os.path.join(tempfile.gettempdir(), self.name)
            archive.unpack(temp_location)

            for candidate in [
                    os.path.join(temp_location, str(archive)),
                    os.path.join(
                        temp_location,
                        '{}-{}.{}'.format(archive.name, archive.version.major,
                                          archive.version.minor)),
                    os.path.join(
                        temp_location,
                        '{}-{}.{}.{}'.format(archive.name.replace('-', '_'),
                                             archive.version.major,
                                             archive.version.minor,
                                             archive.version.tiny)),
                    os.path.join(
                        temp_location,
                        '{}-{}'.format(archive.name.capitalize(),
                                       archive.version)),
            ]:
                if not os.path.exists(os.path.join(candidate, 'setup.py')):
                    continue

                log.warning('Installing {}...'.format(archive))

                if self.slow_install:
                    log.warning(
                        '{} is known to be slow to install'.format(archive))

                with open(os.devnull, 'w') as devnull:
                    subprocess.check_call(
                        [
                            sys.executable,
                            os.path.join(candidate, 'setup.py'),
                            'install',
                            '--home={}'.format(install_location),
                            '--root=/',
                            '--single-version-externally-managed',
                            '--install-lib={}'.format(install_location),
                            '--install-scripts={}'.format(
                                os.path.join(install_location, 'bin')),
                            '--install-data={}'.format(
                                os.path.join(install_location, 'data')),
                            '--install-headers={}'.format(
                                os.path.join(install_location, 'headers')),
                            # Do not automatically install package dependencies, force scripts to be explicit
                            # Even without this flag, setup.py is not consistent about installing dependencies.
                            '--old-and-unmanageable',
                        ],
                        cwd=candidate,
                        env=dict(
                            PATH=os.environ.get('PATH', ''),
                            PATHEXT=os.environ.get('PATHEXT', ''),
                            PYTHONPATH=install_location,
                            SYSTEMROOT=os.environ.get('SYSTEMROOT', ''),
                        ),
                        stdout=devnull,
                        stderr=devnull,
                    )

                break
            else:
                # We might not need setup.py at all, check if we have dist-info and the library in the temporary location
                to_be_moved = os.listdir(temp_location)
                if self.name not in to_be_moved and any(
                        element.endswith('.dist-info')
                        for element in to_be_moved):
                    raise OSError(
                        'Cannot install {}, could not find setup.py'.format(
                            self.name))
                for directory in to_be_moved:
                    shutil.rmtree(os.path.join(install_location, directory),
                                  ignore_errors=True)
                    shutil.move(os.path.join(temp_location, directory),
                                install_location)

            self.do_post_install(temp_location)

            os.remove(archive.path)
            shutil.rmtree(temp_location, ignore_errors=True)

            AutoInstall.userspace_should_own(install_location)

            AutoInstall.manifest[self.name] = {
                'index': AutoInstall.index,
                'version': str(archive.version),
            }

            manifest = os.path.join(AutoInstall.directory, 'manifest.json')
            with open(manifest, 'w') as file:
                json.dump(AutoInstall.manifest, file, indent=4)
            AutoInstall.userspace_should_own(manifest)

            log.warning('Installed {}!'.format(archive))
        except Exception:
            log.critical('Failed to install {}!'.format(archive))
            raise