Skip to content

Commit

Permalink
Add header for lifecycle config expiry to ignore replication
Browse files Browse the repository at this point in the history
  • Loading branch information
poornas committed Sep 15, 2024
1 parent b1f8dd0 commit da4e7b5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 14 deletions.
31 changes: 19 additions & 12 deletions api-bucket-lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,36 @@ func (c *Client) SetBucketLifecycle(ctx context.Context, bucketName string, conf
if config.Empty() {
return c.removeBucketLifecycle(ctx, bucketName)
}

expIgnoreRepl := config.ExpiryIgnoreReplication
config.ExpiryIgnoreReplication = ""
buf, err := xml.Marshal(config)
if err != nil {
return err
}

// Save the updated lifecycle.
return c.putBucketLifecycle(ctx, bucketName, buf)
return c.putBucketLifecycle(ctx, bucketName, buf, expIgnoreRepl)
}

// Saves a new bucket lifecycle.
func (c *Client) putBucketLifecycle(ctx context.Context, bucketName string, buf []byte) error {
func (c *Client) putBucketLifecycle(ctx context.Context, bucketName string, buf []byte, expIgnoreRepl string) error {
// Get resources properly escaped and lined up before
// using them in http request.
urlValues := make(url.Values)
urlValues.Set("lifecycle", "")

var cheaders http.Header
if expIgnoreRepl != "" {
cheaders = make(http.Header)
cheaders.Set(minioLifecycleExpiryIgnoreReplication, expIgnoreRepl)
}
// Content-length is mandatory for put lifecycle request
reqMetadata := requestMetadata{
bucketName: bucketName,
queryValues: urlValues,
contentBody: bytes.NewReader(buf),
contentLength: int64(len(buf)),
contentMD5Base64: sumMD5Base64(buf),
customHeader: cheaders,
}

// Execute PUT to upload a new bucket lifecycle.
Expand Down Expand Up @@ -114,7 +120,7 @@ func (c *Client) GetBucketLifecycleWithInfo(ctx context.Context, bucketName stri
return nil, time.Time{}, err
}

bucketLifecycle, updatedAt, err := c.getBucketLifecycle(ctx, bucketName)
bucketLifecycle, updatedAt, expIgnoreRepl, err := c.getBucketLifecycle(ctx, bucketName)
if err != nil {
return nil, time.Time{}, err
}
Expand All @@ -123,11 +129,12 @@ func (c *Client) GetBucketLifecycleWithInfo(ctx context.Context, bucketName stri
if err = xml.Unmarshal(bucketLifecycle, config); err != nil {
return nil, time.Time{}, err
}
config.ExpiryIgnoreReplication = expIgnoreRepl
return config, updatedAt, nil
}

// Request server for current bucket lifecycle.
func (c *Client) getBucketLifecycle(ctx context.Context, bucketName string) ([]byte, time.Time, error) {
func (c *Client) getBucketLifecycle(ctx context.Context, bucketName string) ([]byte, time.Time, string, error) {
// Get resources properly escaped and lined up before
// using them in http request.
urlValues := make(url.Values)
Expand All @@ -142,28 +149,28 @@ func (c *Client) getBucketLifecycle(ctx context.Context, bucketName string) ([]b

defer closeResponse(resp)
if err != nil {
return nil, time.Time{}, err
return nil, time.Time{}, "", err
}

if resp != nil {
if resp.StatusCode != http.StatusOK {
return nil, time.Time{}, httpRespToErrorResponse(resp, bucketName, "")
return nil, time.Time{}, "", httpRespToErrorResponse(resp, bucketName, "")
}
}

lcBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, time.Time{}, err
return nil, time.Time{}, "", err
}

const minIOLifecycleCfgUpdatedAt = "X-Minio-LifecycleConfig-UpdatedAt"
var updatedAt time.Time
if timeStr := resp.Header.Get(minIOLifecycleCfgUpdatedAt); timeStr != "" {
updatedAt, err = time.Parse(iso8601DateFormat, timeStr)
if err != nil {
return nil, time.Time{}, err
return nil, time.Time{}, "", err
}
}

return lcBytes, updatedAt, nil
expIgnoreRepl := resp.Header.Get(minioLifecycleExpiryIgnoreReplication)
return lcBytes, updatedAt, expIgnoreRepl, nil
}
2 changes: 2 additions & 0 deletions api-put-object.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const (
ReplicationStatusFailed ReplicationStatus = "FAILED"
// ReplicationStatusReplica indicates object is a replica of a source
ReplicationStatusReplica ReplicationStatus = "REPLICA"
// ReplicationStatusReplica indicates object is a replica of a edge source

Check failure on line 48 in api-put-object.go

View workflow job for this annotation

GitHub Actions / Test on Go 1.21.x and ubuntu-latest

exported: comment on exported const ReplicationStatusReplicaEdge should be of the form "ReplicationStatusReplicaEdge ..." (revive)

Check failure on line 48 in api-put-object.go

View workflow job for this annotation

GitHub Actions / Test on Go 1.22.x and ubuntu-latest

exported: comment on exported const ReplicationStatusReplicaEdge should be of the form "ReplicationStatusReplicaEdge ..." (revive)
ReplicationStatusReplicaEdge ReplicationStatus = "REPLICA-EDGE"
)

// Empty returns true if no replication status set.
Expand Down
3 changes: 3 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,7 @@ const (
minioTgtReplicationReady = "X-Minio-Replication-Ready"
// Header asks if delete marker replication request can be sent by source now.
isMinioTgtReplicationReady = "X-Minio-Check-Replication-Ready"

// Header indicating if ilm expiry ignores replication status
minioLifecycleExpiryIgnoreReplication = "X-Minio-Lifecycle-Expire-Ignore-Replication"
)
5 changes: 3 additions & 2 deletions pkg/lifecycle/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,9 @@ type Rule struct {

// Configuration is a collection of Rule objects.
type Configuration struct {
XMLName xml.Name `xml:"LifecycleConfiguration,omitempty" json:"-"`
Rules []Rule `xml:"Rule"`
XMLName xml.Name `xml:"LifecycleConfiguration,omitempty" json:"-"`
Rules []Rule `xml:"Rule"`
ExpiryIgnoreReplication string `xml:"-,omitempty" json:"-"`
}

// Empty check if lifecycle configuration is empty
Expand Down

0 comments on commit da4e7b5

Please sign in to comment.