Documentation
¶
Index ¶
- Constants
- Variables
- func AspireContractPresent(getenv func(string) string) bool
- func InferRuntime(appCommand string) string
- func InferRuntimeFromEnv(env []string) string
- func InferRuntimeFromImage(image string) string
- func TranslateMountPath(mounts map[string]string, containerPath string) (string, bool)
- type ActorType
- type Component
- type ComposeEnv
- type ComposeProject
- type ComposeSource
- type ExtractedFile
- type Health
- type Instance
- type Metadata
- type ScanResult
- type Scanner
- type Service
- type SubRule
- type Subscription
- type TestcontainersSource
Constants ¶
const ( SourceStandalone = "standalone" SourceCompose = "compose" // SourceAspire marks apps injected via the DEVDASHBOARD_APP_* env // contract (aspire mode, or mode-unset with the contract present). SourceAspire = "aspire" // SourceTestcontainers marks daprd sidecars run by Testcontainers // (org.testcontainers=true label), e.g. dapr-spring-boot-starter-test. SourceTestcontainers = "testcontainers" )
const ( StatusRunning = "running" StatusStopped = "stopped" )
Per-target process status. Empty string means unknown.
Variables ¶
var ErrNotFound = errors.New("app not found")
Functions ¶
func AspireContractPresent ¶ added in v0.0.9
AspireContractPresent reports whether the DEVDASHBOARD_APP_* env contract is set at all (anchor variable: DEVDASHBOARD_APP_COUNT). Used with mode unset to decide whether the aspire source joins the merge.
func InferRuntime ¶
InferRuntime guesses the app's language from its launch command (best-effort).
func InferRuntimeFromEnv ¶ added in v0.0.7
InferRuntimeFromEnv guesses the app's language from environment variables inherited from official base images (best-effort, conservative — only well-known variable names count, never values).
func InferRuntimeFromImage ¶
InferRuntimeFromImage guesses the app's language from its container image name (best-effort; conservative — a bespoke image name yields "unknown").
func TranslateMountPath ¶
TranslateMountPath maps a container-internal path to its host path via a bind-mount table (exact destination match or destination-prefix match). Container paths are always slash-separated (Linux containers).
Types ¶
type ComposeEnv ¶
type ComposeEnv struct {
Projects map[string]ComposeProject
// PathProject maps each host resource/config dir found on a sidecar to its
// compose project name.
PathProject map[string]string
}
ComposeEnv is the compose network/mount context from the last scan. The reconciler uses it to translate store addresses to host-reachable ones.
func (ComposeEnv) ProjectForPath ¶
func (e ComposeEnv) ProjectForPath(p string) (string, bool)
ProjectForPath returns the compose project owning p (p equal to, or nested under, one of the scanned host resource dirs).
type ComposeProject ¶
type ComposeProject struct {
// ServicePorts maps service name -> container port -> published host port.
ServicePorts map[string]map[int]int
// Mounts maps container destination -> host source, merged across the
// project's daprd sidecars (first destination wins). Used for SQLite
// connection-path translation.
Mounts map[string]string
}
ComposeProject is the host-reachable view of one compose project.
type ComposeSource ¶
type ComposeSource struct {
// contains filtered or unexported fields
}
ComposeSource discovers Dapr sidecars running in compose-managed containers. A nil runner (no docker/podman) degrades to an empty, error-free scan.
func NewComposeSource ¶
func NewComposeSource(run containerruntime.Runner) *ComposeSource
func (*ComposeSource) Env ¶
func (s *ComposeSource) Env() ComposeEnv
Env returns the compose endpoint/mount context from the last successful scan.
func (*ComposeSource) Scanner ¶
func (s *ComposeSource) Scanner() Scanner
Scanner returns the compose scan as a discovery.Scanner.
type ExtractedFile ¶ added in v0.0.10
ExtractedFile is one YAML file copied out of a daprd container's resources dir. Container is the container name (display identity), Path the container-internal file path.
type Instance ¶
type Instance struct {
AppID string `json:"appId"`
// InstanceKey is the routing identity: container name for compose apps
// (falling back to app id), app id otherwise. Unique per instance even
// when several compose sidecars share one -app-id.
InstanceKey string `json:"instanceKey"`
Health Health `json:"health"`
Runtime string `json:"runtime"` // e.g. "go", "python", "node", "dotnet", "java", "rust", "unknown"
IsAspire bool `json:"isAspire,omitempty"` // true when the app is .NET Aspire-managed
Source string `json:"source"` // "standalone" | "compose" | "aspire"
ComposeProject string `json:"composeProject,omitempty"`
ComposeService string `json:"composeService,omitempty"`
DaprdContainerID string `json:"daprdContainerId,omitempty"`
DaprdContainerName string `json:"daprdContainerName,omitempty"`
AppContainerID string `json:"appContainerId,omitempty"`
AppContainerName string `json:"appContainerName,omitempty"`
SidecarReachable bool `json:"sidecarReachable"`
// DaprHTTPBaseURL is the daprd HTTP endpoint for aspire-source apps
// ("" otherwise; consumers fall back to 127.0.0.1:httpPort).
DaprHTTPBaseURL string `json:"daprHttpBaseUrl,omitempty"`
Namespace string `json:"namespace,omitempty"`
Label string `json:"label,omitempty"`
// TestcontainersSession groups one Testcontainers run's containers
// (org.testcontainers.sessionId label; "" for other sources).
TestcontainersSession string `json:"testcontainersSession,omitempty"`
HTTPPort int `json:"httpPort"`
GRPCPort int `json:"grpcPort"`
AppPort int `json:"appPort"`
AppProtocol string `json:"appProtocol,omitempty"`
DaprdPID int `json:"daprdPid"`
AppPID int `json:"appPid"` // 0 = unknown
CLIPID int `json:"cliPid"`
AppStatus string `json:"appStatus,omitempty"` // "running" | "stopped"; "" unknown
DaprdStatus string `json:"daprdStatus,omitempty"` // "running" | "stopped"; "" unknown
AppStartedAt string `json:"appStartedAt,omitempty"` // RFC3339 UTC; "" when stopped/unknown
DaprdStartedAt string `json:"daprdStartedAt,omitempty"` // RFC3339 UTC; "" when stopped/unknown
// SidecarOrphaned marks a standalone daprd with no supervising dapr CLI
// and no live app (e.g. an external stop missed a detached sidecar).
SidecarOrphaned bool `json:"sidecarOrphaned,omitempty"`
Age string `json:"age"` // human, e.g. "14m"
Created string `json:"created"` // local time string
RunTemplate string `json:"runTemplate"`
ResourcePaths []string `json:"resourcePaths"`
ConfigPath string `json:"configPath"`
AppLogPath string `json:"appLogPath"`
DaprdLogPath string `json:"daprdLogPath"`
AppLogFormat string `json:"appLogFormat,omitempty"` // "" / "plain" / "dcp"
DaprdLogFormat string `json:"daprdLogFormat,omitempty"` // "" / "plain" / "dcp"
Command string `json:"command"`
RuntimeVersion string `json:"runtimeVersion"` // from metadata; "" if unavailable
MetadataOK bool `json:"metadataOk"` // false if /v1.0/metadata failed
Actors []ActorType `json:"actors,omitempty"`
Subscriptions []Subscription `json:"subscriptions,omitempty"`
Components []Component `json:"components,omitempty"`
EnabledFeatures []string `json:"enabledFeatures,omitempty"`
Placement string `json:"placement,omitempty"`
}
Instance represents a running application instance with Dapr
type Metadata ¶
type ScanResult ¶
type ScanResult struct {
AppID string
HTTPPort int
GRPCPort int
AppPort int
DaprdPID int
CLIPID int
Created time.Time
RunTemplate string
ResourcePaths []string
ConfigPath string
Command string
AppProtocol string
// Source is SourceStandalone (process table) or SourceCompose (containers).
Source string
ComposeProject string
ComposeService string
DaprdContainerID string
DaprdContainerName string
AppContainerID string
AppContainerName string
AppImage string
// AppRuntime is the compose scanner's language inference for the app
// container ("" for other sources; possibly "unknown").
AppRuntime string
// SidecarReachable is false only for compose sidecars whose HTTP port is
// not published to the host (metadata/health enrichment impossible).
SidecarReachable bool
// DaprHTTPBaseURL, when set (aspire source), replaces
// http://127.0.0.1:<HTTPPort> as the daprd HTTP endpoint for health,
// metadata, and workflow calls.
DaprHTTPBaseURL string
// Namespace and Label come from the Aspire env contract ("" for other
// sources). Label is the orchestrator's display name for the app.
Namespace string
Label string
// TestcontainersSession groups one Testcontainers run's containers
// (org.testcontainers.sessionId label; "" for other sources).
TestcontainersSession string
// Per-target lifecycle status ("" = unknown; compose scanner and standalone enrichment set these).
AppStatus string
DaprdStatus string
AppStartedAt time.Time
DaprdStartedAt time.Time
}
func (ScanResult) Key ¶ added in v0.0.7
func (r ScanResult) Key() string
Key returns the routing identity for this scan result. Compose sidecars can share one -app-id (scaled instances), so they key by container name — the app container when paired, else the daprd container; everything else keys by AppID. Container names are unique per host, so keys are unique whenever a container name is available.
type Scanner ¶
type Scanner func() ([]ScanResult, error)
func Merge ¶
Merge combines scanners into one. A failing scanner is logged and skipped so one source (e.g. docker being absent) never hides the others; the merged scan errors only when every scanner fails. When any result has Source == SourceAspire, it wins key collisions: every other result sharing its Key() is dropped (an Aspire-launched daprd host process is otherwise double-counted by both the standalone scan and the env contract). Order is stable otherwise.
func NewAspireScanner ¶ added in v0.0.9
NewAspireScanner parses the DEVDASHBOARD_APP_* env contract eagerly and returns a static Scanner over the parsed apps. Malformed contracts fail here — at startup — with an error naming the exact variable, never at scan time. The returned scanner is static: env is read once; liveness comes from the discovery service's per-poll health/metadata probes.
func StandaloneScanner ¶
func StandaloneScanner() Scanner
StandaloneScanner returns a Scanner that reads running Dapr sidecars from the local process table via the Dapr CLI standalone.List function.
type Service ¶
type Service interface {
List(ctx context.Context) ([]Instance, error)
// Get resolves key as an InstanceKey first, then as an AppID (first match).
Get(ctx context.Context, key string) (Instance, error)
}
func FilterAspire ¶ added in v0.0.11
FilterAspire restricts a Service to Aspire-managed instances. Aspire host mode (dashboard on the host, no env contract) scans the full process table — IsAspire is only known after enrichment (the DCP-proxy heuristic in appproc.go), so the filter must wrap the Service rather than the Scanner. Wrap the outermost Service (after the lifecycle overlay) so every consumer — apps API, workflows, state-store election — sees the filtered view.
type Subscription ¶
type TestcontainersSource ¶ added in v0.0.10
type TestcontainersSource struct {
// contains filtered or unexported fields
}
TestcontainersSource discovers daprd sidecars run by Testcontainers (e.g. dapr-spring-boot-starter-test): containers labeled org.testcontainers=true whose argv invokes daprd. The paired app is a host process reached via host.testcontainers.internal; enrichment resolves it from the app port. A nil runner (no docker/podman) degrades to an empty, error-free scan.
func NewTestcontainersSource ¶ added in v0.0.10
func NewTestcontainersSource(run containerruntime.Runner) *TestcontainersSource
func (*TestcontainersSource) Files ¶ added in v0.0.10
func (s *TestcontainersSource) Files() []ExtractedFile
Files returns the extracted resource files of all currently-scanned containers, ordered by container name then path.
func (*TestcontainersSource) Scanner ¶ added in v0.0.10
func (s *TestcontainersSource) Scanner() Scanner
Scanner returns the testcontainers scan as a discovery.Scanner.