add documentation about S3 container, fix S3 configration

This commit is contained in:
Lawrence, Rendall
2025-09-22 15:49:50 +03:00
parent 7b80ed199a
commit febe60b069
3 changed files with 48 additions and 13 deletions

View File

@@ -28,6 +28,11 @@ There are two sources of hashes: `list` and `directory`.
files at start and then periodically watch for new files to add, or for delete events
to remove hash from storage.
* `s3` will search for torrent files in specified S3-compatible storage (AWS S3, MinIO, etc.) and
append/delete records from storage. This source will parse all existing
files at start and then periodically watch for new files to add, or for delete events
to remove hash from storage.
Note: if storage is not `memory`, and `preserve` option set to `true`, records
will be persisted in storage until _somebody_ or _something_ (different tool with access
to storage) won't delete it.
@@ -48,7 +53,21 @@ If `name` is empty or `internal` global storage will be used
- `directory`:
- `path` - directory to watch
- `period` - time between two directory checks
- `invert` and `storage_ctx` has the same meanins as `list`'s options
- `invert` and `storage_ctx` has the same meaning as `list`'s options
- `s3`:
- `endpoint`* - base URL of S3 provider
- `region`* - S3 region to connect to
- `key_id`* - S3 access key ID
- `key_secret`* - S3 secret access key
- `session_token`* - S3 temporary security credential
- `bucket` - S3 bucket
- `prefix` - prefix path to search entries
- `suffix` - suffix to filter returned entries, such as extension (e.g. `.torrent`)
- `period` - time between two S3 checks
- `invert` and `storage_ctx` has the same meaning as `list`'s options
Note: `s3` options marked with `*` and any other specific options can be omitted in MoChi and can be provided
with environment variables or in `$HOME/.aws/*` files (see [AWS SDK documentation](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-gosdk.html)).
Configuration example:

View File

@@ -5,6 +5,7 @@ package s3
import (
"context"
"errors"
"fmt"
"io"
"iter"
@@ -34,9 +35,9 @@ type Config struct {
list.Config
Endpoint string
Region string
KeyID string
KeySecret string
SessionToken string
KeyID string `cfg:"key_id"`
KeySecret string `cfg:"key_secret"`
SessionToken string `cfg:"session_token"`
Bucket string
Prefix string
Suffix string
@@ -52,6 +53,11 @@ func build(conf conf.MapConfig, st storage.DataStorage) (container.Container, er
if err := conf.Unmarshal(c); err != nil {
return nil, fmt.Errorf("unable to deserialise configuration: %w", err)
}
if len(c.Bucket) == 0 {
return nil, errors.New("no bucket provided")
}
if c.Period == 0 {
logger.Warn().
Str("name", "Period").
@@ -61,25 +67,35 @@ func build(conf conf.MapConfig, st storage.DataStorage) (container.Container, er
c.Period = defaultPeriod
}
awsCfg, err := config.LoadDefaultConfig(context.Background())
if err != nil {
return nil, fmt.Errorf("unable load AWS S3 SDK configuration: %w", err)
}
modifiers := make([]func(*config.LoadOptions) error, 1, 4)
awsCfg.Logger = logging.LoggerFunc(func(classification logging.Classification, format string, v ...interface{}) {
modifiers[0] = config.WithLogger(logging.LoggerFunc(func(
classification logging.Classification, format string, v ...interface{},
) {
if classification == logging.Debug {
logger.Debug().CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...))
} else if classification == logging.Warn {
logger.Warn().CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...))
}
})
}))
if len(c.Endpoint) > 0 {
awsCfg.BaseEndpoint = &c.Endpoint
modifiers = append(modifiers, config.WithBaseEndpoint(c.Endpoint))
}
if len(c.Region) > 0 {
awsCfg.Region = c.Region
modifiers = append(modifiers, config.WithRegion(c.Endpoint))
}
if len(c.KeyID) > 0 || len(c.KeySecret) > 0 || len(c.SessionToken) > 0 {
modifiers = append(modifiers, config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(c.KeyID, c.KeySecret, c.SessionToken)),
)
}
awsCfg, err := config.LoadDefaultConfig(context.Background(), modifiers...)
if err != nil {
return nil, fmt.Errorf("unable load AWS S3 SDK configuration: %w", err)
}
if len(c.KeyID) > 0 || len(c.KeySecret) > 0 || len(c.SessionToken) > 0 {

View File

@@ -57,7 +57,7 @@ emDE8BsT0R1/0GVl`),
}
func init() {
_ = log.ConfigureLogger("", "debug", false, false)
_ = log.ConfigureLogger("", "warn", false, false)
}
type mockS3 struct {