luci: go.chromium.org/luci/lucictx Index | Files

package lucictx

import "go.chromium.org/luci/lucictx"

Package lucictx implements a Go client for the protocol defined here:

https://github.com/luci/luci-py/blob/master/client/LUCI_CONTEXT.md

It differs from the python client in a couple ways:

* The initial LUCI_CONTEXT value is captured once at application start.
* Writes are cached into the golang context.Context, not a global variable.
* The LUCI_CONTEXT environment variable is not changed automatically when
  using the Set function. To pass the new context on to a child process,
  you must use the Export function to dump the current context state to
  disk and call exported.SetInCmd(cmd) to configure new command's
  environment.

Index

Package Files

deadline.go exported.go gen.go local_auth.go lucictx.go luciexe.go realm.go result_sink.go resultdb.go sections.pb.go swarming.go

Constants

const DefaultGracePeriod = 30 * time.Second

DefaultGracePeriod is the value of Deadline.grace_period to assume if Deadline is entirely missing in LUCI_CONTEXT.

const EnvKey = "LUCI_CONTEXT"

EnvKey is the environment variable key for the LUCI_CONTEXT file.

Variables

var ErrNoLocalAuthAccount = errors.New("the requested logical account is not present in LUCI_CONTEXT")

ErrNoLocalAuthAccount is returned by SwitchLocalAccount if requested account is not available in the LUCI_CONTEXT.

var File_go_chromium_org_luci_lucictx_sections_proto protoreflect.FileDescriptor

func AdjustDeadline Uses

func AdjustDeadline(ctx context.Context, reserve, reserveCleanup time.Duration) (cleanup <-chan DeadlineEvent, newCtx context.Context, shutdown func())

AdjustDeadline returns a 'cleanup' channel and a new 'shutdown'-able context based on the combination of the input context's deadline, as well as the Deadline information in LUCI_CONTEXT.

This function allows you to reserve a portion of the deadline and/or grace_period with `reserve` and `reserveCleanup` respectively.

reserve and reserveCleanup must not be less than 0 or this panics.

First, if Deadline is missing from LUCI_CONTEXT, it is filled in with the default:

{soft_deadline: infinity, grace_period: 30}

We then calculate:

adjustedSoftDeadline = earlier(
  ctx.Deadline() - gracePeriod,
  Deadline.soft_deadline,
) - reserve

Next, `reserveCleanup` is subtracted from Deadline.grace_period. This becomes the `adjustedGracePeriod`.

The `cleanup` channel is set up with a goroutine which:

* On shutdown()/SIGTERM/os.Interrupt, continuously sends InterruptEvent.
  After `adjustedGracePeriod` from the interrupt, newCtx will be canceled.
* On `adjustedSoftDeadline`, continuously sends TimeoutEvent.
  The newCtx will meet its hard deadline after `adjustedGracePeriod`.
* On newCtx.Done, closes (so reads will see ClosureEvent).

Finally, the newCtx has its deadline set to `adjustedSoftDeadline+adjustedGracePeriod`, and LUCI_CONTEXT['deadline'] is populated with the adjusted soft_deadline and grace_period.

The returned shutdown() function will begin the shutdown process (acts as if an os.Interrupt signal was triggered). After calling shutdown, you may block on ctx.Done() which will take up to adjustedGracePeriod to occur.

Note, if Deadline.grace_period is insufficient to cover reserveCleanup (including if reserveCleanup>DefaultGracePeriodSecs and no Deadline was in LUCI_CONTEXT at all), this function panics.

Example:

func MainFunc(ctx context.Context) {
  // ctx.Deadline  = unix(t0+5:40)
  // soft_deadline = unix(t0+5:00)
  // grace_period  = 40
  cleanup, newCtx, shutdown := lucictx.AdjustDeadline(ctx, time.Minute, 500*time.Millisecond)
  defer shutdown()
  ScopedFunction(newCtx, cleanup)

  // When ScopedFunction returns (assuming it returns immediately on
  // newCtx.Done):
  //   If there was a signal, you have 500ms left.
  //   If newCtx timed out, you have 1m40s.
  //
  // If you had a goroutine waiting on <-cleanup, you would get the full
  // grace_period to do something. If <-cleanup returned TimeoutEvent, you
  // would also get the remainder of soft_deadline (i.e. 1 additional
  // minute)
}

