plainbox.impl.ctrl – Controller Classes

Session controller classes implement the glue between models (jobs, whitelists, session state) and the rest of the application. They encapsulate knowledge that used to be special-cased and sprinkled around various parts of both plainbox and particular plainbox-using applications.

Execution controllers are used by the JobRunner class to select the best method to execute a command of a particular job. This is mostly applicable to jobs that need to run as another user, typically as root, as the method that is used to effectively gain root differs depending on circumstances.

class plainbox.impl.ctrl.CheckBoxSessionStateController[source]

Bases: plainbox.abc.ISessionStateController

A combo controller for CheckBox-like jobs.

This controller implements the following features:

  • A job may depend on another job, this is expressed via the ‘depends’ attribute. Cyclic dependencies are not allowed. A job will become inhibited if any of its dependencies have outcome other than OUTCOME_PASS
  • A job may require that a particular resource expression evaluates to true. This is expressed via the ‘requires’ attribute. A job will become inhibited if any of the requirement programs evaluates to value other than True.
  • A job may have the attribute ‘plugin’ equal to “local” which will cause the controller to interpret the stdout of the command as a set of job definitions.
  • A job may have the attribute ‘plugin’ equal to “resource” which will cause the controller to interpret the stdout of the command as a set of resource definitions.
get_dependency_set(job)[source]

Get the set of direct dependencies of a particular job.

Parameters:job – A IJobDefinition instance that is to be visited
Returns:set of pairs (dep_type, job_id)

Returns a set of pairs (dep_type, job_id) that describe all dependencies of the specified job. The first element in the pair, dep_type, is either DEP_TYPE_DIRECT, DEP_TYPE_ORDERING or DEP_TYPE_RESOURCE. The second element is the id of the job.

get_inhibitor_list(session_state, job)[source]

Get a list of readiness inhibitors that inhibit a particular job.

Parameters:
  • session_state – A SessionState instance that is used to interrogate the state of the session where it matters for a particular job. Currently this is used to access resources and job results.
  • job – A JobDefinition instance
Returns:

List of JobReadinessInhibitor

observe_result(session_state, job, result)[source]

Notice the specified test result and update readiness state.

Parameters:
  • session_state – A SessionState object
  • job – A JobDefinition object
  • result – A IJobResult object

This function updates the internal result collection with the data from the specified test result. Results can safely override older results. Results also change the ready map (jobs that can run) because of dependency relations.

Some results have deeper meaning, those are results for local and resource jobs. They are discussed in detail below:

Resource jobs produce resource records which are used as data to run requirement expressions against. Each time a result for a resource job is presented to the session it will be parsed as a collection of RFC822 records. A new entry is created in the resource map (entirely replacing any old entries), with a list of the resources that were parsed from the IO log.

Local jobs produce more jobs. Like with resource jobs, their IO log is parsed and interpreted as additional jobs. Unlike in resource jobs local jobs don’t replace anything. They cannot replace an existing job with the same id.

class plainbox.impl.ctrl.RootViaPTL1ExecutionController(provider_list)[source]

Bases: plainbox.impl.ctrl.CheckBoxDifferentialExecutionController

Execution controller that gains root using plainbox-trusted-launcher-1

configured_filesystem(job, config)

Context manager for handling filesystem aspects of job execution.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the executable symlink nest directory.

execute_job(job, job_state, config, session_dir, extcmd_popen)

Execute the specified job using the specified subprocess-like object

Parameters:
  • job – The JobDefinition to execute
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • extcmd_popen – A subprocess.Popen like object
Returns:

The return code of the command, as returned by subprocess.call()

get_CHECKBOX_DATA(session_dir)

value of the CHECKBOX_DATA environment variable.

This variable names a sub-directory of the session directory where jobs can share data between invocations.

get_checkbox_score(job)[source]

Compute how applicable this controller is for the specified job.

Returns:two for jobs with an user override that can be invoked by the trusted launcher, zero for jobs without an user override that can be invoked by the trusted launcher, -1 otherwise
get_differential_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. This is simply passed to get_execution_environment() directly.
Returns:

Differential environment (see below).

This implementation computes the desired environment (as it was computed in the base class) and then discards all of the environment variables that are identical in both sets. The exception are variables that are mentioned in plainbox.impl.job.JobDefinition.get_environ_settings() which are always retained.

get_execution_command(job, job_state, config, session_dir, nest_dir)[source]

Get the command to invoke.

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Passed to get_differential_execution_environment().
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Passed to get_differential_execution_environment().

This overridden implementation returns especially crafted command that uses pkexec to run the plainbox-trusted-launcher-1 as the desired user (typically root). It passes the checksum of the job definition as argument, along with all of the required environment key-value pairs. If a job is generated it also passes the special via attribute to let the trusted launcher discover the generated job. Currently it supports at most one-level of generated jobs.

get_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions. Ignored.
  • job_state – The JobState associated to the job to execute. Ignored.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Ignored.
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions. Ignored.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Ignored.
Returns:

None

This implementation always returns None since the environment is always passed in via get_execution_command()

get_score(job)

