Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Grant Linville <[email protected]>
  • Loading branch information
g-linville committed Sep 20, 2024
1 parent 8ecad90 commit fd91f37
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 24 deletions.
2 changes: 1 addition & 1 deletion pkg/credentials/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func NewStore(cfg *config.CLIConfig, credentialBuilder CredentialBuilder, credCt
return Store{
credCtxs: credCtxs,
credBuilder: credentialBuilder,
credHelperDirs: GetCredentialHelperDirs(cacheDir),
credHelperDirs: GetCredentialHelperDirs(cacheDir, cfg.CredentialsStore),
cfg: cfg,
}, nil
}
Expand Down
32 changes: 28 additions & 4 deletions pkg/credentials/util.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,42 @@
package credentials

import (
"fmt"
"path/filepath"

runtimeEnv "github.com/gptscript-ai/gptscript/pkg/env"
)

type CredentialHelperDirs struct {
RevisionFile, LastCheckedFile, BinDir string
}

func GetCredentialHelperDirs(cacheDir string) CredentialHelperDirs {
func RepoNameForCredentialStore(store string) string {
switch store {
case "sqlite":
return "gptscript-credential-sqlite"
default:
return "gptscript-credential-helpers"
}
}

func GitURLForRepoName(repoName string) (string, error) {
switch repoName {
case "gptscript-credential-sqlite":
return runtimeEnv.VarOrDefault("GPTSCRIPT_CRED_SQLITE_ROOT", "https://github.com/gptscript-ai/gptscript-credential-sqlite.git"), nil
case "gptscript-credential-helpers":
return runtimeEnv.VarOrDefault("GPTSCRIPT_CRED_HELPERS_ROOT", "https://github.com/gptscript-ai/gptscript-credential-helpers.git"), nil
default:
return "", fmt.Errorf("unknown repo name: %s", repoName)
}
}

func GetCredentialHelperDirs(cacheDir, store string) CredentialHelperDirs {
repoName := RepoNameForCredentialStore(store)
return CredentialHelperDirs{
RevisionFile: filepath.Join(cacheDir, "repos", "gptscript-credential-helpers", "revision"),
LastCheckedFile: filepath.Join(cacheDir, "repos", "gptscript-credential-helpers", "last-checked"),
BinDir: filepath.Join(cacheDir, "repos", "gptscript-credential-helpers", "bin"),
RevisionFile: filepath.Join(cacheDir, "repos", repoName, "revision"),
LastCheckedFile: filepath.Join(cacheDir, "repos", repoName, "last-checked"),
BinDir: filepath.Join(cacheDir, "repos", repoName, "bin"),
}
}

Expand Down
46 changes: 27 additions & 19 deletions pkg/repos/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/BurntSushi/locker"
"github.com/gptscript-ai/gptscript/pkg/config"
"github.com/gptscript-ai/gptscript/pkg/credentials"
runtimeEnv "github.com/gptscript-ai/gptscript/pkg/env"
"github.com/gptscript-ai/gptscript/pkg/hash"
"github.com/gptscript-ai/gptscript/pkg/repos/git"
"github.com/gptscript-ai/gptscript/pkg/repos/runtimes/golang"
Expand Down Expand Up @@ -55,10 +54,10 @@ func (n noopRuntime) Setup(_ context.Context, _ types.Tool, _, _ string, _ []str
}

type Manager struct {
cacheDir string
storageDir string
gitDir string
runtimeDir string
credHelperDirs credentials.CredentialHelperDirs
runtimes []Runtime
credHelperConfig *credHelperConfig
}
Expand All @@ -72,11 +71,11 @@ type credHelperConfig struct {
func New(cacheDir string, runtimes ...Runtime) *Manager {
root := filepath.Join(cacheDir, "repos")
return &Manager{
storageDir: root,
gitDir: filepath.Join(root, "git"),
runtimeDir: filepath.Join(root, "runtimes"),
credHelperDirs: credentials.GetCredentialHelperDirs(cacheDir),
runtimes: runtimes,
cacheDir: cacheDir,
storageDir: root,
gitDir: filepath.Join(root, "git"),
runtimeDir: filepath.Join(root, "runtimes"),
runtimes: runtimes,
}
}

Expand Down Expand Up @@ -120,40 +119,49 @@ func (m *Manager) deferredSetUpCredentialHelpers(ctx context.Context, cliCfg *co
distInfo = fmt.Sprintf("-%s-%s", runtime.GOOS, runtime.GOARCH)
}

locker.Lock("gptscript-credential-helpers")
defer locker.Unlock("gptscript-credential-helpers")
repoName := credentials.RepoNameForCredentialStore(helperName)

locker.Lock(repoName)
defer locker.Unlock(repoName)

credHelperDirs := credentials.GetCredentialHelperDirs(m.cacheDir, helperName)

// Load the last-checked file to make sure we haven't checked the repo in the last 24 hours.
now := time.Now()
lastChecked, err := os.ReadFile(m.credHelperDirs.LastCheckedFile)
lastChecked, err := os.ReadFile(credHelperDirs.LastCheckedFile)
if err == nil {
if t, err := time.Parse(time.RFC3339, strings.TrimSpace(string(lastChecked))); err == nil && now.Sub(t) < 24*time.Hour {
// Make sure the binary still exists, and if it does, return.
if _, err := os.Stat(filepath.Join(m.credHelperDirs.BinDir, "gptscript-credential-"+helperName+suffix)); err == nil {
if _, err := os.Stat(filepath.Join(credHelperDirs.BinDir, "gptscript-credential-"+helperName+suffix)); err == nil {
log.Debugf("Credential helper %s up-to-date as of %v, checking for updates after %v", helperName, t, t.Add(24*time.Hour))
return nil
}
}
}

if err := os.MkdirAll(filepath.Dir(m.credHelperDirs.LastCheckedFile), 0755); err != nil {
if err := os.MkdirAll(filepath.Dir(credHelperDirs.LastCheckedFile), 0755); err != nil {
return err
}

// Update the last-checked file.
if err := os.WriteFile(m.credHelperDirs.LastCheckedFile, []byte(now.Format(time.RFC3339)), 0644); err != nil {
if err := os.WriteFile(credHelperDirs.LastCheckedFile, []byte(now.Format(time.RFC3339)), 0644); err != nil {
return err
}

gitURL, err := credentials.GitURLForRepoName(repoName)
if err != nil {
return err
}

tool := types.Tool{
ToolDef: types.ToolDef{
Parameters: types.Parameters{
Name: "gptscript-credential-helpers",
Name: repoName,
},
},
Source: types.ToolSource{
Repo: &types.Repo{
Root: runtimeEnv.VarOrDefault("GPTSCRIPT_CRED_HELPERS_ROOT", "https://github.com/gptscript-ai/gptscript-credential-helpers.git"),
Root: gitURL,
},
},
}
Expand All @@ -164,12 +172,12 @@ func (m *Manager) deferredSetUpCredentialHelpers(ctx context.Context, cliCfg *co

var needsDownloaded bool
// Check the last revision shasum and see if it is different from the current one.
lastRevision, err := os.ReadFile(m.credHelperDirs.RevisionFile)
lastRevision, err := os.ReadFile(credHelperDirs.RevisionFile)
if (err == nil && strings.TrimSpace(string(lastRevision)) != tool.Source.Repo.Root+tag) || errors.Is(err, fs.ErrNotExist) {
// Need to pull the latest version.
needsDownloaded = true
// Update the revision file to the new revision.
if err = os.WriteFile(m.credHelperDirs.RevisionFile, []byte(tool.Source.Repo.Root+tag), 0644); err != nil {
if err = os.WriteFile(credHelperDirs.RevisionFile, []byte(tool.Source.Repo.Root+tag), 0644); err != nil {
return err
}
} else if err != nil {
Expand All @@ -179,15 +187,15 @@ func (m *Manager) deferredSetUpCredentialHelpers(ctx context.Context, cliCfg *co
if !needsDownloaded {
// Check for the existence of the credential helper binary.
// If it's there, we have no need to download it and can just return.
if _, err = os.Stat(filepath.Join(m.credHelperDirs.BinDir, "gptscript-credential-"+helperName+suffix)); err == nil {
if _, err = os.Stat(filepath.Join(credHelperDirs.BinDir, "gptscript-credential-"+helperName+suffix)); err == nil {
return nil
}
}

// Find the Go runtime and use it to build the credential helper.
for _, rt := range m.runtimes {
if strings.HasPrefix(rt.ID(), "go") {
return rt.(*golang.Runtime).DownloadCredentialHelper(ctx, tool, helperName, distInfo, suffix, m.credHelperDirs.BinDir)
return rt.(*golang.Runtime).DownloadCredentialHelper(ctx, tool, helperName, distInfo, suffix, credHelperDirs.BinDir)
}
}

Expand Down

0 comments on commit fd91f37

Please sign in to comment.