func ScopedFunction(newCtx context.Context, cleanup <-chan DeadlineEvent) {
  // newCtx.Deadline  = unix(t0+4:39.5)
  // soft_deadline = unix(t0+4:00)
  // grace_period  = 39.5

  go func() {
    // cleanup is unblocked at SIGTERM, $soft_deadline or shutdown(),
    // whichever is first.
    <-cleanup
    // have grace_period to do something (say, send SIGTERM to a child)
    // before newCtx.Done().
  }()
}

NOTE: In the event that `ctx` is canceled, everything immediately moves to the 'Kill' phase without providing any grace period.

func Get Uses

func Get(ctx context.Context, section string, out proto.Message) error

Get retrieves the current section from the current LUCI_CONTEXT, and deserializes it into out. Out may be any target for json.Unmarshal. If the section exists, it deserializes it into the provided out object. If not, then out is unmodified.

func Lookup Uses

func Lookup(ctx context.Context, section string, out proto.Message) (bool, error)

Lookup retrieves the current section from the current LUCI_CONTEXT, and deserializes it into out. Out may be any target for json.Unmarshal. It returns a deserialization error (if any), and a boolean indicating if the section was actually found.

func Set Uses

func Set(ctx context.Context, section string, in proto.Message) context.Context

Set writes the json serialization of `in` as the given section into the LUCI_CONTEXT, returning the new ctx object containing it. This ctx can be passed to Export to serialize it to disk.

If in is nil, it will clear that section of the LUCI_CONTEXT.

The returned context is always safe to use, even if this returns an error.

func SetDeadline Uses

func SetDeadline(ctx context.Context, d *Deadline) context.Context

SetDeadline sets the raw Deadline information in the context.

If d is nil, sets a default deadline of:

{grace_period: DefaultGracePeriod}

If d.deadline == 0, adjusts it to ctx.Deadline() - d.grace_period.

You probably want to use AdjustDeadline instead.

func SetLUCIExe Uses

func SetLUCIExe(ctx context.Context, le *LUCIExe) context.Context

SetLUCIExe sets the LUCIExe in the LUCI_CONTEXT.

func SetLocalAuth Uses

func SetLocalAuth(ctx context.Context, la *LocalAuth) context.Context

SetLocalAuth sets the LocalAuth in the LUCI_CONTEXT.

func SetRealm Uses

func SetRealm(ctx context.Context, r *Realm) context.Context

SetRealm sets the Realm in the LUCI_CONTEXT.

func SetResultDB Uses

func SetResultDB(ctx context.Context, db *ResultDB) context.Context

SetResultDB sets the ResultDB in the LUCI_CONTEXT.

func SetResultSink Uses

func SetResultSink(ctx context.Context, sink *ResultSink) context.Context

SetResultSink sets the ResultSink in the LUCI_CONTEXT.

func SetSwarming Uses

func SetSwarming(ctx context.Context, swarm *Swarming) context.Context

SetSwarming Sets the Swarming in the LUCI_CONTEXT.

func SwitchLocalAccount Uses

func SwitchLocalAccount(ctx context.Context, accountID string) (context.Context, error)

SwitchLocalAccount changes default logical account selected in the context.

For example, it can be used to switch the context into using "system" account by default. The default account is transparently used by LUCI-aware tools.

If the requested account is available, modifies LUCI_CONTEXT["local_auth"] in the context and returns the new modified context.

If the given account is already default, returns the context unchanged.

If the given account is not available, returns (nil, ErrNoLocalAuthAccount).

type Deadline Uses

