Skip to content

Commit 4e1d63a

Browse files
committed
feat(rst): add xtreemstore provider
1 parent 04b449d commit 4e1d63a

5 files changed

Lines changed: 107 additions & 11 deletions

File tree

common/rst/rst.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ func New(ctx context.Context, config *flex.RemoteStorageTarget, mountPoint files
152152
switch config.Type.(type) {
153153
case *flex.RemoteStorageTarget_S3_:
154154
return newS3(ctx, config, mountPoint)
155+
case *flex.RemoteStorageTarget_Xtreemstore:
156+
return newXtreemstore(ctx, config, mountPoint)
155157
case *flex.RemoteStorageTarget_Mock:
156158
// This handles setting up a Mock RST for testing from external packages like WorkerMgr. See
157159
// the documentation ion `MockClient` in mock.go for how to setup expectations.

common/rst/xtreemstore.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package rst
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/aws/aws-sdk-go-v2/service/s3"
8+
smithyhttp "github.com/aws/smithy-go/transport/http"
9+
"github.com/thinkparq/beegfs-go/common/filesystem"
10+
"github.com/thinkparq/protobuf/go/beeremote"
11+
"github.com/thinkparq/protobuf/go/flex"
12+
)
13+
14+
type xtreemstoreS3Provider struct {
15+
s3Provider
16+
s3ApiClient
17+
}
18+
19+
var _ Provider = &xtreemstoreS3Provider{}
20+
21+
// newXtreemstore initializes an xtreemstore provider by reusing the S3 client implementation.
22+
func newXtreemstore(ctx context.Context, rstConfig *flex.RemoteStorageTarget, mountPoint filesystem.Provider) (Provider, error) {
23+
xtreemstore := rstConfig.GetXtreemstore()
24+
if xtreemstore == nil || xtreemstore.GetS3() == nil {
25+
return nil, fmt.Errorf("xtreemstore configuration must include s3 settings")
26+
}
27+
28+
wrapper := &xtreemstoreS3Provider{}
29+
provider, err := newS3WithOptions(ctx, rstConfig, xtreemstore.GetS3(), mountPoint,
30+
withS3ApiClient(func(base s3ApiClient) s3ApiClient {
31+
wrapper.s3ApiClient = base
32+
return wrapper
33+
}),
34+
withS3Provider(func(base s3Provider) s3Provider {
35+
wrapper.s3Provider = base
36+
return wrapper
37+
}),
38+
)
39+
if err != nil {
40+
return nil, fmt.Errorf("unable to initialize xtreemstore provider: %w", err)
41+
}
42+
43+
return provider, nil
44+
}
45+
46+
func (x *xtreemstoreS3Provider) HeadObject(ctx context.Context, in *s3.HeadObjectInput, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error) {
47+
// Update xtreemstore head-object api request headers to include storage details.
48+
optFns = append(optFns, func(options *s3.Options) {
49+
options.APIOptions = append(options.APIOptions, smithyhttp.AddHeaderValue("x-amz-meta-xts-request-storage-details", "true"))
50+
})
51+
52+
return x.s3ApiClient.HeadObject(ctx, in, optFns...)
53+
}
54+
55+
func (x *xtreemstoreS3Provider) IncludeInBulkRequest(ctx context.Context, request *beeremote.JobRequest) (includeInBulk bool) {
56+
return false
57+
}
58+
59+
func (x *xtreemstoreS3Provider) BuildBulkRequest(ctx context.Context) (submitBulkRequest SubmitBulkRequestFn, appendBulkRequestCfg AppendBulkRequestCfgFn, err error) {
60+
return nil, nil, nil
61+
}

common/rst/xtreemstore_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package rst

ctl/internal/cmd/rst/list.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,16 @@ func runListCmd(cmd *cobra.Command, cfg rst.GetRSTCfg) error {
5252

5353
switch rst.WhichType() {
5454
case flex.RemoteStorageTarget_S3_case:
55-
stringBuilder := strings.Builder{}
5655
rstType = "s3"
57-
rst.GetS3().ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
58-
if string(fd.Name()) == "secret_key" && !cfg.ShowSecrets {
59-
stringBuilder.WriteString(fmt.Sprintf("%s: *****, ", fd.Name()))
60-
} else {
61-
stringBuilder.WriteString(fmt.Sprintf("%s: %s, ", fd.Name(), v))
62-
}
63-
return true
64-
})
65-
// Get rid of the last comma+space in the printed configuration.
66-
rstConfiguration = stringBuilder.String()[:stringBuilder.Len()-2]
56+
rstConfiguration = formatS3RSTConfiguration(rst.GetS3(), cfg.ShowSecrets)
57+
case flex.RemoteStorageTarget_Xtreemstore_case:
58+
rstType = "xtreemstore"
59+
xtreemstoreConfig := rst.GetXtreemstore()
60+
if xtreemstoreConfig == nil {
61+
rstConfiguration = "xtreemstore configuration is not set"
62+
break
63+
}
64+
rstConfiguration = formatS3RSTConfiguration(xtreemstoreConfig.GetS3(), cfg.ShowSecrets)
6765
default:
6866
if !cfg.ShowSecrets {
6967
rstType = "unknown"
@@ -85,3 +83,25 @@ func runListCmd(cmd *cobra.Command, cfg rst.GetRSTCfg) error {
8583

8684
return nil
8785
}
86+
87+
func formatS3RSTConfiguration(s3Config *flex.RemoteStorageTarget_S3, showSecrets bool) string {
88+
if s3Config == nil {
89+
return "s3 configuration is not set"
90+
}
91+
92+
stringBuilder := strings.Builder{}
93+
s3Config.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
94+
if string(fd.Name()) == "secret_key" && !showSecrets {
95+
fmt.Fprintf(&stringBuilder, "%s: *****, ", fd.Name())
96+
} else {
97+
fmt.Fprintf(&stringBuilder, "%s: %s, ", fd.Name(), v)
98+
}
99+
return true
100+
})
101+
102+
if stringBuilder.Len() == 0 {
103+
return ""
104+
}
105+
// Get rid of the last comma+space in the printed configuration.
106+
return stringBuilder.String()[:stringBuilder.Len()-2]
107+
}

rst/remote/build/beegfs-remote.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ path-db = "/var/lib/beegfs/remote/path.badger"
107107
# access-key = "<ACCESS_KEY>"
108108
# secret-key = "<SECRET_KEY>"
109109

110+
# [[remote-storage-target]]
111+
# id = "4"
112+
# name = "xtreemstore"
113+
# policies = { FastStartMaxSize = 104857600 }
114+
#
115+
# [remote-storage-target.xtreemstore]
116+
# endpoint-url = "https://<XTREEMSTORE_ENDPOINT>:<PORT>"
117+
# region = "<REGION>"
118+
# bucket = "<BUCKET>"
119+
# access-key = "<ACCESS_KEY>"
120+
# secret-key = "<SECRET_KEY>"
121+
110122
#
111123
# --- Section 2: [Command Line Arguments] ---
112124
#

0 commit comments

Comments
 (0)