Help us shape the future of Go! Take the 2026 Go Developer Survey

sdk

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package sdk is the supported way to drive docket's engine from Go: build and run tasks, read a server back as a recipe or one resource at a time, and describe the registered task types.

Everything else in the module lives under internal/ and cannot be imported from outside it. The recipe loader, the codecs, template rendering and the CLI are docket's own business; this package is the part meant to be built on.

Stability

The exported identifiers in this package are stable from the release they first ship in. While docket is at 0.x, a change that breaks a caller only ships in a release that bumps the minor version, and the release notes call it out. From 1.0 on, only in a major version.

The one exception is the fields of the task types (AppTask, ConfigTask and so on). They mirror the recipe format, and change when it does: a field added, renamed or removed in a recipe is added, renamed or removed here in the same release.

Types are aliases of the engine's own, so a value built here is the value the engine runs. Every type their exported fields and methods take or return is named here too.

Runs

Every call takes a context.Context, and the context carries what a run needs: the server to send dokku commands to and the values to mask. Build it from a Session, which also owns the SSH connections made under it:

session := sdk.NewSession(sdk.NewMasker("s3cr3t"))
defer func() { _ = session.Close() }()
ctx := session.Context(context.Background(), sdk.Target{Host: "dokku@dokku.example.com"})

The zero Target runs dokku locally. Pass WithVersionGate to NewSession to refuse tasks the server is too old for, with the server's versions read once per session however many contexts it hands out.

Tasks executed at once under one session take turns on the same app or datastore service, so concurrent callers do not collide on dokku's deploy lock. Hold the same locks across a separate Plan and ExecutePlan with LockTask.

Testing

A test can drive tasks without a server by installing a fake runner with ContextWithRunner. The fake answers every command a call makes, and since it travels on the context, tests with different fakes can run in parallel. Production code must not use it.

Index

Examples

Constants

View Source
const (
	ObjectApp     = tasks.ObjectApp
	ObjectService = tasks.ObjectService
)

Object kinds, as TaskObject.Kind.

View Source
const (
	TypeString  = tasks.TypeString
	TypeBool    = tasks.TypeBool
	TypeInt     = tasks.TypeInt
	TypeFloat   = tasks.TypeFloat
	TypeList    = tasks.TypeList
	TypeDict    = tasks.TypeDict
	TypeObject  = tasks.TypeObject
	TypeAny     = tasks.TypeAny
	TypeUnknown = tasks.TypeUnknown
)

Field and item type names used in FieldSchema.Type and ItemSchema.Type.

View Source
const (
	IdentityRoleKey        = tasks.IdentityRoleKey
	IdentityRoleCollection = tasks.IdentityRoleCollection
)

Identity roles a FieldSchema can carry.

View Source
const (
	ItemIdentityValue  = tasks.ItemIdentityValue
	ItemIdentityMapKey = tasks.ItemIdentityMapKey
	ItemIdentityFields = tasks.ItemIdentityFields
)

How a collection's items are told apart.

View Source
const (
	ConstraintExactlyOneOf  = tasks.ConstraintExactlyOneOf
	ConstraintAtLeastOneOf  = tasks.ConstraintAtLeastOneOf
	ConstraintAllOrNoneOf   = tasks.ConstraintAllOrNoneOf
	ConstraintConflictsWith = tasks.ConstraintConflictsWith
	ConstraintRequiredWith  = tasks.ConstraintRequiredWith
)

Kinds of Constraint.

View Source
const (
	PropertyScopeApp    = tasks.PropertyScopeApp
	PropertyScopeGlobal = tasks.PropertyScopeGlobal
)

Scopes a property can be set in.

View Source
const (
	ProbeSupported   = tasks.ProbeSupported
	ProbePartial     = tasks.ProbePartial
	ProbeUnsupported = tasks.ProbeUnsupported

	ExportSupported   = tasks.ExportSupported
	ExportPartial     = tasks.ExportPartial
	ExportUnsupported = tasks.ExportUnsupported
)

Probe and export support levels.

View Source
const (
	FormatYAML  = tasks.FormatYAML
	FormatJSON5 = tasks.FormatNameJSON5
	FormatHCL   = tasks.FormatNameHCL
)

Recipe formats ExportResult.MarshalRecipe accepts.

View Source
const (
	StatePresent  = tasks.StatePresent
	StateAbsent   = tasks.StateAbsent
	StateDeployed = tasks.StateDeployed
	StateSet      = tasks.StateSet
	StateClear    = tasks.StateClear
)

Task states.

View Source
const (
	PlanStatusOK      = tasks.PlanStatusOK
	PlanStatusModify  = tasks.PlanStatusModify
	PlanStatusCreate  = tasks.PlanStatusCreate
	PlanStatusDestroy = tasks.PlanStatusDestroy
	PlanStatusError   = tasks.PlanStatusError
)

Plan statuses, as PlanResult.Status.

View Source
const (
	WarnReasonUnknownProperty    = tasks.WarnReasonUnknownProperty
	WarnReasonProbeRejected      = tasks.WarnReasonProbeRejected
	WarnReasonProbeIndeterminate = tasks.WarnReasonProbeIndeterminate
	WarnReasonServiceImageDrift  = tasks.WarnReasonServiceImageDrift
)

PlanWarning reasons.

View Source
const CatalogVersion = tasks.CatalogVersion

CatalogVersion is the TaskCatalog.Version this release emits. It changes only when the catalog's shape does, so a consumer can branch on it.