Compute how applicable this controller is for the specified job.

Returns:A numeric score, or None if the controller cannot run this job. The higher the value, the more applicable this controller is.
get_warm_up_for_job(job)[source]

Get a warm-up function that should be called before running this job.

Returns:a warm-up function for jobs that need to run as another user or None if the job can run as the current user.
on_leftover_files

Basic signal that supports arbitrary listeners.

While this class can be used directly it is best used with the helper decorator Signal.define on a function or method. See the documentation for the plainbox.vendor.morris module for details.

Attr _name:Name of the signal, typically accessed via name().
Attr _listeners:
 List of signal listeners. Each item is a tuple (listener, pass_signal) that encodes how to call the listener.
temporary_cwd(job, config)

Context manager for handling temporary current working directory for a particular execution of a job definition command.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the new temporary directory

class plainbox.impl.ctrl.RootViaPkexecExecutionController(provider_list)[source]

Bases: plainbox.impl.ctrl.CheckBoxDifferentialExecutionController

Execution controller that gains root by using pkexec.

This controller should be used for jobs that need root but cannot be executed by the plainbox-trusted-launcher-1. This happens whenever the job is not in the system-wide provider location.

In practice it is used when working with the special ‘checkbox-in-source-tree’ provider as well as for jobs that need to run as root from the non-system-wide location.

configured_filesystem(job, config)

Context manager for handling filesystem aspects of job execution.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the executable symlink nest directory.

execute_job(job, job_state, config, session_dir, extcmd_popen)

Execute the specified job using the specified subprocess-like object

Parameters:
  • job – The JobDefinition to execute
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • extcmd_popen – A subprocess.Popen like object
Returns:

The return code of the command, as returned by subprocess.call()

get_CHECKBOX_DATA(session_dir)

value of the CHECKBOX_DATA environment variable.

This variable names a sub-directory of the session directory where jobs can share data between invocations.

get_checkbox_score(job)[source]

Compute how applicable this controller is for the specified job.

Returns:one for jobs with a user override, zero otherwise
get_differential_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. This is simply passed to get_execution_environment() directly.
Returns:

Differential environment (see below).

This implementation computes the desired environment (as it was computed in the base class) and then discards all of the environment variables that are identical in both sets. The exception are variables that are mentioned in plainbox.impl.job.JobDefinition.get_environ_settings() which are always retained.

get_execution_command(job, job_state, config, session_dir, nest_dir)[source]

Get the command to invoke.

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Passed to get_differential_execution_environment().
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Passed to get_differential_execution_environment().

Since we cannot pass environment in the ordinary way while using pkexec(1) (pkexec starts new processes in a sanitized, pristine, environment) we’re relying on env(1) to pass some of the environment variables that we require.

get_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions. Ignored.
  • job_state – The JobState associated to the job to execute. Ignored.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Ignored.
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions. Ignored.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Ignored.
Returns:

None

This implementation always returns None since the environment is always passed in via get_execution_command()

get_score(job)

Compute how applicable this controller is for the specified job.

Returns:A numeric score, or None if the controller cannot run this job. The higher the value, the more applicable this controller is.
get_warm_up_for_job(job)

Get a warm-up function that should be called before running this job.

Returns:None
on_leftover_files

Basic signal that supports arbitrary listeners.

While this class can be used directly it is best used with the helper decorator Signal.define on a function or method. See the documentation for the plainbox.vendor.morris module for details.

Attr _name:Name of the signal, typically accessed via name().
Attr _listeners:
 List of signal listeners. Each item is a tuple (listener, pass_signal) that encodes how to call the listener.
temporary_cwd(job, config)

Context manager for handling temporary current working directory for a particular execution of a job definition command.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the new temporary directory

class plainbox.impl.ctrl.RootViaSudoExecutionController(provider_list)[source]

Bases: plainbox.impl.ctrl.CheckBoxDifferentialExecutionController

Execution controller that gains root by using sudo.

This controller should be used for jobs that need root but cannot be executed by the plainbox-trusted-launcher-1.

This happens whenever the job is not in the system-wide provider location. In practice it is used when working with the special ‘checkbox-in-source-tree’ provider as well as for jobs that need to run as root from the non-system-wide location.

Using this controller is preferable to pkexec if running on command line as unlike pkexec, it retains ‘memory’ and doesn’t ask for the password over and over again.

configured_filesystem(job, config)

Context manager for handling filesystem aspects of job execution.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the executable symlink nest directory.

execute_job(job, job_state, config, session_dir, extcmd_popen)

Execute the specified job using the specified subprocess-like object

Parameters:
  • job – The JobDefinition to execute
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • extcmd_popen – A subprocess.Popen like object
Returns:

The return code of the command, as returned by subprocess.call()

get_CHECKBOX_DATA(session_dir)

value of the CHECKBOX_DATA environment variable.

This variable names a sub-directory of the session directory where jobs can share data between invocations.

get_checkbox_score(job)[source]

Compute how applicable this controller is for the specified job.

Returns:-1 if the job does not have a user override or the user cannot use sudo and 2 otherwise
get_differential_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. This is simply passed to get_execution_environment() directly.
Returns:

