def setup_graph(
     bootstrap_options: OptionValueContainer,
     build_configuration: BuildConfiguration,
     dynamic_remote_options: DynamicRemoteOptions,
     executor: PyExecutor | None = None,
 ) -> GraphScheduler:
     build_root = get_buildroot()
     executor = executor or GlobalOptions.create_py_executor(
         bootstrap_options)
     execution_options = ExecutionOptions.from_options(
         bootstrap_options, dynamic_remote_options)
     local_store_options = LocalStoreOptions.from_options(bootstrap_options)
     return EngineInitializer.setup_graph_extended(
         build_configuration,
         execution_options,
         executor=executor,
         pants_ignore_patterns=GlobalOptions.compute_pants_ignore(
             build_root, bootstrap_options),
         use_gitignore=bootstrap_options.pants_ignore_use_gitignore,
         local_store_options=local_store_options,
         local_execution_root_dir=bootstrap_options.
         local_execution_root_dir,
         named_caches_dir=bootstrap_options.named_caches_dir,
         ca_certs_path=bootstrap_options.ca_certs_path,
         build_root=build_root,
         include_trace_on_error=bootstrap_options.print_stacktrace,
         engine_visualize_to=bootstrap_options.engine_visualize_to,
         watch_filesystem=bootstrap_options.watch_filesystem,
         use_deprecated_python_macros=bootstrap_options.
         use_deprecated_python_macros,
     )
Beispiel #2
0
    def create(cls, options_bootstrapper: OptionsBootstrapper,
               env: CompleteEnvironment) -> PantsDaemon:
        # Any warnings that would be triggered here are re-triggered later per-run of Pants, so we
        # silence them.
        with warnings.catch_warnings(record=True):
            bootstrap_options = options_bootstrapper.bootstrap_options
            bootstrap_options_values = bootstrap_options.for_global_scope()

        executor = GlobalOptions.create_py_executor(bootstrap_options_values)
        core = PantsDaemonCore(options_bootstrapper, env, executor,
                               cls._setup_services)

        server = native_engine.nailgun_server_create(
            executor,
            bootstrap_options_values.pantsd_pailgun_port,
            DaemonPantsRunner(core),
        )

        return PantsDaemon(
            work_dir=bootstrap_options_values.pants_workdir,
            log_level=bootstrap_options_values.level,
            server=server,
            core=core,
            metadata_base_dir=bootstrap_options_values.pants_subprocessdir,
            bootstrap_options=bootstrap_options,
        )
Beispiel #3
0
 def setup_graph(
     options_bootstrapper: OptionsBootstrapper,
     build_configuration: BuildConfiguration,
     env: CompleteEnvironment,
     executor: Optional[PyExecutor] = None,
     local_only: bool = False,
 ) -> GraphScheduler:
     build_root = get_buildroot()
     bootstrap_options = options_bootstrapper.bootstrap_options.for_global_scope()
     options = options_bootstrapper.full_options(build_configuration)
     assert bootstrap_options is not None
     executor = executor or GlobalOptions.create_py_executor(bootstrap_options)
     execution_options = ExecutionOptions.from_options(options, env, local_only=local_only)
     return EngineInitializer.setup_graph_extended(
         build_configuration,
         execution_options,
         executor=executor,
         pants_ignore_patterns=GlobalOptions.compute_pants_ignore(build_root, bootstrap_options),
         use_gitignore=bootstrap_options.pants_ignore_use_gitignore,
         local_store_dir=bootstrap_options.local_store_dir,
         local_execution_root_dir=bootstrap_options.local_execution_root_dir,
         named_caches_dir=bootstrap_options.named_caches_dir,
         ca_certs_path=bootstrap_options.ca_certs_path,
         build_root=build_root,
         include_trace_on_error=bootstrap_options.print_stacktrace,
         native_engine_visualize_to=bootstrap_options.native_engine_visualize_to,
     )
Beispiel #4
0
    def _connect_and_execute(
            self, pantsd_handle: PantsDaemonClient.Handle) -> ExitCode:
        global_options = self._bootstrap_options.for_global_scope()
        executor = GlobalOptions.create_py_executor(global_options)

        # Merge the nailgun TTY capability environment variables with the passed environment dict.
        ng_env = NailgunProtocol.ttynames_to_env(sys.stdin, sys.stdout,
                                                 sys.stderr)
        modified_env = {
            **self._env,
            **ng_env,
            "PANTSD_RUNTRACKER_CLIENT_START_TIME":
            str(self._start_time),
            "PANTSD_REQUEST_TIMEOUT_LIMIT":
            str(global_options.pantsd_timeout_when_multiple_invocations),
        }

        command = self._args[0]
        args = self._args[1:]

        retries = 3
        attempt = 1
        while True:
            port = pantsd_handle.port
            logger.debug(
                f"Connecting to pantsd on port {port} attempt {attempt}/{retries}"
            )

            # We preserve TTY settings since the server might write directly to the TTY, and we'd like
            # to clean up any side effects before exiting.
            #
            # We ignore keyboard interrupts because the nailgun client will handle them.
            with STTYSettings.preserved(), interrupts_ignored():
                try:
                    return native_engine.nailgun_client_create(
                        executor, port).execute(command, args, modified_env)

                # NailgunConnectionException represents a failure connecting to pantsd, so we retry
                # up to the retry limit.
                except NailgunConnectionException as e:
                    if attempt > retries:
                        raise self.Fallback(e)

                    # Wait one second before retrying
                    logger.warning(
                        f"Pantsd was unresponsive on port {port}, retrying.")
                    time.sleep(1)

                    # One possible cause of the daemon being non-responsive during an attempt might be if a
                    # another lifecycle operation is happening concurrently (incl teardown). To account for
                    # this, we won't begin attempting restarts until at least 1 attempt has passed.
                    if attempt > 1:
                        pantsd_handle = self._client.restart()

                    attempt += 1