View Source
const MaskPlaceholder = subprocess.MaskPlaceholder

MaskPlaceholder is what a Masker replaces a sensitive value with.

View Source
const PropertyFieldName = tasks.PropertyFieldName

PropertyFieldName is the recipe key every property table constrains.

Variables

View Source
var ErrSessionClosed = subprocess.ErrSessionClosed

ErrSessionClosed is the error a call made under a closed session fails with. Test for it with errors.Is.

View Source
var ErrStateUnreadable = tasks.ErrStateUnreadable

ErrStateUnreadable is wrapped by the error ReadTask returns when a task's probe cannot read its current state, such as dokku_storage_ensure, or when the probe failed in a way the plan treats as drift.

Functions

func As

func As[T Task](e ExportedTask) (T, bool)

As returns an exported task's body as T, the value type registered under e.Type (ConfigTask, not *ConfigTask). It reports false for any other type.

func CheckMinimumVersions added in v0.9.1

func CheckMinimumVersions(ctx context.Context, typeKey string, task Task) error

CheckMinimumVersions returns a *VersionError when the server ctx targets, or an installed plugin task needs, is older than the floor task declares. A task's Plan and Execute already refuse through it when ctx carries a gate; call it to check a task before planning it. It returns nil when ctx carries no gate, when task declares no floor, and when a plugin task needs is not installed, which the task's own probe reports. typeKey names the task in the error, such as "dokku_app".

func ContextWithRunner added in v0.9.1

func ContextWithRunner(ctx context.Context, fn ExecRunner) context.Context

ContextWithRunner returns a copy of ctx whose commands go to fn instead of to a real process or server. The runner travels on the context rather than in a package variable, so two tests can install different fakes at the same time and both can call t.Parallel().

Production code must not use it. The seam exists so a test can drive a task without a server; a caller that wants to change where commands actually run sets a Target.

fn receives every command a call makes, not only dokku's, with its arguments as they would have run: unmasked, and without the sudo or SSH wrapping a Target adds. A Target on ctx has no effect while fn is installed.

A command that ran and exited non-zero is a response carrying that ExitCode. A probe reads it as its answer whether fn returns a nil error alongside it or, as the real runner does, an *ExecError with Ran set. An apply fails only on an error, so return the *ExecError to fail one. Any other error is a command that could not run, which a probe reports as an error rather than as absence.

The response's Command is what an apply records in TaskOutputState.Commands, so set it when a test reads that.

Example

Planning and applying a task against a fake dokku in a test, with no server.

package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/dokku/docket/sdk"
)

func main() {
	var calls []string
	ctx := sdk.ContextWithRunner(context.Background(), func(_ context.Context, in sdk.ExecCommandInput) (sdk.ExecCommandResponse, error) {
		calls = append(calls, strings.Join(in.Args, " "))
		if len(in.Args) > 1 && in.Args[1] == "apps:exists" {
			// The app is absent: the command ran and exited non-zero.
			return sdk.ExecCommandResponse{ExitCode: 1}, nil
		}
		return sdk.ExecCommandResponse{}, nil
	})

	task, _ := sdk.NewTask("dokku_app")
	app := task.(*sdk.AppTask)
	app.App = "api"

	plan := app.Plan(ctx)
	fmt.Println(plan.Reason, plan.Commands)

	state := sdk.ExecutePlan(ctx, plan)
	fmt.Println(state.Changed, calls)
}
Output:
app missing [dokku --quiet apps:create api]
true [--quiet apps:exists api --quiet apps:create api]

func ContextWithTarget

func ContextWithTarget(ctx context.Context, target Target) context.Context

ContextWithTarget returns a copy of ctx that sends dokku commands to target. A context derived from a session context still belongs to that session.

func ContextWithTaskLocks added in v0.10.0

func ContextWithTaskLocks(ctx context.Context) context.Context

ContextWithTaskLocks returns a copy of ctx on which Execute serializes the tasks that change the same app or datastore service, on the same server. A context that already carries a lock table is returned as-is. Every context a NewSession session hands out already carries one, so this is only for a context built without a session.

func ContextWithVersionGate added in v0.9.1

func ContextWithVersionGate(ctx context.Context) context.Context

ContextWithVersionGate returns a copy of ctx on which CheckMinimumVersions compares a task's floor with the server. The versions it reads are cached per target for as long as the context lives, so install it once per run. A context that already carries a gate is returned as-is. A caller that gets a new context for every call it serves gives the gate to its session with WithVersionGate instead.

func IdentityAddress

func IdentityAddress(typeKey string, t Task) string

IdentityAddress renders the resource t addresses, such as `dokku_config[app=api]`. It is the form ParseIdentityAddress and ParseResourceSelectors read back.

func LockTask added in v0.10.0

func LockTask(ctx context.Context, task Task) (context.Context, func(), error)

LockTask takes the locks task needs: one for each app or datastore service it changes, on the server ctx targets, waiting while another task holds them. It returns a context recording them and a function that releases them, safe to call more than once. Execute takes the same locks itself, and one under the returned context does not wait on them again; Plan, ReadTask and ExecutePlan take none. Hold them across a Plan and its ExecutePlan so no other task on the same object runs in between.

A context with no lock table locks nothing. A caller whose ctx ends while it waits gets an error wrapping ctx's and holds nothing. Locks are always taken app first, then service, so a nested call needing a lock ordered before one already held - executing a dokku_service_link while holding only its service - returns an error rather than risk a deadlock: lock the task that changes both first.