type Deadline struct {

    // The absolute soft deadline for execution for this context (as a 'float'
    // unix timestamp; integer part is seconds, fractional part is fractions of
    // a second. This is the same as python's `time.time()` representation).
    //
    // Processes reading this value SHOULD choose to terminate and clean
    // themselves up before this deadline.
    //
    // This is a 'soft' deadline because the parent process will give
    // `grace_period` seconds past this before sending SIGKILL/Terminate.
    //
    // Parent processes MUST send SIGTERM/Ctrl-Break to subprocesses which
    // exceed this deadline. They should attempt to do this as close to
    // `soft_deadline` as possible.
    //
    // If `soft_deadline` is 0 consider there to be no stated deadline (i.e.
    // infinite).
    SoftDeadline float64 `protobuf:"fixed64,1,opt,name=soft_deadline,proto3" json:"soft_deadline,omitempty"`
    // The amount of time (in fractional seconds), processes in this context have
    // time to react to a SIGTERM/Ctrl-Break before being SIGKILL/Terminated.
    //
    // If an intermediate process has a lot of cleanup work to do after its child
    // quits (e.g. flushing stats/writing output files/etc.) it SHOULD reduce this
    // value for the child process by an appropriate margin.
    GracePeriod float64 `protobuf:"fixed64,2,opt,name=grace_period,proto3" json:"grace_period,omitempty"`
    // contains filtered or unexported fields
}

Deadline represents an externally-imposed termination criteria for the process observing the LUCI_CONTEXT.

Additionally, this contains `grace_period` which can be used to communicate how long the external process will allow for clean up once it sends SIGTERM/Ctrl-Break.

Intermediate applications SHOULD NOT increase soft_deadline or grace_period.

If the entire Deadline is missing from LUCI_CONTEXT, it should be assumed to be:

{soft_deadline: infinity, grace_period: 30}

func GetDeadline Uses

func GetDeadline(ctx context.Context) *Deadline

GetDeadline retrieves the raw Deadline information from the context.

You probably want to use AdjustDeadline instead.

func (*Deadline) Descriptor Uses

func (*Deadline) Descriptor() ([]byte, []int)

Deprecated: Use Deadline.ProtoReflect.Descriptor instead.

func (*Deadline) GetGracePeriod Uses

func (x *Deadline) GetGracePeriod() float64

func (*Deadline) GetSoftDeadline Uses

func (x *Deadline) GetSoftDeadline() float64

func (*Deadline) ProtoMessage Uses

func (*Deadline) ProtoMessage()

func (*Deadline) ProtoReflect Uses

func (x *Deadline) ProtoReflect() protoreflect.Message

func (*Deadline) Reset Uses

func (x *Deadline) Reset()

func (*Deadline) String Uses

func (x *Deadline) String() string

type DeadlineEvent Uses

type DeadlineEvent int

DeadlineEvent is the type pushed into the cleanup channel returned by AdjustDeadline.

const (
    // ClosureEvent occurs when the context returned by AdjustDeadline is Done.
    // This is the value you'll get from `cleanup` when it's closed.
    ClosureEvent DeadlineEvent = iota

    // InterruptEvent occurs when a SIGTERM/os.Interrupt was handled to unblock
    // the cleanup channel.
    InterruptEvent

    // TimeoutEvent occurs when the cleanup channel was unblocked due to
    // a timeout on deadline-gracePeriod.
    TimeoutEvent
)

The cleanup channel, when it unblocks, will have an infinite supply of one of the following event types.

func (DeadlineEvent) String Uses

func (de DeadlineEvent) String() string

type Exported Uses

type Exported interface {
    io.Closer

    // SetInCmd sets/replaces the LUCI_CONTEXT environment variable in an
    // exec.Cmd.
    SetInCmd(c *exec.Cmd)

    // SetInEnviron sets/replaces the LUCI_CONTEXT in an environ.Env object.
    SetInEnviron(env environ.Env)
}

Exported represents an exported on-disk LUCI_CONTEXT file.

func Export Uses

func Export(ctx context.Context) (Exported, error)

Export takes the current LUCI_CONTEXT information from ctx, writes it to a file in os.TempDir and returns a wrapping Exported object. This exported value must then be installed into the environment of any subcommands (see the methods on Exported).

