Skip to content

Commit 3246587

Browse files
authored
[cache] Use jetify caches (#2072)
## Summary The main change this PR does is that it considers jetify read caches when determining if a given store path is in binary cache. It loops though all caches (default nix cache, jetify provided caches) and if it finds a path in any one of them, we know output is in binary cache. It also changes the fetch nar info function so that it stores which cache each output is in since we may now use multiple caches. List of changes: * `fetchNarInfoStatusOnce` now checks all caches and returns which cache each output is in. * Moved in memory cache to be at the request level instead of output level. This is more efficient because the meta-output `__default_output__ ` can now propertly use the request cache. * Changed providers to be true singletons. * Small improvements to flake template to prepare for each output using own cache. (Currently there's a hack in there where we always use nix cache as `fromStore` even if not correct. See comment in code. ## How was it tested? Installed `https://github.com/Lagoja/terraform-test` and confirmed cache was used.
1 parent 99c7921 commit 3246587

File tree

20 files changed

+396
-246
lines changed

20 files changed

+396
-246
lines changed

internal/boxcli/auth.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func loginCmd() *cobra.Command {
3838
Short: "Login to devbox",
3939
Args: cobra.ExactArgs(0),
4040
RunE: func(cmd *cobra.Command, args []string) error {
41-
c, err := identity.Get().AuthClient()
41+
c, err := identity.AuthClient()
4242
if err != nil {
4343
return err
4444
}
@@ -62,7 +62,7 @@ func logoutCmd() *cobra.Command {
6262
Short: "Logout from devbox",
6363
Args: cobra.ExactArgs(0),
6464
RunE: func(cmd *cobra.Command, args []string) error {
65-
c, err := identity.Get().AuthClient()
65+
c, err := identity.AuthClient()
6666
if err != nil {
6767
return err
6868
}
@@ -123,7 +123,7 @@ func authNewTokenCommand() *cobra.Command {
123123
Args: cobra.ExactArgs(0),
124124
RunE: func(cmd *cobra.Command, args []string) error {
125125
ctx := cmd.Context()
126-
token, err := identity.Get().GenSession(ctx)
126+
token, err := identity.GenSession(ctx)
127127
if err != nil {
128128
return err
129129
}

internal/boxcli/cache.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func cacheConfigureCmd() *cobra.Command {
8989
u, _ := user.Current()
9090
username = u.Username
9191
}
92-
return nixcache.Get().ConfigureReprompt(cmd.Context(), username)
92+
return nixcache.ConfigureReprompt(cmd.Context(), username)
9393
},
9494
}
9595
cmd.Flags().StringVar(&username, "user", "", "")
@@ -104,7 +104,7 @@ func cacheCredentialsCmd() *cobra.Command {
104104
Hidden: true,
105105
Args: cobra.ExactArgs(0),
106106
RunE: func(cmd *cobra.Command, args []string) error {
107-
creds, err := nixcache.Get().Credentials(cmd.Context())
107+
creds, err := nixcache.CachedCredentials(cmd.Context())
108108
if err != nil {
109109
return err
110110
}
@@ -136,7 +136,7 @@ func cacheInfoCmd() *cobra.Command {
136136
RunE: func(cmd *cobra.Command, args []string) error {
137137
// TODO(gcurtis): We can also output info about the daemon config status
138138
// here
139-
caches, err := nixcache.Get().Caches(cmd.Context())
139+
caches, err := nixcache.Caches(cmd.Context())
140140
if err != nil {
141141
return err
142142
}

internal/boxcli/pull.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func pullCmdFunc(cmd *cobra.Command, url string, flags *pullCmdFlags) error {
6565
}
6666

6767
var creds devopt.Credentials
68-
t, err := identity.Get().GenSession(cmd.Context())
68+
t, err := identity.GenSession(cmd.Context())
6969
if err != nil && !errors.Is(err, auth.ErrNotLoggedIn) {
7070
return errors.WithStack(err)
7171
} else if t != nil && err == nil {

internal/boxcli/push.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func pushCmdFunc(cmd *cobra.Command, url string, flags pushCmdFlags) error {
4444
if err != nil {
4545
return errors.WithStack(err)
4646
}
47-
t, err := identity.Get().GenSession(cmd.Context())
47+
t, err := identity.GenSession(cmd.Context())
4848
var creds devopt.Credentials
4949
if err != nil && !errors.Is(err, auth.ErrNotLoggedIn) {
5050
return errors.WithStack(err)

internal/devbox/cache.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77

88
"go.jetpack.io/devbox/internal/boxcli/usererr"
9+
"go.jetpack.io/devbox/internal/devbox/providers/identity"
910
"go.jetpack.io/devbox/internal/devbox/providers/nixcache"
1011
"go.jetpack.io/devbox/internal/nix"
1112
"go.jetpack.io/devbox/internal/ux"
@@ -18,13 +19,13 @@ func (d *Devbox) UploadProjectToCache(
1819
) error {
1920
if cacheURI == "" {
2021
var err error
21-
cacheURI, err = getWriteCacheURI(ctx, d.stderr, d.providers.NixCache)
22+
cacheURI, err = getWriteCacheURI(ctx, d.stderr)
2223
if err != nil {
2324
return err
2425
}
2526
}
2627

27-
creds, err := d.providers.NixCache.Credentials(ctx)
28+
creds, err := nixcache.CachedCredentials(ctx)
2829
if err != nil && !errors.Is(err, auth.ErrNotLoggedIn) {
2930
return err
3031
}
@@ -50,13 +51,13 @@ func UploadInstallableToCache(
5051
) error {
5152
if cacheURI == "" {
5253
var err error
53-
cacheURI, err = getWriteCacheURI(ctx, stderr, *nixcache.Get())
54+
cacheURI, err = getWriteCacheURI(ctx, stderr)
5455
if err != nil {
5556
return err
5657
}
5758
}
5859

59-
creds, err := nixcache.Get().Credentials(ctx)
60+
creds, err := nixcache.CachedCredentials(ctx)
6061
if err != nil && !errors.Is(err, auth.ErrNotLoggedIn) {
6162
return err
6263
}
@@ -66,9 +67,13 @@ func UploadInstallableToCache(
6667
func getWriteCacheURI(
6768
ctx context.Context,
6869
w io.Writer,
69-
provider nixcache.Provider,
7070
) (string, error) {
71-
caches, err := provider.WriteCaches(ctx)
71+
_, err := identity.GenSession(ctx)
72+
if errors.Is(err, auth.ErrNotLoggedIn) {
73+
return "",
74+
usererr.New("You must be logged in to upload to a Nix cache.")
75+
}
76+
caches, err := nixcache.WriteCaches(ctx)
7277
if err != nil {
7378
return "", err
7479
}

internal/devbox/devbox.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"go.jetpack.io/devbox/internal/cachehash"
2828
"go.jetpack.io/devbox/internal/devbox/envpath"
2929
"go.jetpack.io/devbox/internal/devbox/generate"
30-
"go.jetpack.io/devbox/internal/devbox/providers"
3130
"go.jetpack.io/devbox/internal/devpkg"
3231
"go.jetpack.io/devbox/internal/devpkg/pkgtype"
3332
"go.jetpack.io/devbox/internal/searcher"
@@ -66,7 +65,6 @@ type Devbox struct {
6665
lockfile *lock.File
6766
nix nix.Nixer
6867
projectDir string
69-
providers providers.Providers
7068
pluginManager *plugin.Manager
7169
preservePathStack bool
7270
pure bool

internal/devbox/packages.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/pkg/errors"
2121
"github.com/samber/lo"
2222
"go.jetpack.io/devbox/internal/devbox/devopt"
23+
"go.jetpack.io/devbox/internal/devbox/providers/nixcache"
2324
"go.jetpack.io/devbox/internal/devconfig"
2425
"go.jetpack.io/devbox/internal/devconfig/configfile"
2526
"go.jetpack.io/devbox/internal/devpkg"
@@ -447,7 +448,7 @@ func (d *Devbox) installNixPackagesToStore(ctx context.Context, mode installMode
447448
Flags: flags,
448449
Writer: d.stderr,
449450
}
450-
caches, err := d.providers.NixCache.ReadCaches(ctx)
451+
caches, err := nixcache.CachedReadCaches(ctx)
451452
if err != nil {
452453
debug.Log("error getting nix cache URI, assuming user doesn't have access: %v", err)
453454
}
@@ -460,7 +461,7 @@ func (d *Devbox) installNixPackagesToStore(ctx context.Context, mode installMode
460461
// TODO (Landau): handle errors that are not auth.ErrNotLoggedIn
461462
// Only lookup credentials if we have a cache to use
462463
if len(args.ExtraSubstituters) > 0 {
463-
creds, err := d.providers.NixCache.Credentials(ctx)
464+
creds, err := nixcache.CachedCredentials(ctx)
464465
if err == nil {
465466
args.Env = creds.Env()
466467
}
@@ -470,7 +471,7 @@ func (d *Devbox) installNixPackagesToStore(ctx context.Context, mode installMode
470471
err = redact.Errorf("lookup current user: %v", err)
471472
debug.Log("error configuring cache: %v", err)
472473
}
473-
err = d.providers.NixCache.Configure(ctx, u.Username)
474+
err = nixcache.Configure(ctx, u.Username)
474475
if err != nil {
475476
debug.Log("error configuring cache: %v", err)
476477

internal/devbox/providers/doc.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// providers encapsulates data and/or logic that can affect devbox behavior.
2+
// What a provider does can be influenced by the environment or external services.
3+
// The goal is to centralize this logic and avoid conditionals in core devbox code.
4+
// In the future we should allow dynamic providers as well which can help
5+
// customize devbox behavior.
6+
package providers

internal/devbox/providers/identity/identity.go

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,26 @@ import (
1515

1616
var scopes = []string{"openid", "offline_access", "email", "profile"}
1717

18-
type Provider struct {
19-
cachedAccessTokenFromAPIToken *session.Token
20-
}
21-
22-
var singleton *Provider = &Provider{}
23-
24-
func Get() *Provider {
25-
return singleton
26-
}
18+
var cachedAccessTokenFromAPIToken *session.Token
2719

28-
func (p *Provider) GenSession(ctx context.Context) (*session.Token, error) {
29-
if t, err := p.getAccessTokenFromAPIToken(ctx); err != nil || t != nil {
20+
func GenSession(ctx context.Context) (*session.Token, error) {
21+
if t, err := getAccessTokenFromAPIToken(ctx); err != nil || t != nil {
3022
return t, err
3123
}
3224

33-
c, err := p.AuthClient()
25+
c, err := AuthClient()
3426
if err != nil {
3527
return nil, err
3628
}
3729
return c.GetSession(ctx)
3830
}
3931

40-
func (p *Provider) Peek() (*session.Token, error) {
41-
if p.cachedAccessTokenFromAPIToken != nil {
42-
return p.cachedAccessTokenFromAPIToken, nil
32+
func Peek() (*session.Token, error) {
33+
if cachedAccessTokenFromAPIToken != nil {
34+
return cachedAccessTokenFromAPIToken, nil
4335
}
4436

45-
c, err := p.AuthClient()
37+
c, err := AuthClient()
4638
if err != nil {
4739
return nil, err
4840
}
@@ -58,7 +50,7 @@ func (p *Provider) Peek() (*session.Token, error) {
5850
return tokens[0].Peek(), nil
5951
}
6052

61-
func (p *Provider) AuthClient() (*auth.Client, error) {
53+
func AuthClient() (*auth.Client, error) {
6254
return auth.NewClient(
6355
build.Issuer(),
6456
build.ClientID(),
@@ -68,32 +60,34 @@ func (p *Provider) AuthClient() (*auth.Client, error) {
6860
)
6961
}
7062

71-
func (p *Provider) getAccessTokenFromAPIToken(
63+
func getAccessTokenFromAPIToken(
7264
ctx context.Context,
7365
) (*session.Token, error) {
74-
apiTokenRaw := os.Getenv("DEVBOX_API_TOKEN")
75-
if apiTokenRaw == "" {
76-
return nil, nil
77-
}
78-
79-
apiToken, err := typeid.Parse[ids.APIToken](apiTokenRaw)
80-
if err != nil {
81-
return nil, err
82-
}
83-
84-
apiClient := api.NewClient(ctx, build.JetpackAPIHost(), &session.Token{})
85-
response, err := apiClient.GetAccessToken(ctx, apiToken)
86-
if err != nil {
87-
return nil, err
88-
}
89-
90-
// This is not the greatest. This token is missing id, refresh, etc.
91-
// It may be better to change api.NewClient() to take a token string instead.
92-
p.cachedAccessTokenFromAPIToken = &session.Token{
93-
Token: oauth2.Token{
94-
AccessToken: response.AccessToken,
95-
},
66+
if cachedAccessTokenFromAPIToken == nil {
67+
apiTokenRaw := os.Getenv("DEVBOX_API_TOKEN")
68+
if apiTokenRaw == "" {
69+
return nil, nil
70+
}
71+
72+
apiToken, err := typeid.Parse[ids.APIToken](apiTokenRaw)
73+
if err != nil {
74+
return nil, err
75+
}
76+
77+
apiClient := api.NewClient(ctx, build.JetpackAPIHost(), &session.Token{})
78+
response, err := apiClient.GetAccessToken(ctx, apiToken)
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
// This is not the greatest. This token is missing id, refresh, etc.
84+
// It may be better to change api.NewClient() to take a token string instead.
85+
cachedAccessTokenFromAPIToken = &session.Token{
86+
Token: oauth2.Token{
87+
AccessToken: response.AccessToken,
88+
},
89+
}
9690
}
9791

98-
return p.cachedAccessTokenFromAPIToken, nil
92+
return cachedAccessTokenFromAPIToken, nil
9993
}

0 commit comments

Comments
 (0)