mirror of
https://github.com/minio/minio.git
synced 2025-11-07 04:42:56 -05:00
Add delete marker replication support (#10396)
Delete marker replication is implemented for V2 configuration specified in AWS spec (though AWS allows it only in the V1 configuration). This PR also brings in a MinIO only extension of replicating permanent deletes, i.e. deletes specifying version id are replicated to target cluster.
This commit is contained in:
committed by
GitHub
parent
9f4ad873bc
commit
50c10a5087
@@ -612,6 +612,10 @@ func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs,
|
||||
if web.CacheAPI() != nil {
|
||||
deleteObjects = web.CacheAPI().DeleteObjects
|
||||
}
|
||||
getObjectInfoFn := objectAPI.GetObjectInfo
|
||||
if web.CacheAPI() != nil {
|
||||
getObjectInfoFn = web.CacheAPI().GetObjectInfo
|
||||
}
|
||||
|
||||
claims, owner, authErr := webRequestAuthenticate(r)
|
||||
if authErr != nil {
|
||||
@@ -714,8 +718,27 @@ next:
|
||||
return toJSONError(ctx, errAccessDenied)
|
||||
}
|
||||
}
|
||||
_, replicateDel := checkReplicateDelete(ctx, getObjectInfoFn, args.BucketName, ObjectToDelete{ObjectName: objectName})
|
||||
if replicateDel {
|
||||
opts.DeleteMarkerReplicationStatus = string(replication.Pending)
|
||||
opts.DeleteMarker = true
|
||||
}
|
||||
|
||||
oi, err := deleteObject(ctx, objectAPI, web.CacheAPI(), args.BucketName, objectName, nil, r, opts)
|
||||
if replicateDel {
|
||||
globalReplicationState.queueReplicaDeleteTask(DeletedObjectVersionInfo{
|
||||
DeletedObject: DeletedObject{
|
||||
ObjectName: objectName,
|
||||
DeleteMarkerVersionID: oi.VersionID,
|
||||
DeleteMarkerReplicationStatus: string(oi.ReplicationStatus),
|
||||
DeleteMarkerMTime: oi.ModTime,
|
||||
DeleteMarker: oi.DeleteMarker,
|
||||
VersionPurgeStatus: oi.VersionPurgeStatus,
|
||||
},
|
||||
Bucket: args.BucketName,
|
||||
})
|
||||
}
|
||||
|
||||
_, err = deleteObject(ctx, objectAPI, web.CacheAPI(), args.BucketName, objectName, nil, r, opts)
|
||||
logger.LogIf(ctx, err)
|
||||
continue
|
||||
}
|
||||
@@ -760,9 +783,40 @@ next:
|
||||
// Reached maximum delete requests, attempt a delete for now.
|
||||
break
|
||||
}
|
||||
objects = append(objects, ObjectToDelete{
|
||||
ObjectName: obj.Name,
|
||||
})
|
||||
if obj.ReplicationStatus == replication.Replica {
|
||||
if authErr == errNoAuthToken {
|
||||
// Check if object is allowed to be deleted anonymously
|
||||
if !globalPolicySys.IsAllowed(policy.Args{
|
||||
Action: iampolicy.ReplicateDeleteAction,
|
||||
BucketName: args.BucketName,
|
||||
ConditionValues: getConditionValues(r, "", "", nil),
|
||||
IsOwner: false,
|
||||
ObjectName: objectName,
|
||||
}) {
|
||||
return toJSONError(ctx, errAccessDenied)
|
||||
}
|
||||
} else {
|
||||
if !globalIAMSys.IsAllowed(iampolicy.Args{
|
||||
AccountName: claims.AccessKey,
|
||||
Action: iampolicy.ReplicateDeleteAction,
|
||||
BucketName: args.BucketName,
|
||||
ConditionValues: getConditionValues(r, "", claims.AccessKey, claims.Map()),
|
||||
IsOwner: owner,
|
||||
ObjectName: objectName,
|
||||
Claims: claims.Map(),
|
||||
}) {
|
||||
return toJSONError(ctx, errAccessDenied)
|
||||
}
|
||||
}
|
||||
}
|
||||
// since versioned delete is not available on web browser, yet - this is a simple DeleteMarker replication
|
||||
_, replicateDel := checkReplicateDelete(ctx, getObjectInfoFn, args.BucketName, ObjectToDelete{ObjectName: obj.Name})
|
||||
objToDel := ObjectToDelete{ObjectName: obj.Name}
|
||||
if replicateDel {
|
||||
objToDel.DeleteMarkerReplicationStatus = string(replication.Pending)
|
||||
}
|
||||
|
||||
objects = append(objects, objToDel)
|
||||
}
|
||||
|
||||
// Nothing to do.
|
||||
@@ -772,7 +826,11 @@ next:
|
||||
|
||||
// Deletes a list of objects.
|
||||
deletedObjects, errs := deleteObjects(ctx, args.BucketName, objects, opts)
|
||||
for _, err := range errs {
|
||||
for i, err := range errs {
|
||||
if err != nil && !isErrObjectNotFound(err) {
|
||||
deletedObjects[i].DeleteMarkerReplicationStatus = objects[i].DeleteMarkerReplicationStatus
|
||||
deletedObjects[i].VersionPurgeStatus = objects[i].VersionPurgeStatus
|
||||
}
|
||||
if err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
break next
|
||||
@@ -799,6 +857,12 @@ next:
|
||||
UserAgent: r.UserAgent(),
|
||||
Host: handlers.GetSourceIP(r),
|
||||
})
|
||||
if dobj.DeleteMarkerReplicationStatus == string(replication.Pending) || dobj.VersionPurgeStatus == Pending {
|
||||
globalReplicationState.queueReplicaDeleteTask(DeletedObjectVersionInfo{
|
||||
DeletedObject: dobj,
|
||||
Bucket: args.BucketName,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user