両方試してみましたs3cmd
:
$ s3cmd -r -f -v del s3://my-versioned-bucket/
そして、AWS CLI:
$ aws s3 rm s3://my-versioned-bucket/ --recursive
ただし、これらのコマンドはどちらもDELETE
マーカーをS3に追加するだけです。バケットを削除するコマンドも機能しません(AWS CLIから):
$ aws s3 rb s3://my-versioned-bucket/ --force
Cleaning up. Please wait...
Completed 1 part(s) with ... file(s) remaining
remove_bucket failed: s3://my-versioned-bucket/ A client error (BucketNotEmpty) occurred when calling the DeleteBucket operation: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
わかりました...どうやって?このための ドキュメント には情報がありません。 S3Cmdは、「完全な機能を備えた」S3コマンドラインツールであると言いますが、 バージョンへの参照なし 独自のものではありません。 Webインターフェイスを使用せずにこれを行う方法はありますか?これには永遠に時間がかかり、ラップトップをオンにしておく必要がありますか?
それを行う1つの方法は、バージョンを反復処理して削除することです。 CLIには少し注意が必要ですが、Javaについて述べたように、それはより簡単です。
AmazonS3Client s3 = new AmazonS3Client();
String bucketName = "deleteversions-"+UUID.randomUUID();
//Creates Bucket
s3.createBucket(bucketName);
//Enable Versioning
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration(ENABLED);
s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName, configuration ));
//Puts versions
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("some-bytes".getBytes()), null);
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("other-bytes".getBytes()), null);
//Removes all versions
for ( S3VersionSummary version : S3Versions.inBucket(s3, bucketName) ) {
String key = version.getKey();
String versionId = version.getVersionId();
s3.deleteVersion(bucketName, key, versionId);
}
//Removes the bucket
s3.deleteBucket(bucketName);
System.out.println("Done!");
必要に応じて、効率のために呼び出しをバッチ削除することもできます。
AWS CLIの同じ制限に遭遇しました。 Python and boto :を使用するのが最も簡単な解決策であることがわかりました。
#!/usr/bin/env python
BUCKET = 'your-bucket-here'
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
bucket.object_versions.delete()
# if you want to delete the now-empty bucket as well, uncomment this line:
#bucket.delete()
この回答の以前のバージョンでは boto を使用していましたが、Chucklesが指摘したように、このソリューションには多数のキーでパフォーマンスの問題がありました。
boto3
を使用すると、提案されたboto
ソリューションを使用するよりも簡単に、S3バケット内のすべてのオブジェクトバージョンを削除できます。
#!/usr/bin/env python
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('your-bucket-name')
bucket.object_versions.all().delete()
非常に大量のオブジェクトバージョンでも正常に動作しますが、その場合は時間がかかる場合があります。
バージョン管理されたs3バケット内のすべてのオブジェクトを削除できます。しかし、特定のオブジェクトを削除する方法がわかりません。
$ aws s3api delete-objects \
--bucket <value> \
--delete "$(aws s3api list-object-versions \
--bucket <value> | \
jq '{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
または、jq
なし:
$ aws s3api delete-objects \
--bucket ${bucket_name} \
--delete "$(aws s3api list-object-versions \
--bucket "${bucket_name}" \
--output=json \
--query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
コマンドラインにカットアンドペーストしてすべてのバージョンを削除し、マーカーを削除することができる1つのライナーを次に示します(awsツールが必要です。yourbucket-name-backupをバケット名に置き換えます)
echo '#!/bin/bash' > deleteBucketScript.sh \
&& aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^VERSIONS" |\
awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "$4" --version-id "$8";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh; echo '#!/bin/bash' > \
deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^DELETEMARKERS" | grep -v "null" \
| awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "$3" --version-id "$5";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh;
次に使用できます:
aws s3 rb s3://bucket-name --force
list_buckets
ジェネレーターを使用してall_keys
と呼ばれる大規模なリストを作成するときに Abeのソリューション で問題が発生し、完了しないまま1時間を費やしました。このTweakは、私にとってはうまく機能しているようです。バケツに数えられるオブジェクトが100万個近くありました。
import boto
s3 = boto.connect_s3()
bucket = s3.get_bucket("your-bucket-name-here")
chunk_counter = 0 #this is simply a Nice to have
keys = []
for key in bucket.list_versions():
keys.append(key)
if len(keys) > 1000:
bucket.delete_keys(keys)
chunk_counter += 1
keys = []
print("Another 1000 done.... {n} chunks so far".format(n=chunk_counter))
#bucket.delete() #as per usual uncomment if you're sure!
これが、このS3の悪夢に遭遇する他の人を助けることを願っています!
``
_の代わりに$()
を使用すると、bucket-nameおよびkey-valueの変数を埋め込むことができます。_aws s3api delete-objects --bucket bucket-name --delete "$(aws s3api list-object-versions --bucket bucket-name | jq -M '{Objects: [.["Versions","DeleteMarkers"][]|select(.Key == "key-value")| {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
_
https://Gist.github.com/wknapik/191619bfa650b8572115cd07197f3baf
#!/usr/bin/env bash
set -eEo pipefail
shopt -s inherit_errexit >/dev/null 2>&1 || true
if [[ ! "$#" -eq 2 || "$1" != --bucket ]]; then
echo -e "USAGE: $(basename "$0") --bucket <bucket>"
exit 2
fi
# $@ := bucket_name
empty_bucket() {
local -r bucket="${1:?}"
for object_type in Versions DeleteMarkers; do
local opt=() next_token=""
while [[ "$next_token" != null ]]; do
page="$(aws s3api list-object-versions --bucket "$bucket" --output json --max-items 1000 "${opt[@]}" \
--query="[{Objects: ${object_type}[].{Key:Key, VersionId:VersionId}}, NextToken]")"
objects="$(jq -r '.[0]' <<<"$page")"
next_token="$(jq -r '.[1]' <<<"$page")"
case "$(jq -r .Objects <<<"$objects")" in
'[]'|null) break;;
*) opt=(--starting-token "$next_token")
aws s3api delete-objects --bucket "$bucket" --delete "$objects";;
esac
done
done
}
empty_bucket "${2#s3://}"
例えば。 empty_bucket.sh --bucket foo
これにより、すべてのオブジェクトバージョンが削除され、バケット内のマーカーが1000のバッチで削除されます。その後、aws s3 rb s3://foo
を使用してバケットを削除できます。
Bash、awscli、jqが必要です。
私が見つけた最も簡単な方法は、このCLIツールs3wipe
を使用することです。 Dockerコンテナとして提供されているため、次のように使用できます。
$ docker run -it --rm slmingol/s3wipe --help
usage: s3wipe [-h] --path PATH [--id ID] [--key KEY] [--dryrun] [--quiet]
[--batchsize BATCHSIZE] [--maxqueue MAXQUEUE]
[--maxthreads MAXTHREADS] [--delbucket] [--region REGION]
Recursively delete all keys in an S3 path
optional arguments:
-h, --help show this help message and exit
--path PATH S3 path to delete (e.g. s3://bucket/path)
--id ID Your AWS access key ID
--key KEY Your AWS secret access key
--dryrun Don't delete. Print what we would have deleted
--quiet Suprress all non-error output
--batchsize BATCHSIZE # of keys to batch delete (default 100)
--maxqueue MAXQUEUE Max size of deletion queue (default 10k)
--maxthreads MAXTHREADS Max number of threads (default 100)
--delbucket If S3 path is a bucket path, delete the bucket also
--region REGION Region of target S3 bucket. Default vaue `us-
east-1`
バケット内のすべてのバージョン付きオブジェクトを削除してからバケットを削除する例を次に示します。
$ docker run -it --rm slmingol/s3wipe \
--id $(aws configure get default.aws_access_key_id) \
--key $(aws configure get default.aws_secret_access_key) \
--path s3://bw-tf-backends-aws-example-logs \
--delbucket
[2019-02-20@03:39:16] INFO: Deleting from bucket: bw-tf-backends-aws-example-logs, path: None
[2019-02-20@03:39:16] INFO: Getting subdirs to feed to list threads
[2019-02-20@03:39:18] INFO: Done deleting keys
[2019-02-20@03:39:18] INFO: Bucket is empty. Attempting to remove bucket
ここで少し解凍する必要がありますが、上記は次のことをしています:
docker run -it --rm mikelorant/s3wipe
-s3wipe
コンテナをインタラクティブに実行し、実行のたびに削除します--id
&--key
-アクセスキーとアクセスIDを渡すaws configure get default.aws_access_key_id
-キーIDを取得しますaws configure get default.aws_secret_access_key
-キーシークレットを取得します--path s3://bw-tf-backends-aws-example-logs
-削除するバケット--delbucket
-空になったらバケットを削除しますここにあるこのbashスクリプト: https://Gist.github.com/weavenet/f40b09847ac17dd99d16
私のためにそのまま働いた。
スクリプトをdelete_all_versions.shとして保存してから、単に実行しました。
./delete_all_versions.sh my_foobar_bucket
そしてそれは欠陥なしで働きました。
pythonまたはbotoなど何も必要ありませんでした。