Documentation
¶
Overview ¶
Package setup performs setup tasks and records metadata about when they're run.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrAlreadyRefused = errors.New("already refused by user")
ErrAlreadyRefused indicates that no confirmation prompt was shown because the user previously refused to run the task. Call Reset to re-prompt the user for confirmation.
var ErrUserRefused = errors.New("user refused run")
ErrUserRefused indicates that the user responded no to an interactive confirmation prompt.
Functions ¶
func ConfirmRun ¶
Run interactively prompts the user to confirm that it's ok to run a setup task. It only prompts the user if the task's NeedsRun method returns true. If the user refuses to run the task, then ConfirmPrompt will not ask them again. Call Reset to reset the task's state and re-prompt the user.
func Reset ¶
func Reset(key string)
Reset removes a task's state so that it acts as if it has never run.
func Run ¶
Run runs a setup task and stores its state under a given key. Keys are namespaced by user. It only calls the task's Run method when NeedsRun returns true.
func SudoDevbox ¶
SudoDevbox relaunches Devbox as root using sudo, taking care to preserve Devbox environment variables that can affect the new process. If the current user is already root, then it returns (false, nil) to indicate that no sudo process ran. The caller can use this as a hint to know if it's running as the sudoed process. Typical usage is:
func (*ConfigTask) Run(context.Context) error { ran, err := SudoDevbox(ctx, "cache", "configure") if ran || err != nil { // return early if we kicked off a sudo process or there // was an error return err } // do things as root } ConfirmRun(ctx, key, &ConfigTask{}, "Allow sudo to run Devbox as root?")
A task that calls SudoDevbox should pass command arguments that cause the new Devbox process to rerun the task. The task executes unconditionally within the sudo process without re-prompting the user or a second call to its NeedsRun method.
Types ¶
type RunInfo ¶
type RunInfo struct { // Time is the last time the task ran. Time time.Time `json:"time"` // Version is the version of Devbox that last ran the task. Version string `json:"version"` // Error is the error message returned by the last run. It's empty if // the last run succeeded. Error string `json:"error,omitempty"` }
RunInfo contains metadata that describes the most recent run of a task.
type Task ¶
type Task interface { Run(ctx context.Context) error // NeedsRun returns true if the task needs to be run. It should assume // that lastRun persists across executions of the program and is unique // for each user. // // A task that should only run once can check if lastRun.Time is the zero value. // A task that only runs after an update can check if lastRun.Version < build.Version. // A retryable task can check lastRun.Error to see if the previous run failed. NeedsRun(ctx context.Context, lastRun RunInfo) bool }
Task is a setup action that can conditionally run based on the state of a previous run.
type TaskStatus ¶
type TaskStatus int
TaskStatus describes the status of a task.
const ( // TaskDone indicates that a task doesn't need to run and that its most // recent run (if any) didn't report an error. Note that a task can be // done without ever running if its NeedsRun method returns false before // the first run. TaskDone TaskStatus = iota // TaskNeedsRun is the status of a task that needs to be run. TaskNeedsRun // TaskUserRefused indicates that the user answered no to a confirmation // prompt to run the task. TaskUserRefused // TaskError indicates that a task's most recent run failed and it // cannot be re-run without a call to [Reset]. TaskError // TaskSudoing occurs when the caller of [Status] is running in a sudoed // process due to the task calling [SudoDevbox] from the parent process. TaskSudoing )