Skip to content

Commit 7fbe589

Browse files
committed
feat: add s3 and simplify API
Signed-off-by: Donnie Adams <[email protected]>
1 parent 77a99fe commit 7fbe589

22 files changed

+1066
-1229
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
1-
# workspace-provider
1+
# workspace-provider
2+
3+
There are two providers that can be used to create and manage workspaces: directory and S3.
4+
5+
## Directory
6+
7+
The directory provider provides a directory-based workspace. This provider is used by default.
8+
9+
## S3
10+
11+
The S3 provider provides a S3-based workspace.
12+
13+
This provider supports loading the default AWS configuration. You can control this configuration using the following environment variables:
14+
- `AWS_ACCESS_KEY_ID`
15+
- `AWS_SECRET_ACCESS_KEY`
16+
- `AWS_REGION`
17+
18+
You must set the following environment variables:
19+
- `WORKSPACE_PROVIDER_S3_BUCKET`
20+
21+
### Usage with S3-compatible providers (e.g. Cloudflare R2)
22+
23+
You can use the above referenced AWS environment variables to configure the S3 provider, setting the value of the environment variable to the corresponding value from your provider.
24+
Additionally, you should also set the `WORKSPACE_PROVIDER_S3_BASE_ENDPOINT` environment variable to the endpoint of your provider. For example, if you are using Cloudflare R2, you can set `WORKSPACE_PROVIDER_S3_BASE_ENDPOINT` to `https://<ACCOUND_ID>.r2.cloudflarestorage.com`.

go.mod

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,31 @@ go 1.23.2
44

55
require (
66
github.com/adrg/xdg v0.5.0
7+
github.com/aws/aws-sdk-go-v2 v1.32.2
8+
github.com/aws/aws-sdk-go-v2/config v1.27.43
9+
github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3
710
github.com/google/uuid v1.6.0
811
github.com/gptscript-ai/cmd v0.0.0-20240907001148-ffd49061124a
912
github.com/gptscript-ai/go-gptscript v0.9.5-rc3.0.20240820135702-14a861da41fa
1013
github.com/spf13/cobra v1.8.1
1114
)
1215