Differential environment (see below).

This implementation computes the desired environment (as it was computed in the base class) and then discards all of the environment variables that are identical in both sets. The exception are variables that are mentioned in plainbox.impl.job.JobDefinition.get_environ_settings() which are always retained.

get_execution_command(job, job_state, config, session_dir, nest_dir)[source]

Get the command to invoke.

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Ignored.
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Ingored.

Since we cannot pass environment in the ordinary way while using sudo(8) (even passing -E doesn’t get us everything due to security features built into sudo itself) we’re relying on env(1) to pass some of the environment variables that we require.

get_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions. Ignored.
  • job_state – The JobState associated to the job to execute. Ignored.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Ignored.
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions. Ignored.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Ignored.
Returns:

None

This implementation always returns None since the environment is always passed in via get_execution_command()

get_score(job)

Compute how applicable this controller is for the specified job.

Returns:A numeric score, or None if the controller cannot run this job. The higher the value, the more applicable this controller is.
get_warm_up_for_job(job)[source]

Get a warm-up function that should be called before running this job.

Returns:A callable to do the warm-up
on_leftover_files

Basic signal that supports arbitrary listeners.

While this class can be used directly it is best used with the helper decorator Signal.define on a function or method. See the documentation for the plainbox.vendor.morris module for details.

Attr _name:Name of the signal, typically accessed via name().
Attr _listeners:
 List of signal listeners. Each item is a tuple (listener, pass_signal) that encodes how to call the listener.
temporary_cwd(job, config)

Context manager for handling temporary current working directory for a particular execution of a job definition command.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the new temporary directory

class plainbox.impl.ctrl.UserJobExecutionController(provider_list)[source]

Bases: plainbox.impl.ctrl.CheckBoxExecutionController

An execution controller that works for jobs invoked as the current user.

configured_filesystem(job, config)

Context manager for handling filesystem aspects of job execution.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the executable symlink nest directory.

execute_job(job, job_state, config, session_dir, extcmd_popen)

Execute the specified job using the specified subprocess-like object

Parameters:
  • job – The JobDefinition to execute
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • extcmd_popen – A subprocess.Popen like object
Returns:

The return code of the command, as returned by subprocess.call()

get_CHECKBOX_DATA(session_dir)

value of the CHECKBOX_DATA environment variable.

This variable names a sub-directory of the session directory where jobs can share data between invocations.

get_checkbox_score(job)[source]

Compute how applicable this controller is for the specified job.

Returns:1 for jobs without a user override, 4 for jobs with user override if the invoking uid is 0 (root), -1 otherwise
get_execution_command(job, job_state, config, session_dir, nest_dir)[source]

Get the command to execute the specified job

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. Ignored.
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions. Ignored.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. Ingored.
Returns:

List of command arguments

The return value depends on the flags that a job carries. Since plainbox has originated in a Linux environment where the default shell is a POSIX-y shell (bash or dash) and that’s what all existing jobs assume, unless running on windows, this method returns:

[job.shell, '-c', job.command]

When the system is running windows, the job must have the ‘win32’ flag set (or it won’t be possible to run it as get_checkbox_score() will be -1). In that case a windows-specific command is used:

['cmd.exe', '/C', job.command]
get_execution_environment(job, job_state, config, session_dir, nest_dir)

Get the environment required to execute the specified job:

Parameters:
  • job – job definition with the command and environment definitions
  • job_state – The JobState associated to the job to execute.
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
  • session_dir – Base directory of the session this job will execute in. This directory is used to co-locate some data that is unique to this execution as well as data that is shared by all executions.
  • nest_dir – A directory with a nest of symlinks to all executables required to execute the specified job. This argument may or may not be used, depending on how PATH is passed to the command (via environment or via the commant line)
Returns:

dictionary with the environment to use.

This returned environment has additional PATH, PYTHONPATH entries. It also uses fixed LANG so that scripts behave as expected. Lastly it sets CHECKBOX_SHARE and CHECKBOX_DATA that may be required by some scripts.

get_score(job)

Compute how applicable this controller is for the specified job.

Returns:A numeric score, or None if the controller cannot run this job. The higher the value, the more applicable this controller is.
get_warm_up_for_job(job)

Get a warm-up function that should be called before running this job.

Returns:None
on_leftover_files

Basic signal that supports arbitrary listeners.

While this class can be used directly it is best used with the helper decorator Signal.define on a function or method. See the documentation for the plainbox.vendor.morris module for details.

Attr _name:Name of the signal, typically accessed via name().
Attr _listeners:
 List of signal listeners. Each item is a tuple (listener, pass_signal) that encodes how to call the listener.
temporary_cwd(job, config)

Context manager for handling temporary current working directory for a particular execution of a job definition command.

Parameters:
  • job – The JobDefinition to execute
  • config – A PlainBoxConfig instance which can be used to load missing environment definitions that apply to all jobs. It is used to provide values for missing environment variables that are required by the job (as expressed by the environ key in the job definition file).
Returns:

Pathname of the new temporary directory

comments powered by Disqus