Jak upublicznić 10000 plików w S3


93

Mam folder w wiadrze z 10 000 plików. Wygląda na to, że nie ma możliwości ich przesłania i natychmiastowego upublicznienia. Więc przesłałem je wszystkie, są prywatne i muszę je wszystkie upublicznić.

Wypróbowałem konsolę aws, po prostu wyświetla błąd (działa dobrze z folderami z mniejszą liczbą plików).

Próbowałem użyć organizowania S3 w Firefoksie, to samo.

Czy jest jakieś oprogramowanie lub skrypt, który mogę uruchomić, aby wszystko to upublicznić?


4
Każde narzędzie, które próbowałem, uległo awarii, więc napisałem skrypt PHP, który zajął kilka godzin i po prostu przeszukałem każdy obiekt w wiadrze i upubliczniłem.
PeterV

Odpowiedzi:


119

Możesz wygenerować zasadę zasobnika (patrz przykład poniżej), która daje dostęp do wszystkich plików w zasobniku. Zasady zasobnika można dodać do zasobnika za pośrednictwem konsoli AWS.

{
    "Id": "...",
    "Statement": [ {
        "Sid": "...",
        "Action": [
            "s3:GetObject"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::bucket/*",
        "Principal": {
            "AWS": [ "*" ]
        }
    } ]
}

Spójrz także na następujące narzędzie do generowania zasad udostępniane przez Amazon.

http://awspolicygen.s3.amazonaws.com/policygen.html


5
To nie zadziałało dla mnie. Niektóre obiekty nadal zwracają odpowiedź „odmowa dostępu”, nawet jeśli obowiązuje zasada zasobnika. Jest wklejony z powyższego, ze zmienioną tylko nazwą zasobnika. Chyba czas napisać skrypt, który przejdzie przez wszystkie 1,3 miliona obiektów ... trochę irytujące
Blake Miller

musisz zmienić "wiadro" na nazwę swojego wiadra
karnage

11
Żałuję, że muszę to robić w ten sposób. To jakiś brzydki JSON.
superluminium

7
Tylko uwaga: To może wydawać się oczywiste, ale można również wybrać w celu ograniczenia dostępu do określonych folderów : bucket/avatars/*. (Nie zapomnij *o końcu. Zrobiłem to i przez chwilę
biegałem

2
@Benjamin To, co jest dla Ciebie „podstawową” konfiguracją, jest nieodpowiednie dla innych, ponieważ każdy ma inne wymagania dotyczące bezpieczeństwa. AWS zapewnia jednolity sposób dostosowywania tych zasad. Dlatego należy poświęcić trochę czasu, aby właściwie poznać zasady bezpieczeństwa i nie stronić od kilku prostych wierszy kodu JSON.
afilina

71

Jeśli przesyłasz po raz pierwszy, możesz ustawić pliki jako publiczne podczas przesyłania w wierszu poleceń:

aws s3 sync . s3://my-bucket/path --acl public-read

Jak udokumentowano w Korzystanie z poleceń wysokiego poziomu s3 z interfejsem wiersza poleceń AWS

Niestety, lista ACL jest stosowana tylko podczas przesyłania plików. Nie stosuje (w moich testach) listy ACL do już przesłanych plików.

Jeśli chcesz zaktualizować istniejące obiekty, kiedyś byłeś w stanie zsynchronizować zasobnik ze sobą, ale wydaje się, że przestało to działać.

[Już nie działa] Można to zrobić z wiersza poleceń:

aws s3 sync s3://my-bucket/path s3://my-bucket/path --acl public-read

(Więc to już nie odpowiada na pytanie, ale pozostawia odpowiedź w celach informacyjnych, tak jak kiedyś).


Czy to polecenie dotyczy plików, które zostały już przesłane, ale nie zostały jeszcze publicznie odczytane?
Alston

10
Kiedy go testowałem, wydaje się, że dodaje ACL tylko do nowo zsynchronizowanych plików.
David Roussel

Dziękuję za powtórkę, też to przetestowałem. Czy istnieją sposoby zbiorczej zmiany uprawnień do przesłanych plików?
Alston

Och, nic dziwnego. Byłem tym zdezorientowany. Naprawdę doceniam wyjaśnienie.
Sridhar Sarnobat

Zaktualizowano odpowiedź, aby zawierała informacje o sposobie zmiany istniejących plików.
David Roussel

34

Musiałem zmienić kilkaset tysięcy obiektów. Uruchomiłem instancję EC2, aby to uruchomić, dzięki czemu wszystko działa szybciej. aws-sdkNajpierw musisz zainstalować klejnot.

Oto kod:

require 'rubygems'
require 'aws-sdk'


# Change this stuff.
AWS.config({
    :access_key_id => 'YOURS_HERE',
    :secret_access_key => 'YOURS_HERE',
})
bucket_name = 'YOUR_BUCKET_NAME'


s3 = AWS::S3.new()
bucket = s3.buckets[bucket_name]
bucket.objects.each do |object|
    puts object.key
    object.acl = :public_read
end

2
Prostym sposobem jest przesłanie ich z flagą public_read ustawioną w pierwszej kolejności, ale w przeciwnym razie jest to dobra opcja.
superluminarium

Ten wycięty kod jest nieaktualny, zapoznaj się z moją odpowiedzią
ksarunas

26

Miałem ten sam problem, rozwiązanie @DanielVonFange jest przestarzałe, ponieważ nowa wersja SDK jest niedostępna.

Dodawanie fragmentu kodu, który teraz działa dla mnie z AWS Ruby SDK:

require 'aws-sdk'

Aws.config.update({
  region: 'REGION_CODE_HERE',
  credentials: Aws::Credentials.new(
    'ACCESS_KEY_ID_HERE',
    'SECRET_ACCESS_KEY_HERE'
  )
})
bucket_name = 'BUCKET_NAME_HERE'

s3 = Aws::S3::Resource.new
s3.bucket(bucket_name).objects.each do |object|
  puts object.key
  object.acl.put({ acl: 'public-read' })
end

1
Fantastyczna odpowiedź - po prostu skrypt, którego potrzebowałem w napiętym miejscu
Phantomwhale

@ksarunas W moim przypadku muszę zmienić uprawnienia publiczne na prywatne, więc zamień publiczne odczyt na prywatne i dostęp się zmienił, ale nadal mogę uzyskać dostęp do adresu URL?
Rahul

19

Chciałem tylko dodać, że dzięki nowej konsoli S3 możesz wybrać folder (y) i wybrać, Make publicaby wszystkie pliki w folderach były publiczne. Działa jako zadanie w tle, więc powinno obsługiwać dowolną liczbę plików.

Upublicznij


5
Niestety zajmuje to dużo czasu i nie można zamknąć przeglądarki, gdy polecenie jest uruchomione. Twoja przeglądarka wysyła 2 żądania dla każdego pliku, w moim przypadku dwa żądania zajęły 500 ms. Jeśli masz dużo plików, zajmie to dużo czasu = (
Herlon Aguiar

2
Jest jeszcze jeden problem: to zostanie w pełni upublicznione. Jeśli chcesz tylko publicznego dostępu do odczytu, to jest problem.
Marcelo Agimóvel

BĄDŹ BARDZO ŚWIADOMY - zrobiłem to Upublicznij, a "pasek postępu", który się pojawia, jest tak subtelny, że myślałem, że to zrobione. Sprawdziłem i prawdopodobnie spędziłem nad tym godzinę, zanim zdałem sobie sprawę, że klikasz Upublicznij i pojawia się mały subtelny "pasek postępu" ... grrr ... ponieważ zamykałem okno przeglądarki około 10 razy, zakładam, że za każdym razem je zabijało . Uruchamiam to teraz - to całkiem szybkie - może 20 minut dla 120 000 zdjęć
Scott

12

Korzystanie z CLI:

aws s3 ls s3://bucket-name --recursive > all_files.txt && grep .jpg all_files.txt > files.txt && cat files.txt | awk '{cmd="aws s3api put-object-acl --acl public-read --bucket bucket-name --key "$4;system(cmd)}'


3
nie mógłbyś po prostu użyć potoku do grep zamiast zapisywać na dysku wszystkie pliki.txt? Może to byćaws s3 ls s3://bucket-name --recursive | grep .jpg | awk '{cmd="aws s3api put-object-acl --acl public-read --bucket bucket-name --key "$4;system(cmd)}'
sakurashinken

3

Miałem taką potrzebę, ale liczba plików sprawia, że ​​praca seryjna jest DUŻO wolna. Więc napisałem skrypt , który robi to na iron.io „s ślusarz usług. Ich 500 darmowych godzin obliczeniowych miesięcznie wystarczy, aby obsłużyć nawet duże przedziały (a jeśli przekroczysz tę cenę, jest rozsądna). Ponieważ jest to wykonywane równolegle, trwa mniej niż minutę dla 32 000 obiektów, które miałem. Uważam również, że ich serwery działają na EC2, więc komunikacja między zadaniem a S3 jest szybka.

Każdy może wykorzystać mój skrypt do własnych potrzeb.


2

Spójrz na BucketExplorer, który bardzo dobrze zarządza operacjami masowymi i jest solidnym klientem S3.


3
Teraz można również zbiorczo zmieniać uprawnienia w Cyberduck (bezpłatnie) za pomocą palety Info.
Taylor Edmiston

BucketExplorer jest przydatny tylko wtedy, gdy masz uprawnienia do wyświetlania wszystkich zasobników. Znacznie lepiej jest użyć interfejsu wiersza polecenia lub zestawu SDK do tej operacji i pozostawić użytkownikom ograniczone uprawnienia.
perilandmishap

0

Można by pomyśleć, że upublicznią domyślne zachowanie, prawda? :) Podzieliłem się twoją frustracją podczas budowania niestandardowego interfejsu API do interfejsu z S3 z rozwiązania C #. Oto fragment kodu, który dokonuje przesłania obiektu S3 i domyślnie ustawia go na publiczny dostęp do odczytu:

public void Put(string bucketName, string id, byte[] bytes, string contentType, S3ACLType acl) {
     string uri = String.Format("https://{0}/{1}", BASE_SERVICE_URL, bucketName.ToLower());
     DreamMessage msg = DreamMessage.Ok(MimeType.BINARY, bytes);
     msg.Headers[DreamHeaders.CONTENT_TYPE] = contentType;
     msg.Headers[DreamHeaders.EXPECT] = "100-continue";
     msg.Headers[AWS_ACL_HEADER] = ToACLString(acl);
     try {
        Plug s3Client = Plug.New(uri).WithPreHandler(S3AuthenticationHeader);
        s3Client.At(id).Put(msg);
     } catch (Exception ex) {
        throw new ApplicationException(String.Format("S3 upload error: {0}", ex.Message));
     }
}

Funkcja ToACLString (acl) zwraca public-read , BASE_SERVICE_URL to s3.amazonaws.com, a stała AWS_ACL_HEADER to x-amz-acl . Wtyczka i DreamMessage prawdopodobnie będą wyglądać dziwnie, ponieważ używamy frameworka Dream do usprawnienia naszej komunikacji http. Zasadniczo robimy http PUT z określonymi nagłówkami i specjalną sygnaturą nagłówka zgodnie ze specyfikacjami aws (zobacz tę stronę w dokumentacji aws, aby zapoznać się z przykładami konstruowania nagłówka autoryzacji).

Aby zmienić istniejące listy ACL zawierające 1000 obiektów, można napisać skrypt, ale prawdopodobnie łatwiej jest użyć narzędzia GUI, aby naprawić natychmiastowy problem. Najlepsze, z których do tej pory korzystałem, pochodzi z firmy o nazwie malina moroszka dla S3; wygląda na to, że co najmniej jeden ze swoich produktów ma bezpłatny 15-dniowy okres próbny. Właśnie sprawdziłem, że pozwoli ci to wybrać wiele obiektów jednocześnie i ustawić ich ACL jako publiczną za pomocą menu kontekstowego. Ciesz się chmurą!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.