mirror of
				https://github.com/minio/minio.git
				synced 2025-10-30 00:05:02 -04:00 
			
		
		
		
	replication: default tag timestamps in CopyObject call (#20891)
If object is uploaded with tags, the internal tagging-timestamp tracked for replication will be missing. Default to ModTime in such cases to allow tags to be synced correctly. Also fixing a regression in fetching tags and tag comparison
This commit is contained in:
		
							parent
							
								
									f4fd4ea66d
								
							
						
					
					
						commit
						64a8f2e554
					
				| @ -958,7 +958,11 @@ func getReplicationAction(oi1 ObjectInfo, oi2 minio.ObjectInfo, opType replicati | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	t, _ := tags.ParseObjectTags(oi1.UserTags) | 	t, _ := tags.ParseObjectTags(oi1.UserTags) | ||||||
| 	if (oi2.UserTagCount > 0 && !reflect.DeepEqual(oi2.UserTags, t.ToMap())) || (oi2.UserTagCount != len(t.ToMap())) { | 	oi2Map := make(map[string]string) | ||||||
|  | 	for k, v := range oi2.UserTags { | ||||||
|  | 		oi2Map[k] = v | ||||||
|  | 	} | ||||||
|  | 	if (oi2.UserTagCount > 0 && !reflect.DeepEqual(oi2Map, t.ToMap())) || (oi2.UserTagCount != len(t.ToMap())) { | ||||||
| 		return replicateMetadata | 		return replicateMetadata | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -1447,13 +1451,14 @@ func (ri ReplicateObjectInfo) replicateAll(ctx context.Context, objectAPI Object | |||||||
| 		} | 		} | ||||||
| 		rinfo.Duration = time.Since(startTime) | 		rinfo.Duration = time.Since(startTime) | ||||||
| 	}() | 	}() | ||||||
| 
 | 	sOpts := minio.StatObjectOptions{ | ||||||
| 	oi, cerr := tgt.StatObject(ctx, tgt.Bucket, object, minio.StatObjectOptions{ |  | ||||||
| 		VersionID: objInfo.VersionID, | 		VersionID: objInfo.VersionID, | ||||||
| 		Internal: minio.AdvancedGetOptions{ | 		Internal: minio.AdvancedGetOptions{ | ||||||
| 			ReplicationProxyRequest: "false", | 			ReplicationProxyRequest: "false", | ||||||
| 		}, | 		}, | ||||||
| 	}) | 	} | ||||||
|  | 	sOpts.Set(xhttp.AmzTagDirective, "ACCESS") | ||||||
|  | 	oi, cerr := tgt.StatObject(ctx, tgt.Bucket, object, sOpts) | ||||||
| 	if cerr == nil { | 	if cerr == nil { | ||||||
| 		rAction = getReplicationAction(objInfo, oi, ri.OpType) | 		rAction = getReplicationAction(objInfo, oi, ri.OpType) | ||||||
| 		rinfo.ReplicationStatus = replication.Completed | 		rinfo.ReplicationStatus = replication.Completed | ||||||
| @ -1538,19 +1543,30 @@ applyAction: | |||||||
| 				ReplicationRequest: true, // always set this to distinguish between `mc mirror` replication and serverside | 				ReplicationRequest: true, // always set this to distinguish between `mc mirror` replication and serverside | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		if tagTmStr, ok := objInfo.UserDefined[ReservedMetadataPrefixLower+TaggingTimestamp]; ok { | 		// default timestamps to ModTime unless present in metadata | ||||||
|  | 		lkMap := caseInsensitiveMap(objInfo.UserDefined) | ||||||
|  | 		if _, ok := lkMap.Lookup(xhttp.AmzObjectLockLegalHold); ok { | ||||||
|  | 			dstOpts.Internal.LegalholdTimestamp = objInfo.ModTime | ||||||
|  | 		} | ||||||
|  | 		if _, ok := lkMap.Lookup(xhttp.AmzObjectLockRetainUntilDate); ok { | ||||||
|  | 			dstOpts.Internal.RetentionTimestamp = objInfo.ModTime | ||||||
|  | 		} | ||||||
|  | 		if objInfo.UserTags != "" { | ||||||
|  | 			dstOpts.Internal.TaggingTimestamp = objInfo.ModTime | ||||||
|  | 		} | ||||||
|  | 		if tagTmStr, ok := lkMap.Lookup(ReservedMetadataPrefixLower + TaggingTimestamp); ok { | ||||||
| 			ondiskTimestamp, err := time.Parse(time.RFC3339, tagTmStr) | 			ondiskTimestamp, err := time.Parse(time.RFC3339, tagTmStr) | ||||||
| 			if err == nil { | 			if err == nil { | ||||||
| 				dstOpts.Internal.TaggingTimestamp = ondiskTimestamp | 				dstOpts.Internal.TaggingTimestamp = ondiskTimestamp | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if retTmStr, ok := objInfo.UserDefined[ReservedMetadataPrefixLower+ObjectLockRetentionTimestamp]; ok { | 		if retTmStr, ok := lkMap.Lookup(ReservedMetadataPrefixLower + ObjectLockRetentionTimestamp); ok { | ||||||
| 			ondiskTimestamp, err := time.Parse(time.RFC3339, retTmStr) | 			ondiskTimestamp, err := time.Parse(time.RFC3339, retTmStr) | ||||||
| 			if err == nil { | 			if err == nil { | ||||||
| 				dstOpts.Internal.RetentionTimestamp = ondiskTimestamp | 				dstOpts.Internal.RetentionTimestamp = ondiskTimestamp | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if lholdTmStr, ok := objInfo.UserDefined[ReservedMetadataPrefixLower+ObjectLockLegalHoldTimestamp]; ok { | 		if lholdTmStr, ok := lkMap.Lookup(ReservedMetadataPrefixLower + ObjectLockLegalHoldTimestamp); ok { | ||||||
| 			ondiskTimestamp, err := time.Parse(time.RFC3339, lholdTmStr) | 			ondiskTimestamp, err := time.Parse(time.RFC3339, lholdTmStr) | ||||||
| 			if err == nil { | 			if err == nil { | ||||||
| 				dstOpts.Internal.LegalholdTimestamp = ondiskTimestamp | 				dstOpts.Internal.LegalholdTimestamp = ondiskTimestamp | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user