It is required that the caller of this function invoke Close() on the returned Exported object, or they will leak temporary files.

Internally this function reuses existing files, when possible, so if you anticipate calling a lot of subcommands with exported LUCI_CONTEXT, you can export it in advance (thus grabbing a reference to the exported file). Then subsequent Export() calls with this context will be extremely cheap, since they will just reuse the existing file. Don't forget to release it with Close() when done.

func ExportInto Uses

func ExportInto(ctx context.Context, dir string) (Exported, error)

ExportInto is like Export, except it places the temporary file into the given directory.

Exports done via this method are not reused: each individual ExportInto call produces a new temporary file.

type LUCIExe Uses

type LUCIExe struct {

    // The absolute path of the base cache directory. This directory MAY be on the
    // same filesystem as CWD (but is not guaranteed to be). The available caches
    // are described in Buildbucket as CacheEntry messages.
    CacheDir string `protobuf:"bytes,1,opt,name=cache_dir,proto3" json:"cache_dir,omitempty"`
    // contains filtered or unexported fields
}

LUCIExe is a struct that may be used with the "luciexe" section of LUCI_CONTEXT.

func GetLUCIExe Uses

func GetLUCIExe(ctx context.Context) *LUCIExe

GetLUCIExe calls Lookup and returns a copy of the current LUCIExe from LUCI_CONTEXT if it was present. If no LUCIExe is in the context, this returns nil.

func (*LUCIExe) Descriptor Uses

func (*LUCIExe) Descriptor() ([]byte, []int)

Deprecated: Use LUCIExe.ProtoReflect.Descriptor instead.

func (*LUCIExe) GetCacheDir Uses

func (x *LUCIExe) GetCacheDir() string

func (*LUCIExe) ProtoMessage Uses

func (*LUCIExe) ProtoMessage()

func (*LUCIExe) ProtoReflect Uses

func (x *LUCIExe) ProtoReflect() protoreflect.Message

func (*LUCIExe) Reset Uses

func (x *LUCIExe) Reset()

func (*LUCIExe) String Uses

func (x *LUCIExe) String() string

type LocalAuth Uses

type LocalAuth struct {

    // RPCPort and Secret define how to connect to the local auth server.
    RpcPort uint32 `protobuf:"varint,1,opt,name=rpc_port,proto3" json:"rpc_port,omitempty"`
    Secret  []byte `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"`
    // Accounts and DefaultAccountID defines what access tokens are available.
    Accounts         []*LocalAuthAccount `protobuf:"bytes,3,rep,name=accounts,proto3" json:"accounts,omitempty"`
    DefaultAccountId string              `protobuf:"bytes,4,opt,name=default_account_id,proto3" json:"default_account_id,omitempty"`
    // contains filtered or unexported fields
}

LocalAuth is a struct that may be used with the "local_auth" section of LUCI_CONTEXT.

func GetLocalAuth Uses

func GetLocalAuth(ctx context.Context) *LocalAuth

GetLocalAuth calls Lookup and returns a copy of the current LocalAuth from LUCI_CONTEXT if it was present. If no LocalAuth is in the context, this returns nil.

func (*LocalAuth) Descriptor Uses

func (*LocalAuth) Descriptor() ([]byte, []int)

Deprecated: Use LocalAuth.ProtoReflect.Descriptor instead.

func (*LocalAuth) GetAccounts Uses

func (x *LocalAuth) GetAccounts() []*LocalAuthAccount

func (*LocalAuth) GetDefaultAccountId Uses

func (x *LocalAuth) GetDefaultAccountId() string

func (*LocalAuth) GetRpcPort Uses

func (x *LocalAuth) GetRpcPort() uint32

func (*LocalAuth) GetSecret Uses

func (x *LocalAuth) GetSecret() []byte

func (*LocalAuth) ProtoMessage Uses

func (*LocalAuth) ProtoMessage()

func (*LocalAuth) ProtoReflect Uses

func (x *LocalAuth) ProtoReflect() protoreflect.Message

