amazon web services - reconoce - ¿Cómo elimino un grupo versionado en AWS S3 utilizando la CLI?
configurar aws cli (8)
- Para borrar objetos específicos, use jq filter.
- Es posible que necesite limpiar los ''DeleteMarkers'' y no solo las ''Versiones''.
- Usando
$()
lugar de``
, puede incrustar variables para nombre-cubo y valor-clave.
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}'')"
He intentado tanto s3cmd
:
$ s3cmd -r -f -v del s3://my-versioned-bucket/
Y el CLI de AWS:
$ aws s3 rm s3://my-versioned-bucket/ --recursive
Pero ambos comandos simplemente agregan marcadores DELETE
a S3. El comando para eliminar un depósito tampoco funciona (desde la CLI de AWS):
$ 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.
¿Vale, cómo? No hay información en su documentación para esto. S3Cmd dice que es una herramienta de línea de comandos S3 ''con todas las funciones'', pero no hace referencia a versiones que no sean las suyas. ¿Hay alguna forma de hacer esto sin usar la interfaz web, que tardará una eternidad y me obliga a mantener mi portátil encendido?
Aquí hay una sola línea que puede cortar y pegar en la línea de comandos para eliminar todas las versiones y eliminar marcadores (requiere herramientas aws, reemplazar su nombre de la copia de seguridad con su nombre de cubo)
echo ''#!/bin/bash'' > deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket yourbucket-name-backup | grep -E "^VERSIONS" | awk ''{print "aws s3api delete-object --bucket yourbucket-name-backup --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 yourbucket-name-backup | grep -E "^DELETEMARKERS" | grep -v "null" | awk ''{print "aws s3api delete-object --bucket yourbucket-name-backup --key "$3" --version-id "$5";"}'' >> deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh;
entonces podrías usar:
aws s3 rb s3://bucket-name --force
Encontré las otras respuestas incompletas o que requieren la instalación de dependencias externas (como boto), por lo que aquí hay una que está inspirada en esas pero que va un poco más allá.
Como se documenta en Trabajar con marcadores de eliminación , antes de que se pueda eliminar un grupo de versiones, todas sus versiones deben eliminarse por completo, lo que es un proceso de 2 pasos:
- "eliminar" todos los objetos de la versión en el contenedor, que los marca como eliminados pero en realidad no los elimina
- complete la eliminación eliminando todos los objetos de marcador de eliminación
Aquí está la solución CLI pura que funcionó para mí (inspirada en las otras respuestas):
#!/usr/bin/env bash
bucket_name=...
del_s3_bucket_obj()
{
local bucket_name=$1
local obj_type=$2
local query="{Objects: $obj_type[].{Key:Key,VersionId:VersionId}}"
local s3_objects=$(aws s3api list-object-versions --bucket ${bucket_name} --output=json --query="$query")
if ! (echo $s3_objects | grep -q ''"Objects": null''); then
aws s3api delete-objects --bucket "${bucket_name}" --delete "$s3_objects"
fi
}
del_s3_bucket_obj ${bucket_name} ''Versions''
del_s3_bucket_obj ${bucket_name} ''DeleteMarkers''
Una vez hecho esto, funcionará lo siguiente:
aws s3 rb "s3://${bucket_name}"
Sin embargo, no estoy seguro de cómo le irá con más de 1000 objetos, si alguien puede informar eso sería increíble.
Me encontré con la misma limitación de AWS CLI. Encontré que la solución más fácil es usar Python y boto3 :
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()
Una versión anterior de esta respuesta usaba boto pero esa solución tenía problemas de rendimiento con un gran número de claves, como lo señaló Chuckles.
Me encontré con problemas con la solución de Abe, ya que el generador list_buckets
se usa para crear una lista masiva llamada all_keys
y pasé una hora sin que se completara. Este ajuste parece funcionar mejor para mí, ¡tenía cerca de un millón de objetos en mi cubeta y contando!
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!
¡Espero que esto ayude a cualquier otra persona que se encuentre con esta pesadilla S3!
Puede eliminar todos los objetos en la versión s3 bucket. Pero no sé cómo borrar objetos específicos. aws s3api delete-objects --bucket <value> --delete "$(aws s3api list-object-versions --bucket <value> | jq ''{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}'')"
Espero que te sea de ayuda.
Una forma de hacerlo es iterar a través de las versiones y eliminarlas. Un poco complicado en el CLI, pero como mencionó Java, sería más sencillo:
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!");
También puede eliminar llamadas por lotes para mejorar la eficiencia si es necesario.
Usar boto3
es incluso más fácil que con la solución de boto
propuesta para eliminar todas las versiones de objetos en un grupo de S3:
#!/usr/bin/env python
import boto3
s3 = boto3.resource(''s3'')
bucket = s3.Bucket(''your-bucket-name'')
bucket.object_versions.all().delete()
Funciona bien también para cantidades muy grandes de versiones de objetos, aunque puede tomar algún tiempo en ese caso.