luci: Index | Files

package invoke

import ""

Package invoke implements the process of invoking a 'luciexe' compatible subprocess, but without setting up any of the 'host' requirements (like a Logdog Butler or LUCI Auth).

See for details on the protocol.


Package Files

options.go subprocess.go terminate_unix.go

type Options Uses

type Options struct {
    // This should be in Build.Step.Name format, i.e. "parent|parent|leaf".
    // Namespace is used as:
    //   * The Step name of the enclosing Build Step.
    //   * Generating the new LOGDOG_NAMESPACE in the environment for the
    //     subprocess. Non-StreamName characters are replaced with '_',
    //     and if the first character of a segment is not a character, "s_" is
    //     prpended. i.e. if the current LOGDOG_NAMESPACE is "u", and this
    //     namespace is "x|!!cool!!|z", then LOGDOG_NAMESPACE for the
    //     subprocess will be "u/x/s___cool__/z".
    //     * The LUCI Executable host process will assert that all logdog stream
    //       names mentioned in the subprocess's Build are relative to this.
    //   * The basis for the stdout/stderr Logdog streams for the subprocess.
    //   * The LUCI Executable host process will adjust the subprocess's step
    //     names to be relative to this. i.e. if the subprocess emits a step "a|b"
    //     and the Namespace is "x|y|z", then the step will show up as "x|y|z|a|b"
    //     on the overall Build.
    // TODO(iannucci): Logdog stream names are restricted because they show up in
    // URLs on the logdog service. If the logdog service instead uses URL encoding
    // of the stream name, then StreamName could be expanded to allow all
    // characters except for "/". At some later point we could potentially change
    // the separator from "/" to "|" to match Buildbucket semantics.
    // TODO(iannucci): Find a way to have logdog stream name namespacing be more
    // transparent (i.e. without needing explicit cooperation from the logdog
    // client library via LOGDOG_NAMESPACE envvar).
    // Default: The Namespace is empty. This is ONLY useful when writing
    // a transparent wrapper for a luciexe which doesn't, itself, implement the
    // luciexe protocol. If Namespace is empty, then Subprocess.Step will be
    // `nil`.
    Namespace string

    // The base dir where all sub-directories (i.e. workdir, tempdir, etc.)
    // will be created under (i.e. the `cwd` for invoked luciexe will be
    // `$BaseDir/w`). If specified, this must exist and be a directory.
    // If empty, a random directory under os.TempDir will be used.
    BaseDir string

    // Absolute path to the cache base directory. This must exist and be
    // a directory.
    // Default: If LUCI_CONFIG['lucictx']['cache_dir'] is set, it will be passed
    // through unchanged. Otherwise a new empty directory is allocated which will
    // be destroyed on the subprocess's completion.
    CacheDir string

    // If set, the subprocess's final Build message will be collected and returned
    // from Wait.
    // If CollectOutput is specified, but CollectOutputPath is not, a temporary
    // path will be seleceted and destroyed on the subprocess's completion.
    CollectOutput bool

    // If set, will be used as the path to output the subprocess's final Build
    // state. Must end with one of {'.pb', '.json', '.textpb'}. This must be
    // a path to a non-existent file (i.e. parent must be a directory).
    // If CollectOutputPath is specified, but CollectOutput is not, the subprocess
    // will be instructed to dump the result to this path, but we won't attempt to
    // parse or validate it in any way, and Wait will return a nil `output`.
    CollectOutputPath string

    // A replacement environment for the Options.
    // If this is not specified, the current process's environment is inherited.
    // The following environment variables will be ignored from this `Env`:
    //   * LUCI_CONTEXT
    Env environ.Env

Options represents settings to use when Start'ing a luciexe.

All values here have defaults, so Start can accept `nil`.

type Subprocess Uses

type Subprocess struct {
    Step *bbpb.Step
    // contains filtered or unexported fields

Subprocess represents a running luciexe.

func Start Uses

func Start(ctx context.Context, luciexeArgs []string, input *bbpb.Build, opts *Options, deadlineEvtCh <-chan lucictx.DeadlineEvent) (*Subprocess, error)

Start launches a binary implementing the luciexe protocol and returns immediately with a *Subprocess.


* ctx will be used for deadlines/cancellation of the started luciexe.
* luciexeArgs[0] must be the full absolute path to the luciexe binary.
* input must be the Build message you wish to pass to the luciexe binary.
* opts is optional (may be nil to take all defaults)
* deadlineEvtCh is optional. When supplied, it must be the cleanup channel
  returned by calling `lucictx.AdjustDeadline` in the outer layer. While
  the luciexe subprocess is running, if
    - `InterruptEvent` or `TimeoutEvent` is received, the subprocess will
       be terminated.
    - `ClosureEvent` is received, the subprocess will be killed.

Callers MUST call Wait and/or cancel the context or this will leak handles for the process' stdout/stderr.

This assumes that the current process is already operating within a "host application" environment. See "" for details.

The caller SHOULD immediately take Subprocess.Step, append it to the current Build state, and send that (e.g. using `exe.BuildSender`). Otherwise this luciexe's steps will not show up in the Build.

func (*Subprocess) Kill Uses

func (s *Subprocess) Kill() error

Kill kills the luciexe process.

func (*Subprocess) Terminate Uses

func (s *Subprocess) Terminate() error

Terminate sends SIGTERM on unix or CTRL+BREAK on windows to the luciexe process.

func (*Subprocess) Wait Uses

func (s *Subprocess) Wait() (*bbpb.Build, error)

Wait waits for the subprocess to terminate.

If Options.CollectOutput (default: false) was specified, this will return the final Build message, as reported by the luciexe.

If you wish to cancel the subprocess (e.g. due to a timeout or deadline), make sure to pass a cancelable/deadline context to Start().

Calling this multiple times is OK; it will return the same values every time.

Package invoke imports 27 packages (graph) and is imported by 1 packages. Updated 2021-01-18. Refresh now. Tools for package owners.