【问题标题】:S3 Object Expiration using boto使用 boto 的 S3 对象过期
【发布时间】:2023-03-18 05:29:01
【问题描述】:

我试图找出一种方法来清理我的 s3 存储桶。我想删除所有早于 X 天的密钥(在我的情况下 X 是 30 天)。

我想不出删除 s3 中对象的方法。

我使用了以下方法,但都不起作用(通过工作,我的意思是我在 X 天后尝试获取对象,并且 s3 仍在为对象提供服务。我期待“找不到对象”或“对象过期”消息

方法一:

    k = Key(bucket)
    k.key = my_key_name
    expires = datetime.utcnow() + timedelta(seconds=(10))
    expires = expires.strftime("%a, %d %b %Y %H:%M:%S GMT")
    k.set_contents_from_filename(filename,headers={'Expires':expires})

方法二:

    k = Key(bucket)
    k.key = "Event_" + str(key_name) + "_report"
    expires = datetime.utcnow() + timedelta(seconds=(10))
    expires = expires.strftime("%a, %d %b %Y %H:%M:%S GMT")
    k.set_meta_data('Expires', expires)
    k.set_contents_from_filename(filename)

如果有人可以分享为他们工作的代码,即删除 s3 对象,那就太好了

【问题讨论】:

    标签: python amazon-s3 boto


    【解决方案1】:

    您可以使用lifecycle policies 从 s3 中删除那些 超过 X 天。例如,假设你有这些 对象:

    logs/first
    logs/second
    logs/third
    otherfile.txt
    

    要在 30 天后使日志/下的所有内容过期,您会说:

    import boto
    from boto.s3.lifecycle import (
        Lifecycle,
        Expiration,
    )
    
    lifecycle = Lifecycle()
    lifecycle.add_rule(
        'rulename',
         prefix='logs/',
         status='Enabled',
         expiration=Expiration(days=30)
    )
    
    s3 = boto.connect_s3()
    bucket = s3.get_bucket('boto-lifecycle-test')
    bucket.configure_lifecycle(lifecycle)
    

    您还可以检索生命周期配置:

    >>> config = bucket.get_lifecycle_config()
    >>> print(config[0])
    <Rule: ruleid>
    >>> print(config[0].prefix)
    logs/
    >>> print(config[0].expiration)
    <Expiration: in: 30 days>
    

    【讨论】:

    • 我正在尝试对此进行测试,并想知道是否可以使用分钟/秒来测试过期时间。看起来 days=1 是可以使用的最短时间
    • 无法使用分钟/秒。最短为 0 天,唯一的保证是 AWS 会根据 PUT Bucket lifecycle 在 UTC 次日午夜之前采取行动。
    • 请将“from boto.s3.lifecycle import LifeCycle”中的 LifeCycle 更改为 Lifecycle,因为 Lifecycle 是正确的类名。
    • 有什么方法可以测试一个对象是否处于特定的生命周期中?
    【解决方案2】:

    jamesis 的答案是使用 boto,这是一个旧版本,将被弃用。 当前支持的版本是boto3

    logs 文件夹上的过期策略可以做如下:

    import boto3
    from botocore.exceptions import ClientError
    
    client = boto3.client('s3')
    try:
        policy_status = client.put_bucket_lifecycle_configuration(
                   Bucket='boto-lifecycle-test',
                   LifecycleConfiguration={
                        'Rules': 
                               [
                                 {
                                 'Expiration':
                                    {
                                     'Days': 30,
                                     'ExpiredObjectDeleteMarker': True
                                    },
                                 'Prefix': 'logs/',
                                 'Filter': {
                                   'Prefix': 'logs/',
                                 },
                                 'Status': 'Enabled',
                                }
                            ]})
    except ClientError as e:
         print("Unable to apply bucket policy. \nReason:{0}".format(e))
    

    这将覆盖logs 上的任何现有生命周期配置策略。

    最好在应用过期配置之前检查存储桶是否存在以及您是否有权访问它,即在try-except之前

    bucket_exists = client.head_bucket(
       Bucket='boto-lifecycle-test'
    )
    

    由于logs 文件夹本身不是存储桶,而是存储桶boto-lifecycletest 中的一个对象,因此存储桶本身可以有不同的过期策略。 您可以从policy_exists 的结果中检查这一点,如下所示。

    policy_exists = client.get_bucket_lifecycle_configuration(
        Bucket='boto-lifecycle-test')
    bucket_policy = policy_exists['Rules'][0]['Expiration']
    

    更多关于设置过期策略的信息可以在Expiry policy查看

    【讨论】:

    • 我在 Ceph 中使用它,我必须注释掉 'ExpiredObjectDeleteMarker': True 行,否则我会收到格式错误的 XML 错误。
    • 是的,也许该标志已被弃用
    【解决方案3】:

    Vaulstein 的上述 python 脚本引发了格式错误的 XML 异常。请删除“'Status': 'Enabled',”行末尾多余的“,”。

    【讨论】:

    • 您只需提交编辑请求以获取来自@Vaulstein 的答案或将其添加为评论。这不应该作为答案发布。我建议提交编辑
    • 在提交编辑请求时抛出错误“编辑必须至少 6 个字符”。感谢您的建议。
    • 然后将其作为评论添加到答案中会更合适。
    • @mbbce 他可能想要这样做,但他必须至少有 20(?) 名声才能这样做。你知道,我遇到了那个无限循环。
    【解决方案4】:
    session = boto3.Session(profile_name='my-aws-login-profile', region_name='ap-south-1')
    s3 = session.resource('s3')
    bucket_lifecycle_configuration = s3.BucketLifecycleConfiguration('my-s3bucket')
        try:
            bucket_lifecycle_configuration.put(
                LifecycleConfiguration={
                    'Rules': [
                        {
                            'Expiration': {
                                'Days': 7
                            },
                            'ID': 'life cycle config for log folder',
                            'Filter': {
                                'Prefix': 'logs/',
                            },
                            'Status': 'Enabled',
                            'NoncurrentVersionExpiration': {
                                'NoncurrentDays': 7
                            },
                            'AbortIncompleteMultipartUpload': {
                                'DaysAfterInitiation': 7
                            }
                        },
                    ]
                }
            )
        except Exception as e:
            print e.message
            exit(1)
    

    解析的 XML 响应:

    <?xml version="1.0" encoding="UTF-8"?>
    <LifecycleConfiguration>
       <Rule>
          <ID>life cycle config for log folder</ID>
          <Filter>
             <Prefix>logs/</Prefix>
          </Filter>
          <Status>Enabled</Status>
          <Expiration>
             <Days>7</Days>
          </Expiration>
          <NoncurrentVersionExpiration>
             <NoncurrentDays>7</NoncurrentDays>
          </NoncurrentVersionExpiration>
          <AbortIncompleteMultipartUpload>
             <DaysAfterInitiation>7</DaysAfterInitiation>
          </AbortIncompleteMultipartUpload>
       </Rule>
    </LifecycleConfiguration>
    

    【讨论】:

      猜你喜欢
      • 2012-03-29
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      • 2018-07-14
      • 2019-05-23
      • 1970-01-01
      相关资源
      最近更新 更多