Skip to content

Commit 3ad35af

Browse files
authored
Merge pull request #275 from l-iberty/master
multiversioning recovery demo
2 parents 1766f91 + 38f03cd commit 3ad35af

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

demo/disaster_recovery_demo.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# -*- coding=utf-8
2+
#
3+
# ref to @shezhangjun
4+
# https://github.com/shezhangjun/TencentCOS/blob/master/Python_SDK/COS_Disaster_Recovery/DisasterRecovery.py
5+
#
6+
from qcloud_cos import CosConfig
7+
from qcloud_cos import CosS3Client
8+
import sys
9+
import os
10+
import logging
11+
12+
# logging.basicConfig(level=logging.INFO, stream=sys.stdout)
13+
14+
15+
def _recover_main(src_region, src_secret_id, src_secret_key, src_bucket, prefix,
16+
dst_region, dst_secret_id, dst_secret_key, dst_bucket):
17+
src_client = CosS3Client(CosConfig(Region=src_region, SecretId=src_secret_id, SecretKey=src_secret_key))
18+
dst_client = CosS3Client(CosConfig(Region=dst_region, SecretId=dst_secret_id, SecretKey=dst_secret_key))
19+
while True:
20+
key_marker = ''
21+
versionId_marker = ''
22+
response = src_client.list_objects_versions(
23+
Bucket=src_bucket,
24+
Prefix=prefix,
25+
KeyMarker=key_marker,
26+
VersionIdMarker=versionId_marker,
27+
)
28+
delete_marker_keys = list()
29+
recovered_keys = list()
30+
# 从 DeleteMarker 取出被删除的对象
31+
if 'DeleteMarker' in response:
32+
for version in response['DeleteMarker']:
33+
if version['IsLatest'] == 'true':
34+
delete_marker_keys.append(version['Key'])
35+
36+
if len(delete_marker_keys) == 0:
37+
print('no delete markers found, no data to recover')
38+
return
39+
40+
# 从 Version 取最新的版本号
41+
if 'Version' in response:
42+
for version in response['Version']:
43+
key = version['Key']
44+
versionId = version['VersionId']
45+
if key in delete_marker_keys and not key in recovered_keys:
46+
print('recover from key:{key}, versionId:{versionId}'.format(key=key, versionId=versionId))
47+
try:
48+
dst_client.copy(
49+
Bucket=dst_bucket,
50+
Key=key,
51+
CopySource={
52+
'Bucket': src_bucket,
53+
'Key': key,
54+
'Region': src_region,
55+
'VersionId': versionId,
56+
}
57+
)
58+
recovered_keys.append(key)
59+
print("success recover object: {src_bucket}/{key}({versionId}) => {dst_bucket}/{key}".format(
60+
src_bucket=src_bucket, key=key, versionId=versionId, dst_bucket=dst_bucket))
61+
except Exception as e:
62+
print(e)
63+
pass
64+
65+
if response['IsTruncated'] == 'false':
66+
break
67+
68+
key_marker = response['NextKeyMarker']
69+
versionId_marker = response['NextVersionIdMarker']
70+
71+
72+
if __name__ == '__main__':
73+
# 使用场景:
74+
# 根据源桶src_bucket的删除标记从历史版本里把文件恢复到dst_bucket
75+
# src_bucket和dst_bucket可以一致, 即原地恢复
76+
77+
# 源桶信息
78+
src_region = 'ap-guangzhou' # 源地域
79+
src_secret_id = '' # 源桶SecretID
80+
src_secret_key = '' # 源桶SecretKey
81+
src_bucket = 'bucket-1200000000' # 源桶名
82+
83+
# 目标桶信息
84+
dst_region = 'ap-guangzhou' # 目标桶地域
85+
dst_secret_id = '' # 目标桶SecretID
86+
dst_secret_key = '' # 目标桶SecretKey
87+
dst_bucket = 'bucket-1250000000' # 目标桶名
88+
89+
prefix = '' # 设置要恢复的对象前缀
90+
91+
_recover_main(src_region, src_secret_id, src_secret_key, src_bucket, prefix,
92+
dst_region, dst_secret_id, dst_secret_key, dst_bucket)

0 commit comments

Comments
 (0)