diff --git a/docs/configuration.md b/docs/configuration.md index d5e04ba3..6c046b48 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -139,6 +139,7 @@ storage: multipartcopythresholdsize: 33554432 rootdirectory: /s3/object/name/prefix usedualstack: false + loglevel: debug inmemory: # This driver takes no parameters delete: enabled: false @@ -410,6 +411,7 @@ storage: multipartcopymaxconcurrency: 100 multipartcopythresholdsize: 33554432 rootdirectory: /s3/object/name/prefix + loglevel: debug inmemory: delete: enabled: false diff --git a/docs/storage-drivers/s3.md b/docs/storage-drivers/s3.md index 3122a897..fa9ab72d 100644 --- a/docs/storage-drivers/s3.md +++ b/docs/storage-drivers/s3.md @@ -26,6 +26,7 @@ Amazon S3 or S3 compatible services for object storage. | `rootdirectory` | no | This is a prefix that is applied to all S3 keys to allow you to segment data in your bucket if necessary. | | `storageclass` | no | The S3 storage class applied to each registry file. The default is `STANDARD`. | | `objectacl` | no | The S3 Canned ACL for objects. The default value is "private". | +| `loglevel` | no | The log level for the S3 client. The default value is `off`. | > **Note** You can provide empty strings for your access and secret keys to run the driver > on an ec2 instance and handles authentication with the instance's credentials. If you @@ -56,6 +57,7 @@ Amazon S3 or S3 compatible services for object storage. `objectacl`: (optional) The canned object ACL to be applied to each registry object. Defaults to `private`. If you are using a bucket owned by another AWS account, it is recommended that you set this to `bucket-owner-full-control` so that the bucket owner can access your objects. Other valid options are available in the [AWS S3 documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl). +`loglevel`: (optional) Valid values are: `off` (default), `debug`, `debugwithsigning`, `debugwithhttpbody`, `debugwithrequestretries`, `debugwithrequesterrors` and `debugwitheventstreambody`. See the [AWS SDK for Go API reference](https://docs.aws.amazon.com/sdk-for-go/api/aws/#LogLevelType) for details. ## S3 permission scopes diff --git a/registry/storage/driver/s3-aws/s3.go b/registry/storage/driver/s3-aws/s3.go index 3df5e5b3..46e53194 100644 --- a/registry/storage/driver/s3-aws/s3.go +++ b/registry/storage/driver/s3-aws/s3.go @@ -117,6 +117,7 @@ type DriverParameters struct { SessionToken string UseDualStack bool Accelerate bool + LogLevel aws.LogLevelType } func init() { @@ -461,11 +462,39 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) { fmt.Sprint(sessionToken), useDualStackBool, accelerateBool, + getS3LogLevelFromParam(parameters["loglevel"]), } return New(params) } +func getS3LogLevelFromParam(param interface{}) aws.LogLevelType { + if param == nil { + return aws.LogOff + } + logLevelParam := param.(string) + var logLevel aws.LogLevelType + switch strings.ToLower(logLevelParam) { + case "off": + logLevel = aws.LogOff + case "debug": + logLevel = aws.LogDebug + case "debugwithsigning": + logLevel = aws.LogDebugWithSigning + case "debugwithhttpbody": + logLevel = aws.LogDebugWithHTTPBody + case "debugwithrequestretries": + logLevel = aws.LogDebugWithRequestRetries + case "debugwithrequesterrors": + logLevel = aws.LogDebugWithRequestErrors + case "debugwitheventstreambody": + logLevel = aws.LogDebugWithEventStreamBody + default: + logLevel = aws.LogOff + } + return logLevel +} + // getParameterAsInt64 converts parameters[name] to an int64 value (using // defaultt if nil), verifies it is no smaller than min, and returns it. func getParameterAsInt64(parameters map[string]interface{}, name string, defaultt int64, min int64, max int64) (int64, error) { @@ -504,7 +533,7 @@ func New(params DriverParameters) (*Driver, error) { return nil, fmt.Errorf("on Amazon S3 this storage driver can only be used with v4 authentication") } - awsConfig := aws.NewConfig() + awsConfig := aws.NewConfig().WithLogLevel(params.LogLevel) if params.AccessKey != "" && params.SecretKey != "" { creds := credentials.NewStaticCredentials( diff --git a/registry/storage/driver/s3-aws/s3_test.go b/registry/storage/driver/s3-aws/s3_test.go index 4987c52d..5851d665 100644 --- a/registry/storage/driver/s3-aws/s3_test.go +++ b/registry/storage/driver/s3-aws/s3_test.go @@ -21,8 +21,10 @@ import ( "github.com/distribution/distribution/v3/registry/storage/driver/testsuites" ) -var s3DriverConstructor func(rootDirectory, storageClass string) (*Driver, error) -var skipS3 func() string +var ( + s3DriverConstructor func(rootDirectory, storageClass string) (*Driver, error) + skipS3 func() string +) func init() { var ( @@ -42,6 +44,7 @@ func init() { useDualStack = os.Getenv("S3_USE_DUALSTACK") combineSmallPart = os.Getenv("MULTIPART_COMBINE_SMALL_PART") accelerate = os.Getenv("S3_ACCELERATE") + logLevel = os.Getenv("S3_LOGLEVEL") ) root, err := os.MkdirTemp("", "driver-") @@ -135,6 +138,7 @@ func init() { sessionToken, useDualStackBool, accelerateBool, + getS3LogLevelFromParam(logLevel), } return New(parameters)