copy - motivation - hashtags fitness gym
¿Es posible copiar todos los archivos de un depósito S3 a otro con s3cmd? (11)
Estoy bastante contento con s3cmd, pero hay un problema: ¿cómo copiar todos los archivos de un depósito de S3 a otro? ¿Es posible?
EDIT: he encontrado una forma de copiar archivos entre cubos utilizando Python con boto:
from boto.s3.connection import S3Connection
def copyBucket(srcBucketName, dstBucketName, maxKeys = 100):
conn = S3Connection(awsAccessKey, awsSecretKey)
srcBucket = conn.get_bucket(srcBucketName);
dstBucket = conn.get_bucket(dstBucketName);
resultMarker = ''''
while True:
keys = srcBucket.get_all_keys(max_keys = maxKeys, marker = resultMarker)
for k in keys:
print ''Copying '' + k.key + '' from '' + srcBucketName + '' to '' + dstBucketName
t0 = time.clock()
dstBucket.copy_key(k.key, srcBucketName, k.key)
print time.clock() - t0, '' seconds''
if len(keys) < maxKeys:
print ''Done''
break
resultMarker = keys[maxKeys - 1].key
La sincronización es casi tan simple como copiar. Hay campos para ETag, tamaño y último modificado disponibles para las claves.
Quizás esto ayude a otros también.
AWS CLI parece hacer el trabajo a la perfección, y tiene la ventaja de ser una herramienta oficialmente compatible.
aws s3 sync s3://mybucket s3://backup-mybucket
http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html
El código de mdahlman no funcionó para mí, pero este comando copia todos los archivos del depósito1 en una nueva carpeta (el comando también crea esta nueva carpeta) en el depósito 2.
cp --recursive --include=file_prefix* s3://bucket1/ s3://bucket2/new_folder_name/
En realidad es posible. Esto funcionó para mí:
import boto
AWS_ACCESS_KEY = ''Your access key''
AWS_SECRET_KEY = ''Your secret key''
conn = boto.s3.connection.S3Connection(AWS_ACCESS_KEY, AWS_SECRET_KEY)
bucket = boto.s3.bucket.Bucket(conn, SRC_BUCKET_NAME)
for item in bucket:
# Note: here you can put also a path inside the DEST_BUCKET_NAME,
# if you want your item to be stored inside a folder, like this:
# bucket.copy(DEST_BUCKET_NAME, ''%s/%s'' % (folder_name, item.key))
bucket.copy(DEST_BUCKET_NAME, item.key)
Escribí un script que respalda un cubo de S3: https://github.com/roseperrone/aws-backup-rake-task
#!/usr/bin/env python
from boto.s3.connection import S3Connection
import re
import datetime
import sys
import time
def main():
s3_ID = sys.argv[1]
s3_key = sys.argv[2]
src_bucket_name = sys.argv[3]
num_backup_buckets = sys.argv[4]
connection = S3Connection(s3_ID, s3_key)
delete_oldest_backup_buckets(connection, num_backup_buckets)
backup(connection, src_bucket_name)
def delete_oldest_backup_buckets(connection, num_backup_buckets):
"""Deletes the oldest backup buckets such that only the newest NUM_BACKUP_BUCKETS - 1 buckets remain."""
buckets = connection.get_all_buckets() # returns a list of bucket objects
num_buckets = len(buckets)
backup_bucket_names = []
for bucket in buckets:
if (re.search(''backup-'' + r''/d{4}-/d{2}-/d{2}'' , bucket.name)):
backup_bucket_names.append(bucket.name)
backup_bucket_names.sort(key=lambda x: datetime.datetime.strptime(x[len(''backup-''):17], ''%Y-%m-%d'').date())
# The buckets are sorted latest to earliest, so we want to keep the last NUM_BACKUP_BUCKETS - 1
delete = len(backup_bucket_names) - (int(num_backup_buckets) - 1)
if delete <= 0:
return
for i in range(0, delete):
print ''Deleting the backup bucket, '' + backup_bucket_names[i]
connection.delete_bucket(backup_bucket_names[i])
def backup(connection, src_bucket_name):
now = datetime.datetime.now()
# the month and day must be zero-filled
new_backup_bucket_name = ''backup-'' + str(''%02d'' % now.year) + ''-'' + str(''%02d'' % now.month) + ''-'' + str(now.day);
print "Creating new bucket " + new_backup_bucket_name
new_backup_bucket = connection.create_bucket(new_backup_bucket_name)
copy_bucket(src_bucket_name, new_backup_bucket_name, connection)
def copy_bucket(src_bucket_name, dst_bucket_name, connection, maximum_keys = 100):
src_bucket = connection.get_bucket(src_bucket_name);
dst_bucket = connection.get_bucket(dst_bucket_name);
result_marker = ''''
while True:
keys = src_bucket.get_all_keys(max_keys = maximum_keys, marker = result_marker)
for k in keys:
print ''Copying '' + k.key + '' from '' + src_bucket_name + '' to '' + dst_bucket_name
t0 = time.clock()
dst_bucket.copy_key(k.key, src_bucket_name, k.key)
print time.clock() - t0, '' seconds''
if len(keys) < maximum_keys:
print ''Done backing up.''
break
result_marker = keys[maximum_keys - 1].key
if __name__ ==''__main__'':main()
Lo uso en una tarea de rake (para una aplicación de Rails):
desc "Back up a file onto S3"
task :backup do
S3ID = "*****"
S3KEY = "*****"
SRCBUCKET = "primary-mzgd"
NUM_BACKUP_BUCKETS = 2
Dir.chdir("#{Rails.root}/lib/tasks")
system "./do_backup.py #{S3ID} #{S3KEY} #{SRCBUCKET} #{NUM_BACKUP_BUCKETS}"
end
Gracias. Utilizo una versión ligeramente modificada, donde solo copio archivos que no existen o tienen un tamaño diferente, y verifico el destino si la clave existe en la fuente. Encontré esto un poco más rápido para preparar el entorno de prueba:
def botoSyncPath(path):
"""
Sync keys in specified path from source bucket to target bucket.
"""
try:
conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
srcBucket = conn.get_bucket(AWS_SRC_BUCKET)
destBucket = conn.get_bucket(AWS_DEST_BUCKET)
for key in srcBucket.list(path):
destKey = destBucket.get_key(key.name)
if not destKey or destKey.size != key.size:
key.copy(AWS_DEST_BUCKET, key.name)
for key in destBucket.list(path):
srcKey = srcBucket.get_key(key.name)
if not srcKey:
key.delete()
except:
return False
return True
La respuesta con la mayor cantidad de upvotes mientras escribo esto es esta:
s3cmd sync s3://from/this/bucket s3://to/this/bucket
Es una respuesta útil. Pero a veces la sincronización no es lo que necesita (elimina archivos, etc.). Me tomó mucho tiempo descubrir esta alternativa que no es un script para simplemente copiar varios archivos entre los cubos. (OK, en el caso que se muestra a continuación no está entre cubos. Está entre las carpetas que no son realmente, pero funciona entre los cubos igualmente bien).
# Slightly verbose, slightly unintuitive, very useful:
s3cmd cp --recursive --exclude=* --include=file_prefix* s3://semarchy-inc/source1/ s3://semarchy-inc/target/
Explicación del comando anterior:
- -recursivo
En mi opinión, mi requisito no es recursivo. Simplemente quiero múltiples archivos. Pero recursivo en este contexto simplemente le dice a s3cmd cp que maneje varios archivos. Estupendo. - -excluir
Es una manera extraña de pensar en el problema. Comience por seleccionar recursivamente todos los archivos. A continuación, excluya todos los archivos. ¿Esperar lo? - -incluir
Ahora estamos hablando. Indique el prefijo del archivo (o sufijo o cualquier patrón) que desee incluir.
s3://sourceBucket/ s3://targetBucket/
Esta parte es lo suficientemente intuitiva. Aunque técnicamente parece violar el ejemplo documentado de la ayuda s3cmd que indica que debe especificarse un objeto fuente:
s3cmd cp s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]
Necesitaba copiar un cubo muy grande, así que adapté el código de la pregunta en una versión multihilo y lo puse en GitHub.
También puede usar la interfaz web para hacerlo:
- Ve al cubo fuente en la interfaz web.
- Marque los archivos que desea copiar (use los cambios y los clics del mouse para marcar varios).
- Presione Acciones-> Copiar.
- Ir al cubo de destino.
- Presione Acciones-> Pegar.
Eso es.
También puede usar s3funnel que usa multi-threading:
https://github.com/neelakanta/s3funnel
ejemplo (sin la clave de acceso o los parámetros clave secreta mostrados):
s3funnel source-bucket-name list | copia de s3funnel dest-bucket-name --source-bucket source-bucket-name --threads = 10
s3cmd no copiará cp con solo prefijos o comodines, pero puede guiar el comportamiento con ''s3cmd ls sourceBucket'', y awk para extraer el nombre del objeto. Luego use ''s3cmd cp sourceBucket / name destBucket'' para copiar cada nombre de objeto en la lista.
Yo uso estos archivos por lotes en un cuadro de DOS en Windows:
s3list.bat
s3cmd ls %1 | gawk "/s3/{ print /"//"/"/"substr($0,index($0,/"s3:///"))/"//"/"/"; }"
s3copy.bat
@for /F "delims=" %%s in (''s3list %1'') do @s3cmd cp %%s %2
s3cmd sync s3://from/this/bucket/ s3://to/this/bucket/
Para ver las opciones disponibles, usa: $s3cmd --help