mobilerunner

package
v1.332.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2026 License: AGPL-3.0 Imports: 26 Imported by: 0

Documentation

Overview

Package mobilerunner holds the rules shared by every surface that decides whether a mobile runner can be used and how it is reached over HTTP.

Index

Constants

View Source
const AgentNamespaceReadyField = "agent_namespace_ready"

AgentNamespaceReadyField is the hidden mobile_runners field where Credimi records that it prepared the runner's agent namespace, so a restarted Credimi keeps answering heartbeats with the namespace.

View Source
const CredentialSecretEnvVar = "CREDIMI_RUNNER_CREDENTIAL_SECRET"

CredentialSecretEnvVar names the secret every runner credential is derived from. Rotating it invalidates every runner credential until each runner's next registration or heartbeat delivers the new one.

View Source
const DashboardCodeTTL = 60 * time.Second

DashboardCodeTTL is how long a dashboard sign-in code can be redeemed.

View Source
const DefaultSelectorHeartbeatTTL = 60 * time.Second

DefaultSelectorHeartbeatTTL tolerates two missed heartbeats. The runner heartbeats every 30s, so a runner that has not reported for a minute is treated as unavailable by catalog surfaces. The lifecycle heartbeat timeout stays an hour because it drives the durable `online` flag, which must not flap.

View Source
const SelectorHeartbeatTTLEnv = "MOBILE_RUNNER_SELECTOR_HEARTBEAT_TTL"

Variables

View Source
var (
	ErrDeviceNotFound       = errors.New("mobile device not found")
	ErrDeviceRunnerNotFound = errors.New("mobile device runner not found")
	ErrDeviceNotAccessible  = errors.New("mobile device is not accessible")
	ErrRunnerNotFound       = errors.New("mobile runner not found")
)
View Source
var ErrCredentialSecretMissing = errors.New(CredentialSecretEnvVar + " is not set")

ErrCredentialSecretMissing reports that CredentialSecretEnvVar is not set.

View Source
var ErrTooManyDashboardCodes = errors.New("too many pending dashboard sign-in codes")

ErrTooManyDashboardCodes is returned when maxDashboardCodes unexpired codes are pending.

View Source
var ErrTooManyUserDashboardCodes = errors.New(
	"too many pending dashboard sign-in codes for the user",
)

ErrTooManyUserDashboardCodes is returned when the user already has maxDashboardCodesPerUser unexpired codes pending.

Functions

func AgentEnabled added in v1.330.0

func AgentEnabled(runner *core.Record) bool

AgentEnabled reports whether runner serves action author sessions: its agent is enabled and the runner is not disabled.

func AgentNamespace added in v1.330.0

func AgentNamespace(runnerRecordID string) string

AgentNamespace is the Temporal namespace where the action author sessions of the runner with record ID runnerRecordID run.

func AgentNamespaceReady added in v1.330.0

func AgentNamespaceReady(runner *core.Record) bool

AgentNamespaceReady reports whether runner's agent may serve its namespace: the agent is enabled and Credimi prepared the namespace, in this process or in an earlier one (AgentNamespaceReadyField).

func AgentNamespaceServed added in v1.330.0

func AgentNamespaceServed(runnerID string) bool

AgentNamespaceServed reports whether this process runs the workers of the agent namespace of the runner with record ID runnerID.

func Credential

func Credential(runner *core.Record) (string, error)

Credential returns the key Credimi presents to runner as Credimi-Api-Key: the lowercase hex HMAC-SHA256, keyed by CredentialSecretEnvVar, of "<record id>:<credential_generation>". Each runner gets its own value, and bumping credential_generation rotates it. Credimi never sends its internal admin key to a runner.

func HTTPClient

func HTTPClient(runner *core.Record) *http.Client

HTTPClient returns the client every Credimi call to runner must use; see Transport. Requests carry the caller's trace context, so the runner's spans join the Credimi trace.

func IsQuickTunnelURL

func IsQuickTunnelURL(runnerURL string) bool

func MarkAgentNamespaceReady added in v1.330.0

func MarkAgentNamespaceReady(app core.App, runnerID string) error

MarkAgentNamespaceReady sets AgentNamespaceReadyField on the runner with record ID runnerID while its agent is enabled and it is not disabled. It writes the column alone, so record hooks don't run again.

func NormalizeDeviceIDs

func NormalizeDeviceIDs(values []string) []string

NormalizeDeviceIDs splits comma lists, normalizes, deduplicates and sorts device IDs.