1316
require (
17+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect
18+
github.com/aws/aws-sdk-go-v2/credentials v1.17.41 // indirect
19+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 // indirect
20+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect
21+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect
22+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
23+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect
24+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
25+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect
26+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect
27+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect
28+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 // indirect
29+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 // indirect
30+
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 // indirect
31+
github.com/aws/smithy-go v1.22.0 // indirect
1432
github.com/getkin/kin-openapi v0.124.0 // indirect
1533
github.com/go-openapi/jsonpointer v0.20.2 // indirect
1634
github.com/go-openapi/swag v0.22.8 // indirect

go.sum

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
11
github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
22
github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4=
3+
github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI=
4+
github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
5+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0=
6+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA=
7+
github.com/aws/aws-sdk-go-v2/config v1.27.43 h1:p33fDDihFC390dhhuv8nOmX419wjOSDQRb+USt20RrU=
8+
github.com/aws/aws-sdk-go-v2/config v1.27.43/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc=
9+
github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8=
10+
github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU=
11+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 h1:TMH3f/SCAWdNtXXVPPu5D6wrr4G5hI1rAxbcocKfC7Q=
12+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17/go.mod h1:1ZRXLdTpzdJb9fwTMXiLipENRxkGMTn1sfKexGllQCw=
13+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk=
14+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y=
15+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s=
16+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60=
17+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
18+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
19+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE=
20+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ=
21+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
22+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
23+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4=
24+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw=
25+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA=
26+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0=
27+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg=
28+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM=
29+
github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 h1:xxHGZ+wUgZNACQmxtdvP5tgzfsxGS3vPpTP5Hy3iToE=
30+
github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8=
31+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 h1:bSYXVyUzoTHoKalBmwaZxs97HU9DWWI3ehHSAMa7xOk=
32+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2/go.mod h1:skMqY7JElusiOUjMJMOv1jJsP7YUg7DrhgqZZWuzu1U=
33+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 h1:AhmO1fHINP9vFYUE0LHzCWg/LfUWUF+zFPEcY9QXb7o=
34+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2/go.mod h1:o8aQygT2+MVP0NaV6kbdE1YnnIM8RRVQzoeUH45GOdI=
35+
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 h1:CiS7i0+FUe+/YY1GvIBLLrR/XNGZ4CtM1Ll0XavNuVo=
36+
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2/go.mod h1:HtaiBI8CjYoNVde8arShXb94UbQQi9L4EMr6D+xGBwo=
37+
github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM=
38+
github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
339
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
440
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
541
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

pkg/cli/cpfile.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,14 @@ package cli
22

33
import (
44
"context"
5-
"io"
65
"os"
76
"path/filepath"
87

9-
"github.com/gptscript-ai/workspace-provider/pkg/client"
108
"github.com/spf13/cobra"
119
)
1210

1311
type cpFile struct {
1412
root *workspaceProvider
15-
16-
client.WriteOptions
1713
}
1814

1915
func (c *cpFile) Customize(cmd *cobra.Command) {
@@ -40,12 +36,5 @@ func (c *cpFile) copyFile(ctx context.Context, workspaceID, src string) error {
4036
}
4137
defer source.Close()
4238

43-
file, err := c.root.client.WriteFile(ctx, workspaceID, filepath.Base(src), c.WriteOptions)
44-
if err != nil {
45-
return err
46-
}
47-
defer file.Close()
48-
49-
_, err = io.Copy(file, source)
50-
return err
39+
return c.root.client.WriteFile(ctx, workspaceID, filepath.Base(src), source)
5140
}

pkg/cli/ls.go

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
package cli
22

33
import (
4-
"encoding/json"
54
"fmt"
5+
"strings"
66

7-
"github.com/gptscript-ai/workspace-provider/pkg/client"
87
"github.com/spf13/cobra"
98
)
109

1110
type ls struct {
1211
root *workspaceProvider
1312

14-
client.LsOptions
15-
JSON bool `usage:"Output as JSON" env:"LS_JSON"`
13+
Prefix string `usage:"Only list files with this prefix" env:"LS_PREFIX"`
1614
}
1715

1816
func (l *ls) Customize(c *cobra.Command) {
@@ -22,42 +20,20 @@ func (l *ls) Customize(c *cobra.Command) {
2220
}
2321

2422
func (l *ls) Run(cmd *cobra.Command, args []string) error {
25-
var workspaceContents []client.WorkspaceContent
2623
for _, arg := range args {
27-
contents, err := l.root.client.Ls(cmd.Context(), arg, l.LsOptions)
24+
contents, err := l.root.client.Ls(cmd.Context(), arg, l.Prefix)
2825
if err != nil {
2926
return err
3027
}
3128

32-
if l.JSON {
33-
workspaceContents = append(workspaceContents, contents)
34-
continue
35-
}
36-
37-
printContent(contents)
38-
}
39-
40-
if l.JSON {
41-
b, err := json.Marshal(workspaceContents)
42-
if err != nil {
43-
return fmt.Errorf("failed to marshal workspace contents: %w", err)
44-
}
45-
46-
fmt.Println(string(b))
29+
printContent(arg, contents)
4730
}
4831

4932
return nil
5033
}
5134

52-
func printContent(content client.WorkspaceContent) {
53-
fmt.Printf("%s:\n", content.ID)
54-
fmt.Printf("%s:\n", content.Path)
55-
for _, child := range content.Children {
56-
if child.FileName != "" {
57-
fmt.Printf("%s\n", child.FileName)
58-
} else if child.Path != "" {
59-
printContent(child)
60-
}
61-
}
35+
func printContent(id string, content []string) {
36+
fmt.Printf("%s:\n", id)
37+
fmt.Println(strings.Join(content, "\n"))
6238
fmt.Print("\n\n")
6339
}

pkg/cli/mkdir.go

Lines changed: 0 additions & 32 deletions
This file was deleted.

pkg/cli/removewithprefix.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/spf13/cobra"
7+
)
8+
9+
type removeAllWithPrefix struct {
10+
root *workspaceProvider
11+
}
12+
13+
func (r *removeAllWithPrefix) Customize(c *cobra.Command) {
14+
c.Args = cobra.MinimumNArgs(2)
15+
c.Use = "rm-with-prefix [OPTIONS] ID PREFIX..."
16+
c.Short = "Remove all files with a given prefix"
17+
}
18+
19+
func (r *removeAllWithPrefix) Run(cmd *cobra.Command, args []string) error {
20+
workspaceID := args[0]
21+
for _, arg := range args[1:] {
22+
if err := r.root.client.RemoveAllWithPrefix(cmd.Context(), workspaceID, arg); err != nil {
23+
return err
24+
}
25+
26+
fmt.Printf("files with prefix %s deleted from workspace %s\n", arg, args[0])
27+
}
28+
29+
return nil
30+
}

pkg/cli/rm.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
package cli
22

33
import (
4-
"errors"
54
"fmt"
65
"strings"
76

8-
"github.com/gptscript-ai/workspace-provider/pkg/client"
97
"github.com/spf13/cobra"
108
)
119

1210
type rm struct {
13-
root *workspaceProvider
14-
IgnoreNotFound bool `usage:"Ignore not found errors"`
11+
root *workspaceProvider
1512
}
1613

1714
func (r *rm) Customize(c *cobra.Command) {
@@ -31,11 +28,6 @@ func (r *rm) Run(cmd *cobra.Command, args []string) error {
3128
for _, arg := range args {
3229
fmt.Println(arg)
3330
if err := r.root.client.Rm(cmd.Context(), arg); err != nil {
34-
var notFound *client.WorkspaceNotFoundError
35-
if r.IgnoreNotFound && errors.As(err, &notFound) {
36-
fmt.Printf("workspace %s not found\n", arg)
37-
continue
38-
}
3931
return err
4032
}
4133

pkg/cli/rmdir.go

Lines changed: 0 additions & 41 deletions
This file was deleted.

pkg/cli/rmfile.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
package cli
22

33
import (
4-
"errors"
54
"fmt"
65

7-
"github.com/gptscript-ai/workspace-provider/pkg/client"
86
"github.com/spf13/cobra"
97
)
108

119
type rmFile struct {
1210
root *workspaceProvider
13-
14-
IgnoreNotFound bool `usage:"Ignore not found errors"`
1511
}
1612

1713
func (r *rmFile) Customize(c *cobra.Command) {
@@ -24,11 +20,6 @@ func (r *rmFile) Run(cmd *cobra.Command, args []string) error {
2420
workspaceID := args[0]
2521
for _, arg := range args[1:] {
2622
if err := r.root.client.DeleteFile(cmd.Context(), workspaceID, arg); err != nil {
27-
var notFound *client.FileNotFoundError
28-
if r.IgnoreNotFound && errors.As(err, &notFound) {
29-
fmt.Printf("file %s not found in workspace %s\n", arg, workspaceID)
30-
continue
31-
}
3223
return err
3324
}
3425

0 commit comments

Comments
 (0)