func (*LocalAuth) Reset Uses

func (x *LocalAuth) Reset()

func (*LocalAuth) String Uses

func (x *LocalAuth) String() string

type LocalAuthAccount Uses

type LocalAuthAccount struct {

    // ID is logical identifier of the account, e.g. "system" or "task".
    Id  string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
    // Email is an account email or "-" if not available.
    Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
    // contains filtered or unexported fields
}

LocalAuthAccount contains information about a service account available through a local auth server.

func (*LocalAuthAccount) Descriptor Uses

func (*LocalAuthAccount) Descriptor() ([]byte, []int)

Deprecated: Use LocalAuthAccount.ProtoReflect.Descriptor instead.

func (*LocalAuthAccount) GetEmail Uses

func (x *LocalAuthAccount) GetEmail() string

func (*LocalAuthAccount) GetId Uses

func (x *LocalAuthAccount) GetId() string

func (*LocalAuthAccount) ProtoMessage Uses

func (*LocalAuthAccount) ProtoMessage()

func (*LocalAuthAccount) ProtoReflect Uses

func (x *LocalAuthAccount) ProtoReflect() protoreflect.Message

func (*LocalAuthAccount) Reset Uses

func (x *LocalAuthAccount) Reset()

func (*LocalAuthAccount) String Uses

func (x *LocalAuthAccount) String() string

type Realm Uses

type Realm struct {

    // Realm name of the task.
    Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // e.g. infra:ci
    // contains filtered or unexported fields
}

Realm is a struct that may be used with the "realm" section of LUCI_CONTEXT.

func GetRealm Uses

func GetRealm(ctx context.Context) *Realm

GetRealm returns the current Realm from LUCI_CONTEXT if it was present. nil, otherwise.

func (*Realm) Descriptor Uses

func (*Realm) Descriptor() ([]byte, []int)

Deprecated: Use Realm.ProtoReflect.Descriptor instead.

func (*Realm) GetName Uses

func (x *Realm) GetName() string

func (*Realm) ProtoMessage Uses

func (*Realm) ProtoMessage()

func (*Realm) ProtoReflect Uses

func (x *Realm) ProtoReflect() protoreflect.Message

func (*Realm) Reset Uses

func (x *Realm) Reset()

func (*Realm) String Uses

func (x *Realm) String() string

type ResultDB Uses

type ResultDB struct {
    Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"` // e.g. results.api.cr.dev
    // The invocation in the current context.
    // For example, in a Buildbucket build context, it is the build's invocation.
    //
    // This is the recommended way to propagate invocation name and update token
    // to subprocesses.
    CurrentInvocation *ResultDBInvocation `protobuf:"bytes,2,opt,name=current_invocation,proto3" json:"current_invocation,omitempty"`
    // contains filtered or unexported fields
}

ResultDB is a struct that may be used with the "resultdb" section of LUCI_CONTEXT.

func GetResultDB Uses

func GetResultDB(ctx context.Context) *ResultDB

GetResultDB returns the current ResultDB from LUCI_CONTEXT if it was present. nil, otherwise.

func (*ResultDB) Descriptor Uses

func (*ResultDB) Descriptor() ([]byte, []int)

Deprecated: Use ResultDB.ProtoReflect.Descriptor instead.

func (*ResultDB) GetCurrentInvocation Uses

func (x *ResultDB) GetCurrentInvocation() *ResultDBInvocation

func (*ResultDB) GetHostname Uses

func (x *ResultDB) GetHostname() string

func (*ResultDB) ProtoMessage Uses

func (*ResultDB) ProtoMessage()

func (*ResultDB) ProtoReflect Uses

func (x *ResultDB) ProtoReflect() protoreflect.Message

func (*ResultDB) Reset Uses

func (x *ResultDB) Reset()

func (*ResultDB) String Uses

func (x *ResultDB) String() string

type ResultDBInvocation Uses