func OrganizationPublishedLoader

func OrganizationPublishedLoader(app core.App, orgID string) func() (bool, error)

OrganizationPublishedLoader returns a function that reads the organization's published flag on first use and reuses it afterwards.

func RecentlyAlive

func RecentlyAlive(record *core.Record, now time.Time) bool

RecentlyAlive reports whether a runner reported a heartbeat recently enough to be offered in a device selector. It answers "the runner was reaching Credimi a moment ago", which is what a catalog needs; whether the runner is reachable at execution time is decided by a live health check on the run path, not here.

func ResolveDevice

func ResolveDevice(app core.App, id string) (device, runner *core.Record, err error)

ResolveDevice returns the mobile device at the canonified path id and its runner. It returns an error wrapping ErrDeviceNotFound when id is not a mobile device and ErrDeviceRunnerNotFound when its runner record is missing; any other error is a lookup failure.

func ResolveRunner

func ResolveRunner(app core.App, id string) (*core.Record, error)

ResolveRunner returns the mobile runner at the canonified path id. It returns an error wrapping ErrRunnerNotFound when id is not a mobile runner; any other error is a lookup failure.

func RunnerIdentifier

func RunnerIdentifier(app core.App, runner *core.Record) (string, error)

RunnerIdentifier returns the normalized canonified path of a runner.

func RunnerURL

func RunnerURL(runner *core.Record) string

RunnerURL returns the runner base URL built from its ip and optional port.

func SelectorHeartbeatTTL

func SelectorHeartbeatTTL() time.Duration

func SetAgentNamespaceServed added in v1.330.0

func SetAgentNamespaceServed(runnerID string, served bool)

SetAgentNamespaceServed records whether this process runs the workers of the agent namespace of the runner with record ID runnerID.

func SharedWith

func SharedWith(runner *core.Record, orgPublished bool) bool

SharedWith reports whether another organization's runner may be used by an organization: only published runners are shared, and unpublished organizations only get admin-managed ones.

func Transport

func Transport(runner *core.Record) http.RoundTripper

Transport returns the round tripper every Credimi call to runner must go through, or nil when the default transport is correct. Callers that own their own client (an activity setting its own timeout) use this instead of HTTPClient.

Admin-managed runners are operator infrastructure: they get the default transport, or the Cloudflare-resolving one for quick tunnels. A tenant chooses its runner's address, so tenant runners are reached only over https, without a proxy, and only at public addresses checked on every dial, which also covers redirects and rebinding hostnames. A rejected destination fails with an error wrapping safehttp.ErrBlockedDestination.

func URLUsable

func URLUsable(runnerURL string) bool

URLUsable reports whether a runner URL can be called at all. A catalog surface that trusts heartbeats still has to exclude a runner whose stored URL is malformed: it reports healthy while being uncallable.

func ValidateDeviceAccess

func ValidateDeviceAccess(app core.App, ownerID string, deviceIDs []string) error

ValidateDeviceAccess checks that every device exists, has a runner and is either owned by ownerID or shared with that organization.

Types

type DashboardCode added in v1.331.0

type DashboardCode struct {
	RunnerID       string
	UserID         string
	AuthCollection string
	ReturnTo       string
	Expires        time.Time
}

DashboardCode is a pending sign-in to a runner's dashboard: the user with record UserID in AuthCollection may sign in to the dashboard of the runner with record ID RunnerID until Expires. ReturnTo is the dashboard callback the code was sent to; only that dashboard may redeem it.

type DashboardCodeStore added in v1.331.0

type DashboardCodeStore struct {
	// contains filtered or unexported fields
}

DashboardCodeStore holds pending codes by code. It lives in this process's memory: a restart drops them and users sign in again.

func NewDashboardCodeStore added in v1.331.0

func NewDashboardCodeStore() *DashboardCodeStore

NewDashboardCodeStore returns an empty store.

func (*DashboardCodeStore) Issue added in v1.331.0

func (s *DashboardCodeStore) Issue(c DashboardCode, now time.Time) (string, error)

Issue stores c under a new random code and returns the code. Expired codes are dropped first; then a user with maxDashboardCodesPerUser pending codes gets ErrTooManyUserDashboardCodes and a store with maxDashboardCodes ErrTooManyDashboardCodes.

func (*DashboardCodeStore) Redeem added in v1.331.0

func (s *DashboardCodeStore) Redeem(code string, now time.Time) (DashboardCode, bool)

Redeem removes code and returns its sign-in when it had not expired at now. A code can be redeemed once.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL