Skip to content

Commit b9eee59

Browse files
authored
nixcache: don't check Jetify caches if they're not configured (#2096)
nixcache: don't check Jetify caches if they're not configured Don't check the Jetify Nix caches for store paths if Nix isn't configured to use them. This can happen if the user says "no" to the confirmation prompt for cache setup. Otherwise, `nix build` prints an error about the path missing: $ devbox add [email protected] Info: Adding package "[email protected]" to devbox.json ? You're logged into a Devbox account that now has access to a Nix cache. Allow Devbox to configure Nix to use the new cache (requires sudo)? No Info: Skipping cache setup. Run `devbox cache configure` to enable the cache at a later time. Info: Installing the following packages to the nix store: [email protected] error: path '/nix/store/n7fkj8vif9yc1g063r0z88j5dh3i7p8a-mongodb-6.0.15' is required, but there is no substituter that can build it
1 parent 8e8cfc1 commit b9eee59

File tree

3 files changed

+72
-11
lines changed

3 files changed

+72
-11
lines changed

internal/devbox/providers/nixcache/setup.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ import (
2121
"go.jetpack.io/devbox/internal/ux"
2222
)
2323

24+
const setupKey = "nixcache-setup"
25+
26+
func IsConfigured(ctx context.Context) bool {
27+
u, err := user.Current()
28+
if err != nil {
29+
return false
30+
}
31+
task := &setupTask{u.Username}
32+
status := setup.Status(ctx, setupKey, task)
33+
return status == setup.TaskDone
34+
}
35+
2436
func Configure(ctx context.Context) error {
2537
u, err := user.Current()
2638
if err != nil {
@@ -34,15 +46,14 @@ func ConfigureReprompt(ctx context.Context, username string) error {
3446
}
3547

3648
func configure(ctx context.Context, username string, reprompt bool) error {
37-
const key = "nixcache-setup"
3849
if reprompt {
39-
setup.Reset(key)
50+
setup.Reset(setupKey)
4051
}
4152

4253
task := &setupTask{username}
4354
const sudoPrompt = "You're logged into a Devbox account that now has access to a Nix cache. " +
4455
"Allow Devbox to configure Nix to use the new cache (requires sudo)?"
45-
err := setup.ConfirmRun(ctx, key, task, sudoPrompt)
56+
err := setup.ConfirmRun(ctx, setupKey, task, sudoPrompt)
4657
if err != nil {
4758
return redact.Errorf("nixcache: run setup: %w", err)
4859
}

internal/devpkg/narinfo_cache.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ func fetchNarInfoStatusFromS3(
341341

342342
func readCaches(ctx context.Context) ([]string, error) {
343343
cacheURIs := []string{binaryCache}
344+
if !nixcache.IsConfigured(ctx) {
345+
return cacheURIs, nil
346+
}
347+
344348
otherCaches, err := nixcache.CachedReadCaches(ctx)
345349
if err != nil {
346350
return nil, err

internal/setup/setup.go

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,50 @@ type RunInfo struct {
6666
Error string `json:"error,omitempty"`
6767
}
6868

69+
// TaskStatus describes the status of a task.
70+
type TaskStatus int
71+
72+
const (
73+
// TaskDone indicates that a task doesn't need to run and that its most
74+
// recent run (if any) didn't report an error. Note that a task can be
75+
// done without ever running if its NeedsRun method returns false before
76+
// the first run.
77+
TaskDone TaskStatus = iota
78+
79+
// TaskNeedsRun is the status of a task that needs to be run.
80+
TaskNeedsRun
81+
82+
// TaskUserRefused indicates that the user answered no to a confirmation
83+
// prompt to run the task.
84+
TaskUserRefused
85+
86+
// TaskError indicates that a task's most recent run failed and it
87+
// cannot be re-run without a call to [Reset].
88+
TaskError
89+
90+
// TaskSudoing occurs when the caller of [Status] is running in a sudoed
91+
// process due to the task calling [SudoDevbox] from the parent process.
92+
TaskSudoing
93+
)
94+
95+
// Status returns the status of a setup task.
96+
func Status(ctx context.Context, key string, task Task) TaskStatus {
97+
state := loadState(key)
98+
switch {
99+
case isSudo(key):
100+
return TaskSudoing
101+
case state.ConfirmPrompt.Asked && !state.ConfirmPrompt.Allowed:
102+
return TaskUserRefused
103+
case task.NeedsRun(ctx, state.LastRun):
104+
return TaskNeedsRun
105+
case state.LastRun.Error == "":
106+
return TaskDone
107+
case state.LastRun.Error != "":
108+
return TaskError
109+
}
110+
panic("setup.Status switch isn't exhaustive")
111+
}
112+
69113
// Run runs a setup task and stores its state under a given key. Keys are
70114
// namespaced by user. It only calls the task's Run method when NeedsRun returns
71115
// true.
@@ -190,14 +234,7 @@ var defaultPrompt = func(msg string) (response any, err error) {
190234
func run(ctx context.Context, key string, task Task, prompt string) error {
191235
ctx = context.WithValue(ctx, ctxKeyTask, key)
192236

193-
// DEVBOX_SUDO_TASK is set when a task relaunched Devbox by calling
194-
// SudoDevbox. If it matches the current task key, then the pre-sudo
195-
// process is already running this task and we can skip checking
196-
// task.NeedsRun and prompting the user.
197-
isSudo := false
198-
if envTask := os.Getenv("DEVBOX_SUDO_TASK"); envTask != "" {
199-
isSudo = envTask == key
200-
}
237+
isSudo := isSudo(key)
201238
state := loadState(key)
202239
if !isSudo && !task.NeedsRun(ctx, state.LastRun) {
203240
return nil
@@ -346,3 +383,12 @@ func devboxExecutable() (string, error) {
346383
}
347384
return exe, nil
348385
}
386+
387+
func isSudo(key string) bool {
388+
// DEVBOX_SUDO_TASK is set when a task relaunched Devbox by calling
389+
// SudoDevbox. If it matches the current task key, then the pre-sudo
390+
// process is already running this task and we can skip checking
391+
// task.NeedsRun and prompting the user.
392+
envTask := os.Getenv("DEVBOX_SUDO_TASK")
393+
return envTask != "" && envTask == key
394+
}

0 commit comments

Comments
 (0)