type ResultDBInvocation struct {
    Name        string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`                 // e.g. "invocations/build:1234567890"
    UpdateToken string `protobuf:"bytes,2,opt,name=update_token,proto3" json:"update_token,omitempty"` // required in all mutation requests
    // contains filtered or unexported fields
}

ResultDBInvocation is a struct that contains the necessary info to update an invocation in the ResultDB service.

func (*ResultDBInvocation) Descriptor Uses

func (*ResultDBInvocation) Descriptor() ([]byte, []int)

Deprecated: Use ResultDBInvocation.ProtoReflect.Descriptor instead.

func (*ResultDBInvocation) GetName Uses

func (x *ResultDBInvocation) GetName() string

func (*ResultDBInvocation) GetUpdateToken Uses

func (x *ResultDBInvocation) GetUpdateToken() string

func (*ResultDBInvocation) ProtoMessage Uses

func (*ResultDBInvocation) ProtoMessage()

func (*ResultDBInvocation) ProtoReflect Uses

func (x *ResultDBInvocation) ProtoReflect() protoreflect.Message

func (*ResultDBInvocation) Reset Uses

func (x *ResultDBInvocation) Reset()

func (*ResultDBInvocation) String Uses

func (x *ResultDBInvocation) String() string

type ResultSink Uses

type ResultSink struct {

    // TCP address (e.g. "localhost:62115") where a ResultSink pRPC server is hosted.
    Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
    // secret string required in all ResultSink requests in HTTP header
    // `Authorization: ResultSink <auth-token>`
    AuthToken string `protobuf:"bytes,2,opt,name=auth_token,proto3" json:"auth_token,omitempty"`
    // contains filtered or unexported fields
}

func GetResultSink Uses

func GetResultSink(ctx context.Context) *ResultSink

GetResultSink returns the current ResultSink from LUCI_CONTEXT if it was present. nil, otherwise.

func (*ResultSink) Descriptor Uses

func (*ResultSink) Descriptor() ([]byte, []int)

Deprecated: Use ResultSink.ProtoReflect.Descriptor instead.

func (*ResultSink) GetAddress Uses

func (x *ResultSink) GetAddress() string

func (*ResultSink) GetAuthToken Uses

func (x *ResultSink) GetAuthToken() string

func (*ResultSink) ProtoMessage Uses

func (*ResultSink) ProtoMessage()

func (*ResultSink) ProtoReflect Uses

func (x *ResultSink) ProtoReflect() protoreflect.Message

func (*ResultSink) Reset Uses

func (x *ResultSink) Reset()

func (*ResultSink) String Uses

func (x *ResultSink) String() string

type Swarming Uses

type Swarming struct {

    // The user-supplied secret bytes specified for the task, if any. This can be
    // used to pass application or task-specific secret keys, JSON, etc. from the
    // task triggerer directly to the task. The bytes will not appear on any
    // swarming UI, or be visible to any users of the swarming service.
    SecretBytes []byte `protobuf:"bytes,1,opt,name=secret_bytes,proto3" json:"secret_bytes,omitempty"`
    // contains filtered or unexported fields
}

Swarming is a struct that may be used with the "swarming" section of LUCI_CONTEXT.

func GetSwarming Uses

func GetSwarming(ctx context.Context) *Swarming

GetSwarming calls Lookup and returns the current Swarming from LUCI_CONTEXT if it was present. If no Swarming is in the context, this returns nil.

func (*Swarming) Descriptor Uses

func (*Swarming) Descriptor() ([]byte, []int)

Deprecated: Use Swarming.ProtoReflect.Descriptor instead.

func (*Swarming) GetSecretBytes Uses

func (x *Swarming) GetSecretBytes() []byte

func (*Swarming) ProtoMessage Uses

func (*Swarming) ProtoMessage()

func (*Swarming) ProtoReflect Uses

func (x *Swarming) ProtoReflect() protoreflect.Message

func (*Swarming) Reset Uses

func (x *Swarming) Reset()

func (*Swarming) String Uses

func (x *Swarming) String() string

Package lucictx imports 23 packages (graph) and is imported by 21 packages. Updated 2020-12-06. Refresh now. Tools for package owners.