func ParseIdentityAddress

func ParseIdentityAddress(address string) (string, map[string]string, error)

ParseIdentityAddress parses `dokku_config[app=api]` into its type key and key map. A bare type key parses to an empty map.

func TaskDeprecation

func TaskDeprecation(t Task) string

TaskDeprecation returns t's deprecation notice, or "" when t is current.

func TaskImperative added in v0.10.0

func TaskImperative(t Task) bool

TaskImperative reports whether t runs an operation rather than declaring a resource, so it has nothing to undo.

func TaskSensitiveValues added in v0.9.1

func TaskSensitiveValues(t Task) []string

TaskSensitiveValues returns the values the CLI masks for t before a run: its `sensitive:"true"` fields, including those of nested items, the value of a property marked sensitive, and whatever t's own SensitiveValues method returns. Pass them to NewMasker. Empty values are dropped and duplicates removed; the order is unspecified.

A value only known once the server is read, such as a secret property's current value, is added to the context's masker during Plan.

Example

Building a masker for one task before planning it, so nothing rendered for it carries a secret.

package main

import (
	"fmt"

	"github.com/dokku/docket/sdk"
)

func main() {
	task, err := sdk.DecodeTask("dokku_http_auth_user", []byte(`
app: api
users:
  - username: admin
    password: s3cr3t
`))
	if err != nil {
		panic(err)
	}

	masker := sdk.NewMasker(sdk.TaskSensitiveValues(task)...)
	fmt.Println(masker.String("http-auth:add-user api admin s3cr3t"))
}
Output:
http-auth:add-user api admin ***

func TaskSynopsis

func TaskSynopsis(t Task) string

TaskSynopsis returns t's description, or "" when it has none.

func TaskTypes

func TaskTypes() []string

TaskTypes returns every registered task type, sorted. The slice is the caller's own.

Example
package main

import (
	"fmt"

	"github.com/dokku/docket/sdk"
)

func main() {
	for _, typeKey := range sdk.TaskTypes() {
		task, _ := sdk.Lookup(typeKey)
		if typeKey == "dokku_app" {
			fmt.Println(typeKey, "-", sdk.TaskSynopsis(task))
		}
	}
}
Output:
dokku_app - Creates or destroys an app

func ValidateSSHOptions added in v0.9.1

func ValidateSSHOptions(opts []string) error

ValidateSSHOptions reports whether opts can be a Target's SSHOptions, without contacting anything: each must be non-empty, free of control characters, and must not set an option docket manages itself.

Types

type AclAppTask

type AclAppTask = tasks.AclAppTask

AclAppTask is tasks.AclAppTask.

type AclServiceTask

type AclServiceTask = tasks.AclServiceTask

AclServiceTask is tasks.AclServiceTask.

type AppCloneTask

type AppCloneTask = tasks.AppCloneTask

AppCloneTask is tasks.AppCloneTask.

type AppJsonPropertyTask

type AppJsonPropertyTask = tasks.AppJsonPropertyTask

AppJsonPropertyTask is tasks.AppJsonPropertyTask.

type AppLockTask

type AppLockTask = tasks.AppLockTask

AppLockTask is tasks.AppLockTask.

type AppTask

type AppTask = tasks.AppTask

AppTask is tasks.AppTask.

type AppsPropertyTask

type AppsPropertyTask = tasks.AppsPropertyTask

AppsPropertyTask is tasks.AppsPropertyTask.

type BuilderDockerfilePropertyTask

type BuilderDockerfilePropertyTask = tasks.BuilderDockerfilePropertyTask

BuilderDockerfilePropertyTask is tasks.BuilderDockerfilePropertyTask.

type BuilderHerokuishPropertyTask

type BuilderHerokuishPropertyTask = tasks.BuilderHerokuishPropertyTask

BuilderHerokuishPropertyTask is tasks.BuilderHerokuishPropertyTask.

type BuilderLambdaPropertyTask

type BuilderLambdaPropertyTask = tasks.BuilderLambdaPropertyTask

BuilderLambdaPropertyTask is tasks.BuilderLambdaPropertyTask.

type BuilderNixpacksPropertyTask

type BuilderNixpacksPropertyTask = tasks.BuilderNixpacksPropertyTask

BuilderNixpacksPropertyTask is tasks.BuilderNixpacksPropertyTask.

type BuilderPackPropertyTask

type BuilderPackPropertyTask = tasks.BuilderPackPropertyTask

BuilderPackPropertyTask is tasks.BuilderPackPropertyTask.

type BuilderPropertyTask

type BuilderPropertyTask = tasks.BuilderPropertyTask

BuilderPropertyTask is tasks.BuilderPropertyTask.

type BuilderRailpackPropertyTask

type BuilderRailpackPropertyTask = tasks.BuilderRailpackPropertyTask

BuilderRailpackPropertyTask is tasks.BuilderRailpackPropertyTask.

type BuildpacksPropertyTask

type BuildpacksPropertyTask = tasks.BuildpacksPropertyTask

BuildpacksPropertyTask is tasks.BuildpacksPropertyTask.

type BuildpacksTask

type BuildpacksTask = tasks.BuildpacksTask

BuildpacksTask is tasks.BuildpacksTask.

type BuildsPropertyTask

type BuildsPropertyTask = tasks.BuildsPropertyTask

BuildsPropertyTask is tasks.BuildsPropertyTask.

type CaddyPropertyTask

type CaddyPropertyTask = tasks.CaddyPropertyTask

CaddyPropertyTask is tasks.CaddyPropertyTask.

type CertsTask

type CertsTask = tasks.CertsTask

CertsTask is tasks.CertsTask.

type ChecksPropertyTask

type ChecksPropertyTask = tasks.ChecksPropertyTask

ChecksPropertyTask is tasks.ChecksPropertyTask.

type ChecksToggleTask

type ChecksToggleTask = tasks.ChecksToggleTask

ChecksToggleTask is tasks.ChecksToggleTask.

type ConfigTask

type ConfigTask = tasks.ConfigTask

ConfigTask is tasks.ConfigTask.

type Constraint added in v0.10.0

type Constraint = tasks.Constraint

Constraint is tasks.Constraint.

func TaskConstraints added in v0.10.0

func TaskConstraints(t Task) []Constraint

TaskConstraints returns the rules over several of t's fields, the same ones TaskSchema.Constraints publishes. Nil when t declares none.

type ConstraintKind added in v0.10.0

type ConstraintKind = tasks.ConstraintKind

ConstraintKind is tasks.ConstraintKind.

type CronPropertyTask

type CronPropertyTask = tasks.CronPropertyTask

CronPropertyTask is tasks.CronPropertyTask.

type DockerOptionsTask

type DockerOptionsTask = tasks.DockerOptionsTask

DockerOptionsTask is tasks.DockerOptionsTask.

type DomainsTask

type DomainsTask = tasks.DomainsTask

DomainsTask is tasks.DomainsTask.

type DomainsToggleTask

type DomainsToggleTask = tasks.DomainsToggleTask

DomainsToggleTask is tasks.DomainsToggleTask.

type DynamicPropertySchema

type DynamicPropertySchema = tasks.DynamicPropertySchema

DynamicPropertySchema is tasks.DynamicPropertySchema.

type ExampleSchema

type ExampleSchema = tasks.ExampleSchema

ExampleSchema is tasks.ExampleSchema.

type ExecCommandInput added in v0.9.1

type ExecCommandInput = subprocess.ExecCommandInput

ExecCommandInput is subprocess.ExecCommandInput.

type ExecCommandResponse added in v0.9.1

type ExecCommandResponse = subprocess.ExecCommandResponse

ExecCommandResponse is subprocess.ExecCommandResponse.

type ExecError added in v0.9.1

type ExecError = subprocess.ExecError

ExecError is subprocess.ExecError.

type ExecRunner added in v0.9.1

type ExecRunner = subprocess.ExecRunner

ExecRunner is subprocess.ExecRunner.

type ExportOptions

type ExportOptions = tasks.ExportOptions

ExportOptions is tasks.ExportOptions.

type ExportReport

type ExportReport = tasks.ExportReport

ExportReport is tasks.ExportReport.

type ExportResult

type ExportResult = tasks.ExportResult

ExportResult is tasks.ExportResult.

func ExportRecipe

func ExportRecipe(ctx context.Context, opts ExportOptions) (*ExportResult, error)

ExportRecipe reads the server ctx targets and returns the recipe that describes it. An export that finds nothing is not an error: check Report.MissingApps and Report.MissingResources.

An exporter whose task declares a floor newer than the server is skipped with a warning and listed in Report.VersionErrors. Set ExportOptions.IgnoreVersion to read it anyway.

Example

Reading a server back and picking out one task type.

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/dokku/docket/sdk"
)

func main() {
	session := sdk.NewSession(nil)
	defer func() { _ = session.Close() }()
	ctx := session.Context(context.Background(), sdk.Target{Host: "dokku@dokku.example.com"})

	res, err := sdk.ExportRecipe(ctx, sdk.ExportOptions{Inline: true})
	if err != nil {
		panic(err)
	}

	// Register what the export read before printing anything it produced.
	masker := sdk.NewMasker(res.SensitiveValues()...)
	for _, w := range res.Report.Warnings {
		fmt.Fprintln(os.Stderr, masker.String(w))
	}

	for _, play := range res.Plays() {
		for _, task := range play.Tasks {
			cfg, ok := sdk.As[sdk.ConfigTask](task)
			if !ok {
				continue
			}
			fmt.Println(play.Name, cfg.App, len(cfg.Config))
		}
	}
}

type ExportStatus

type ExportStatus = tasks.ExportStatus

ExportStatus is tasks.ExportStatus.

type ExportSupport

type ExportSupport = tasks.ExportSupport

ExportSupport is tasks.ExportSupport.

func TaskExportSupport

func TaskExportSupport(t Task) (ExportSupport, bool)

TaskExportSupport reports whether ExportRecipe can reconstruct t from a server. The bool is false when t declares nothing.

type ExportedPlay

type ExportedPlay = tasks.ExportedPlay

ExportedPlay is tasks.ExportedPlay.

type ExportedTask

type ExportedTask = tasks.ExportedTask

ExportedTask is tasks.ExportedTask.

type FieldSchema

type FieldSchema = tasks.FieldSchema

FieldSchema is tasks.FieldSchema.

type GitAuthTask

type GitAuthTask = tasks.GitAuthTask

GitAuthTask is tasks.GitAuthTask.

type GitFromArchiveTask

type GitFromArchiveTask = tasks.GitFromArchiveTask

GitFromArchiveTask is tasks.GitFromArchiveTask.

type GitFromImageTask

type GitFromImageTask = tasks.GitFromImageTask

GitFromImageTask is tasks.GitFromImageTask.

type GitPropertyTask

type GitPropertyTask = tasks.GitPropertyTask

GitPropertyTask is tasks.GitPropertyTask.

type GitSyncTask

type GitSyncTask = tasks.GitSyncTask

GitSyncTask is tasks.GitSyncTask.

type HaproxyPropertyTask

type HaproxyPropertyTask = tasks.HaproxyPropertyTask

HaproxyPropertyTask is tasks.HaproxyPropertyTask.

type HttpAuthAllowedIpTask

type HttpAuthAllowedIpTask = tasks.HttpAuthAllowedIpTask

HttpAuthAllowedIpTask is tasks.HttpAuthAllowedIpTask.

type HttpAuthDomainTask

type HttpAuthDomainTask = tasks.HttpAuthDomainTask

HttpAuthDomainTask is tasks.HttpAuthDomainTask.

type HttpAuthTask

type HttpAuthTask = tasks.HttpAuthTask

HttpAuthTask is tasks.HttpAuthTask.

type HttpAuthUser

type HttpAuthUser = tasks.HttpAuthUser

HttpAuthUser is tasks.HttpAuthUser.

type HttpAuthUserTask

type HttpAuthUserTask = tasks.HttpAuthUserTask

HttpAuthUserTask is tasks.HttpAuthUserTask.

type IdentityCollectionSchema

type IdentityCollectionSchema = tasks.IdentityCollectionSchema

IdentityCollectionSchema is tasks.IdentityCollectionSchema.

type IdentitySchema

type IdentitySchema = tasks.IdentitySchema

IdentitySchema is tasks.IdentitySchema.

type ItemIdentity

type ItemIdentity = tasks.ItemIdentity

ItemIdentity is tasks.ItemIdentity.

type ItemSchema

type ItemSchema = tasks.ItemSchema

ItemSchema is tasks.ItemSchema.

type LetsencryptPropertyTask

type LetsencryptPropertyTask = tasks.LetsencryptPropertyTask

LetsencryptPropertyTask is tasks.LetsencryptPropertyTask.

type LetsencryptTask

type LetsencryptTask = tasks.LetsencryptTask

LetsencryptTask is tasks.LetsencryptTask.

type LogsPropertyTask

type LogsPropertyTask = tasks.LogsPropertyTask

LogsPropertyTask is tasks.LogsPropertyTask.

type MaintenanceCustomPageTask

type MaintenanceCustomPageTask = tasks.MaintenanceCustomPageTask

MaintenanceCustomPageTask is tasks.MaintenanceCustomPageTask.

type MaintenanceTask

type MaintenanceTask = tasks.MaintenanceTask

MaintenanceTask is tasks.MaintenanceTask.

type Masker

type Masker = subprocess.Masker

Masker is subprocess.Masker.

func NewMasker

func NewMasker(values ...string) *Masker

NewMasker returns a masker for values.

type NetworkPropertyTask

type NetworkPropertyTask = tasks.NetworkPropertyTask

NetworkPropertyTask is tasks.NetworkPropertyTask.

type NetworkTask

type NetworkTask = tasks.NetworkTask

NetworkTask is tasks.NetworkTask.

type NginxPropertyTask

type NginxPropertyTask = tasks.NginxPropertyTask

NginxPropertyTask is tasks.NginxPropertyTask.

type ObjectEffects added in v0.10.0

type ObjectEffects = tasks.ObjectEffects

ObjectEffects is tasks.ObjectEffects.

type ObjectKind added in v0.10.0

type ObjectKind = tasks.ObjectKind

ObjectKind is tasks.ObjectKind.

type ObjectRestart added in v0.10.0

type ObjectRestart = tasks.ObjectRestart

ObjectRestart is tasks.ObjectRestart.

type ObjectSchema added in v0.10.0

type ObjectSchema = tasks.ObjectSchema

ObjectSchema is tasks.ObjectSchema.

type OpenrestyPropertyTask

type OpenrestyPropertyTask = tasks.OpenrestyPropertyTask

OpenrestyPropertyTask is tasks.OpenrestyPropertyTask.

type PlanResult

type PlanResult = tasks.PlanResult

PlanResult is tasks.PlanResult.

type PlanStatus

type PlanStatus = tasks.PlanStatus

PlanStatus is tasks.PlanStatus.

type PlanWarning

type PlanWarning = tasks.PlanWarning

PlanWarning is tasks.PlanWarning.

type PluginRequirement

type PluginRequirement = tasks.PluginRequirement

PluginRequirement is tasks.PluginRequirement.

type PluginRequirementSchema

type PluginRequirementSchema = tasks.PluginRequirementSchema

PluginRequirementSchema is tasks.PluginRequirementSchema.

type PluginTask

type PluginTask = tasks.PluginTask

PluginTask is tasks.PluginTask.

type PortMapping

type PortMapping = tasks.PortMapping

PortMapping is tasks.PortMapping.

type PortsTask

type PortsTask = tasks.PortsTask

PortsTask is tasks.PortsTask.

type ProbeStatus

type ProbeStatus = tasks.ProbeStatus

ProbeStatus is tasks.ProbeStatus.

type ProbeSupport

type ProbeSupport = tasks.ProbeSupport

ProbeSupport is tasks.ProbeSupport.

func TaskProbeSupport

func TaskProbeSupport(t Task) (ProbeSupport, bool)

TaskProbeSupport reports how much of its own state t's Plan can read back. The bool is false when t declares nothing.

type PropertyEntrySchema

type PropertyEntrySchema = tasks.PropertyEntrySchema

PropertyEntrySchema is tasks.PropertyEntrySchema.

type PropertySchema

type PropertySchema = tasks.PropertySchema

PropertySchema is tasks.PropertySchema.

type ProxyPropertyTask

type ProxyPropertyTask = tasks.ProxyPropertyTask

ProxyPropertyTask is tasks.ProxyPropertyTask.

type ProxyToggleTask

type ProxyToggleTask = tasks.ProxyToggleTask

ProxyToggleTask is tasks.ProxyToggleTask.

type PsPropertyTask

type PsPropertyTask = tasks.PsPropertyTask

PsPropertyTask is tasks.PsPropertyTask.

type PsScaleTask

type PsScaleTask = tasks.PsScaleTask

PsScaleTask is tasks.PsScaleTask.

type RegistryAuthTask

type RegistryAuthTask = tasks.RegistryAuthTask

RegistryAuthTask is tasks.RegistryAuthTask.

type RegistryPropertyTask

type RegistryPropertyTask = tasks.RegistryPropertyTask

RegistryPropertyTask is tasks.RegistryPropertyTask.

type RejectedPropertySchema

type RejectedPropertySchema = tasks.RejectedPropertySchema

RejectedPropertySchema is tasks.RejectedPropertySchema.

type ResourceLimitTask

type ResourceLimitTask = tasks.ResourceLimitTask

ResourceLimitTask is tasks.ResourceLimitTask.

type ResourceReserveTask

type ResourceReserveTask = tasks.ResourceReserveTask

ResourceReserveTask is tasks.ResourceReserveTask.

type ResourceSelector

type ResourceSelector = tasks.ResourceSelector

ResourceSelector is tasks.ResourceSelector.

func ParseResourceSelectors

func ParseResourceSelectors(addresses []string) ([]ResourceSelector, error)

ParseResourceSelectors parses addresses for ExportOptions.Resources. Each must name a registered, exportable task type and only keys it declares.

type Restart added in v0.10.0

type Restart = tasks.Restart

Restart is tasks.Restart.

type SchedulerDockerLocalPropertyTask

type SchedulerDockerLocalPropertyTask = tasks.SchedulerDockerLocalPropertyTask

SchedulerDockerLocalPropertyTask is tasks.SchedulerDockerLocalPropertyTask.

type SchedulerK3sAnnotationsTask

type SchedulerK3sAnnotationsTask = tasks.SchedulerK3sAnnotationsTask

SchedulerK3sAnnotationsTask is tasks.SchedulerK3sAnnotationsTask.

type SchedulerK3sAutoscalingAuthTask

type SchedulerK3sAutoscalingAuthTask = tasks.SchedulerK3sAutoscalingAuthTask

SchedulerK3sAutoscalingAuthTask is tasks.SchedulerK3sAutoscalingAuthTask.

type SchedulerK3sChartTask

type SchedulerK3sChartTask = tasks.SchedulerK3sChartTask

SchedulerK3sChartTask is tasks.SchedulerK3sChartTask.

type SchedulerK3sLabelsTask

type SchedulerK3sLabelsTask = tasks.SchedulerK3sLabelsTask

SchedulerK3sLabelsTask is tasks.SchedulerK3sLabelsTask.

type SchedulerK3sNodeSysctlsTask

type SchedulerK3sNodeSysctlsTask = tasks.SchedulerK3sNodeSysctlsTask

SchedulerK3sNodeSysctlsTask is tasks.SchedulerK3sNodeSysctlsTask.

type SchedulerK3sProfileTask

type SchedulerK3sProfileTask = tasks.SchedulerK3sProfileTask

SchedulerK3sProfileTask is tasks.SchedulerK3sProfileTask.

type SchedulerK3sPropertyTask

type SchedulerK3sPropertyTask = tasks.SchedulerK3sPropertyTask

SchedulerK3sPropertyTask is tasks.SchedulerK3sPropertyTask.

type SchedulerPropertyTask

type SchedulerPropertyTask = tasks.SchedulerPropertyTask

SchedulerPropertyTask is tasks.SchedulerPropertyTask.

type ServiceBackupTask

type ServiceBackupTask = tasks.ServiceBackupTask

ServiceBackupTask is tasks.ServiceBackupTask.

type ServiceCreateTask

type ServiceCreateTask = tasks.ServiceCreateTask

ServiceCreateTask is tasks.ServiceCreateTask.

type ServiceExposeTask

type ServiceExposeTask = tasks.ServiceExposeTask

ServiceExposeTask is tasks.ServiceExposeTask.

type ServiceLinkTask

type ServiceLinkTask = tasks.ServiceLinkTask

ServiceLinkTask is tasks.ServiceLinkTask.

type ServicePropertyTask

type ServicePropertyTask = tasks.ServicePropertyTask

ServicePropertyTask is tasks.ServicePropertyTask.

type Session

type Session = subprocess.Session

Session is subprocess.Session.

func NewSession

func NewSession(masker *Masker, opts ...SessionOption) *Session

NewSession returns a session whose contexts carry masker and whatever opts, such as WithVersionGate, install. A nil masker leaves any masker already on the parent context in place.

Every context the session hands out also carries one lock table, so Execute calls made under the session - from any goroutine - take turns on the same app or datastore service rather than colliding on dokku's deploy lock. See LockTask.

Example

A session installs the masker and target a run needs, and closes the SSH connections made under it.

package main

import (
	"context"

	"github.com/dokku/docket/sdk"
)

func main() {
	session := sdk.NewSession(sdk.NewMasker("s3cr3t"))
	defer func() { _ = session.Close() }()

	ctx := session.Context(context.Background(), sdk.Target{
		Host: "deploy@dokku.example.com",
		Sudo: true,
	})
	_ = ctx
}

type SessionOption added in v0.10.0

type SessionOption = subprocess.SessionOption

SessionOption is subprocess.SessionOption.

func WithVersionGate added in v0.10.0

func WithVersionGate() SessionOption

WithVersionGate is a NewSession option that installs the version gate on every context the session hands out. They share one cache per target for as long as the session lives, so `dokku version` and `plugin:list` are read once per server per session rather than once per call, while each context keeps the cancellation of the parent it was built from. Only a successful read is cached; a failed one is retried by the next call. Each session gets its own cache, and the session's gate replaces one already on the parent context.

Example

A session given the version gate refuses tasks the server is too old for, and reads the server's versions once however many calls it serves, each with a context of its own.

package main

import (
	"context"

	"github.com/dokku/docket/sdk"
)

func main() {
	session := sdk.NewSession(nil, sdk.WithVersionGate())
	defer func() { _ = session.Close() }()

	serve := func(reqCtx context.Context) {
		ctx := session.Context(reqCtx, sdk.Target{Host: "deploy@dokku.example.com"})
		_ = ctx
	}
	serve(context.Background())
	serve(context.Background())
}

type SshKeyTask

type SshKeyTask = tasks.SshKeyTask

SshKeyTask is tasks.SshKeyTask.

type State

type State = tasks.State

State is tasks.State.

type StorageEnsureTask

type StorageEnsureTask = tasks.StorageEnsureTask

StorageEnsureTask is tasks.StorageEnsureTask.

type StorageEntryTask

type StorageEntryTask = tasks.StorageEntryTask

StorageEntryTask is tasks.StorageEntryTask.

type StorageMount

type StorageMount = tasks.StorageMount

StorageMount is tasks.StorageMount.

type StorageMountTask

type StorageMountTask = tasks.StorageMountTask

StorageMountTask is tasks.StorageMountTask.

type Target

type Target = subprocess.Target

Target is subprocess.Target.

type Task

type Task = tasks.Task

Task is tasks.Task.

func DecodeTask

func DecodeTask(typeKey string, body []byte) (Task, error)

DecodeTask builds a task of the registered type typeKey from a YAML task body, with defaults applied.

func Lookup

func Lookup(typeKey string) (Task, bool)

Lookup reports whether typeKey is a registered task type and, when it is, returns a new zero-value instance of it for reading metadata. It has no defaults applied; use NewTask for a task to run.

func NewTask

func NewTask(typeKey string) (Task, error)

NewTask returns a new task of the registered type typeKey, such as "dokku_app", with its `default:` values applied. Use it rather than a struct literal, which leaves State as "" instead of the default the field documents.

The task is a pointer to the registered type, so fields are set through a type assertion:

task, err := sdk.NewTask("dokku_app")
app := task.(*sdk.AppTask)
app.App = "api"
Example
package main

import (
	"fmt"

	"github.com/dokku/docket/sdk"
)

func main() {
	task, err := sdk.NewTask("dokku_app")
	if err != nil {
		panic(err)
	}
	app := task.(*sdk.AppTask)
	app.App = "api"

	fmt.Println(sdk.IdentityAddress("dokku_app", app), app.State)
}
Output:
dokku_app[app=api] present

func ReadAddress added in v0.10.0

func ReadAddress(ctx context.Context, address string) (Task, bool, error)

ReadAddress returns the resource an identity address names, such as `dokku_buildpacks[app=api]`, as it exists on the server, and whether it exists, from the address alone; nothing is applied. It reads every member the resource has, the way a task in state set or clear would own them: a dokku_config leaves out the keys docket keeps (linked-service DSNs, NO_VHOST, the git rev env var), and a dokku_ps_scale leaves out process types scaled to zero. The returned task and errors are ReadTask's: the value type registered for the task, the *VersionError when ctx carries a gate the server is behind, and an error wrapping ErrStateUnreadable for a task whose probe cannot read its state.

The address must name one resource. A bare type, a key the task does not declare, or a missing required key is an error, raised before the server is contacted. IdentityAddress renders the address of a task you hold.

Example

Reading a resource known only by its identity address, such as one being imported, reads every member it has.

package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/dokku/docket/sdk"
)

func main() {
	ctx := sdk.ContextWithRunner(context.Background(), func(_ context.Context, in sdk.ExecCommandInput) (sdk.ExecCommandResponse, error) {
		switch strings.Join(in.Args, " ") {
		case "version":
			return sdk.ExecCommandResponse{Stdout: "dokku version 0.38.31"}, nil
		case "--quiet buildpacks:list api":
			return sdk.ExecCommandResponse{Stdout: "=====> api buildpack urls\nhttps://github.com/heroku/heroku-buildpack-nodejs.git"}, nil
		}
		return sdk.ExecCommandResponse{}, nil
	})
	ctx = sdk.ContextWithVersionGate(ctx)

	current, exists, err := sdk.ReadAddress(ctx, "dokku_buildpacks[app=api]")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(exists, current.(sdk.BuildpacksTask).Buildpacks)
}
Output:
true [https://github.com/heroku/heroku-buildpack-nodejs.git]

func ReadTask added in v0.9.2

func ReadTask(ctx context.Context, task Task) (Task, bool, error)

ReadTask returns task as it exists on the server, and whether the resource exists, from a single Plan; nothing is applied. The returned task is the value type registered for task (AppTask, not *AppTask), carrying the identity keys from task and every field the server reports. Fields whose catalog entry is WriteOnly or ApplyOnly are left empty or at their default.

task must be a valid task: its State picks which members of a collection are read, so a dokku_config in state present reads the keys it names, and one in state set reads every key it would own. A property task known only by its identity keys is read with State absent, which needs no Value.

When ctx carries a version gate and the server is older than task's floor, the error is the *VersionError, never a resource reported as absent. A task whose probe cannot read its state returns an error wrapping ErrStateUnreadable.

Example

Reading one resource's current state through its task, without exporting the server.

package main

import (
	"context"
	"errors"
	"fmt"
	"strings"

	"github.com/dokku/docket/sdk"
)

func main() {
	ctx := sdk.ContextWithRunner(context.Background(), func(_ context.Context, in sdk.ExecCommandInput) (sdk.ExecCommandResponse, error) {
		switch strings.Join(in.Args, " ") {
		case "version":
			return sdk.ExecCommandResponse{Stdout: "dokku version 0.38.31"}, nil
		case "--quiet config:export --format json api":
			return sdk.ExecCommandResponse{Stdout: `{"LOG_LEVEL":"debug","OTHER":"x"}`}, nil
		}
		return sdk.ExecCommandResponse{}, nil
	})
	ctx = sdk.ContextWithVersionGate(ctx)

	task, _ := sdk.NewTask("dokku_config")
	cfg := task.(*sdk.ConfigTask)
	cfg.App = "api"
	cfg.Config = map[string]string{"LOG_LEVEL": "info"}

	current, exists, err := sdk.ReadTask(ctx, cfg)
	var verr *sdk.VersionError
	if errors.As(err, &verr) {
		fmt.Println("server too old for", verr.TaskType)
		return
	}
	if err != nil {
		fmt.Println(err)
		return
	}
	observed := current.(sdk.ConfigTask)
	fmt.Println(exists, observed.Config)
}
Output:
true map[LOG_LEVEL:debug]

type TaskCatalog

type TaskCatalog = tasks.TaskCatalog

TaskCatalog is tasks.TaskCatalog.

func Catalog

func Catalog() (TaskCatalog, error)

Catalog describes every registered task type. It is what `docket schema` emits.

func CatalogFor

func CatalogFor(typeKeys []string) (TaskCatalog, error)

CatalogFor describes only the given task types. An unregistered type is an error.

Example
package main

import (
	"fmt"

	"github.com/dokku/docket/sdk"
)

func main() {
	catalog, err := sdk.CatalogFor([]string{"dokku_app"})
	if err != nil {
		panic(err)
	}
	for _, schema := range catalog.Tasks {
		fmt.Println(schema.Type, "-", schema.Synopsis)
	}
}
Output:
dokku_app - Creates or destroys an app

type TaskObject added in v0.10.0

type TaskObject = tasks.TaskObject

TaskObject is tasks.TaskObject.

func TaskObjects added in v0.10.0

func TaskObjects(t Task) []TaskObject

TaskObjects returns the app and the datastore service t changes, app first: the recipe keys naming each and the values t holds for them, whether t creates it, and when t restarts or redeploys it. The catalog publishes the same data as TaskSchema.Objects. Nil when t changes neither.

type TaskOutputState

type TaskOutputState = tasks.TaskOutputState

TaskOutputState is tasks.TaskOutputState.

func ExecutePlan

func ExecutePlan(ctx context.Context, p PlanResult) TaskOutputState

ExecutePlan applies p, the result of a task's Plan, without probing the server again. A plan that is already in sync applies nothing.

type TaskSchema

type TaskSchema = tasks.TaskSchema

TaskSchema is tasks.TaskSchema.

type TraefikPropertyTask

type TraefikPropertyTask = tasks.TraefikPropertyTask

TraefikPropertyTask is tasks.TraefikPropertyTask.

type VersionError added in v0.9.1

type VersionError = tasks.VersionError

VersionError is tasks.VersionError.

type VersionSupport

type VersionSupport = tasks.VersionSupport

VersionSupport is tasks.VersionSupport.

func TaskMinimumVersions added in v0.9.1

func TaskMinimumVersions(t Task) (VersionSupport, bool)

TaskMinimumVersions reports the oldest Dokku, and the plugins, t declares it runs on. The bool is false when t declares nothing.

type Violation added in v0.10.0

type Violation = tasks.Violation

Violation is one declared field constraint a task breaks. Field is the recipe key path at fault, such as `users[1].hash`; for a rule over several keys it is the path of the element the rule sits on, empty for the task itself.

func ConstraintViolations added in v0.10.0

func ConstraintViolations(t Task) []Violation

ConstraintViolations returns every declared field constraint t breaks - the required_when and forbidden_when of each field, the task's Constraints, and those of each element of its structured lists - or nil when it satisfies them all. A task's Validate and Plan reject the first of these; this reports them all at once, as `docket validate` does.

Jump to

Keyboard shortcuts

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