วิธีสร้าง 10,000 ไฟล์ใน S3 สาธารณะ


93

ฉันมีโฟลเดอร์ในที่เก็บข้อมูล 10,000 ไฟล์ ดูเหมือนว่าจะไม่มีวิธีใดในการอัปโหลดและทำให้เป็นแบบสาธารณะทันที ดังนั้นฉันจึงอัปโหลดทั้งหมดเป็นแบบส่วนตัวและฉันต้องทำให้เป็นแบบสาธารณะทั้งหมด

ฉันได้ลองใช้คอนโซล aws แล้วมันทำให้เกิดข้อผิดพลาด (ทำงานได้ดีกับโฟลเดอร์ที่มีไฟล์น้อยกว่า)

ฉันได้ลองใช้ S3 จัดระเบียบใน Firefox เหมือนกัน

มีซอฟต์แวร์หรือสคริปต์บางตัวที่ฉันสามารถเรียกใช้เพื่อทำให้สิ่งเหล่านี้เป็นสาธารณะได้หรือไม่


4
เครื่องมือทุกอย่างที่ฉันลองผิดพลาดดังนั้นฉันจึงเขียนสคริปต์ PHP ที่ใช้เวลาสองสามชั่วโมงและวนซ้ำทุกวัตถุในที่เก็บข้อมูลและทำให้เป็นสาธารณะ
PeterV

คำตอบ:


120

คุณสามารถสร้างนโยบายที่เก็บข้อมูล (ดูตัวอย่างด้านล่าง) ซึ่งให้สิทธิ์เข้าถึงไฟล์ทั้งหมดในที่เก็บข้อมูล คุณสามารถเพิ่มนโยบายที่เก็บข้อมูลลงในที่เก็บข้อมูลผ่านคอนโซล AWS

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

ดูที่เครื่องมือสร้างนโยบายต่อไปนี้ที่จัดทำโดย Amazon

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


5
สิ่งนี้ไม่ได้ผลสำหรับฉัน ออบเจ็กต์บางอย่างยังคงส่งคืนการตอบสนอง "การเข้าถึงถูกปฏิเสธ" แม้ว่าจะมีนโยบายที่เก็บข้อมูลอยู่ก็ตาม คัดลอกวางจากด้านบนโดยมีการเปลี่ยนชื่อที่เก็บข้อมูลเท่านั้น ฉันเดาว่าถึงเวลาที่ต้องเขียนสคริปต์เพื่อวนรอบวัตถุทั้งหมด 1.3 ล้านชิ้น ... ค่อนข้างน่ารำคาญ
Blake Miller

คุณต้องเปลี่ยน "ถัง" เป็นชื่อถังของคุณ
karnage

11
ฉันไม่พอใจที่ต้องทำแบบนี้ นั่นคือ JSON ที่น่าเกลียด
superluminary

7
เพียงบันทึก: มันอาจดูเหมือนชัดเจน แต่คุณยังสามารถเลือกที่จะ จำกัด การเข้าถึงเฉพาะโฟลเดอร์bucket/avatars/* : (อย่าลืม*ตอนท้ายฉันทำและวิ่งวนเป็นวงกลมอยู่พักหนึ่ง)
bschaeffer

2
@Benjamin การกำหนดค่า "พื้นฐาน" สำหรับคุณคืออะไรไม่เหมาะสมสำหรับผู้อื่นเนื่องจากข้อกำหนดด้านความปลอดภัยของทุกคนแตกต่างกัน AWS มีวิธีการที่สม่ำเสมอในการปรับแต่งนโยบายเหล่านี้ ดังนั้นเราต้องใช้เวลาในการเรียนรู้นโยบายความปลอดภัยอย่างถูกต้องและอย่าอายจาก JSON เพียงไม่กี่บรรทัด
afilina

71

หากคุณกำลังอัปโหลดเป็นครั้งแรกคุณสามารถตั้งค่าไฟล์เป็นสาธารณะเมื่ออัปโหลดบนบรรทัดคำสั่ง:

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

ตามที่ระบุไว้ในการใช้คำสั่ง s3 ระดับสูงกับ AWS Command Line Interface

น่าเสียดายที่จะใช้ ACL เมื่ออัปโหลดไฟล์เท่านั้น มันไม่ (ในการทดสอบของฉัน) ใช้ ACL กับไฟล์ที่อัปโหลดแล้ว

หากคุณต้องการอัปเดตวัตถุที่มีอยู่คุณเคยสามารถซิงค์ที่เก็บข้อมูลกับตัวเองได้ แต่ดูเหมือนว่าจะหยุดทำงาน

[ไม่ทำงานอีกต่อไป] สามารถทำได้จากบรรทัดคำสั่ง:

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

(ดังนั้นสิ่งนี้จึงไม่ตอบคำถามอีกต่อไป แต่ทิ้งคำตอบไว้สำหรับการอ้างอิงตามที่เคยใช้ได้ผล)


คำสั่งนี้มีผลกับไฟล์ที่อัปโหลดแล้ว แต่ยังไม่ได้อ่านแบบสาธารณะหรือไม่?
Alston

10
เมื่อฉันทดสอบดูเหมือนว่าจะเพิ่ม ACL ลงในไฟล์ที่ซิงค์ใหม่เท่านั้น
David Roussel

ขอบคุณสำหรับการเล่นซ้ำฉันทดสอบด้วย มีวิธีใดบ้างในการเปลี่ยนการอนุญาตของไฟล์ที่อัปโหลดเป็นกลุ่ม?
Alston

โอ้ไม่น่าแปลกใจเลย ฉันสับสนกับสิ่งนี้ ขอบคุณจริงๆที่คุณชี้แจง
Sridhar Sarnobat

คำตอบปรับปรุงเพื่อรวมวิธีการเปลี่ยนไฟล์ที่มีอยู่
David Roussel

34

ฉันต้องเปลี่ยนวัตถุหลายแสนชิ้น ฉันยิงอินสแตนซ์ EC2 ขึ้นเพื่อเรียกใช้สิ่งนี้ซึ่งทำให้ทุกอย่างเร็วขึ้น คุณจะต้องติดตั้งไฟล์aws-sdkอัญมณีก่อน

นี่คือรหัส:

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
วิธีง่ายๆคืออัปโหลดโดยใช้แฟล็ก public_read ตั้งแต่แรก แต่ไม่สำเร็จนี่เป็นตัวเลือกที่ดี
superluminary

การตัดโค้ดนี้ล้าสมัยโปรดดูคำตอบ
ksarunas

26

ฉันมีปัญหาเดียวกันการแก้ปัญหาโดย @DanielVonFange ล้าสมัยเนื่องจาก SDK เวอร์ชันใหม่หมด

การเพิ่มข้อมูลโค้ดที่เหมาะกับฉันในตอนนี้ด้วย 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
คำตอบที่ยอดเยี่ยม - เพียงแค่สคริปต์ที่ฉันต้องการในจุดที่ จำกัด
Phantomwhale

@ksarunas ในกรณีของฉันฉันต้องเปลี่ยนการอนุญาตสาธารณะเป็นสิทธิ์ส่วนตัวดังนั้นแทนที่การอ่านแบบสาธารณะเป็นแบบส่วนตัวและการเข้าถึงมีการเปลี่ยนแปลง แต่ฉันยังสามารถเข้าถึง URL ได้หรือไม่
ราหุล

19

เพียงแค่ต้องการเพิ่มสิ่งนั้นด้วย S3 Console ใหม่คุณสามารถเลือกโฟลเดอร์ของคุณและเลือกที่Make publicจะทำให้ไฟล์ทั้งหมดในโฟลเดอร์เป็นสาธารณะ ทำงานเป็นงานพื้นหลังดังนั้นจึงควรจัดการไฟล์จำนวนเท่าใดก็ได้

ทำให้เป็นสาธารณะ


5
น่าเสียดายที่ใช้เวลานานและคุณไม่สามารถปิดเบราว์เซอร์ได้ในขณะที่คำสั่งทำงานอยู่ เบราว์เซอร์ของคุณกำลังส่งคำขอ 2 รายการสำหรับแต่ละไฟล์ในกรณีของฉันคำขอทั้งสองใช้เวลา 500 มิลลิวินาที หากคุณมีไฟล์จำนวนมากจะใช้เวลานาน = (
Herlon Aguiar

2
และยังมีปัญหาอีกประการหนึ่ง: สิ่งนี้จะเปิดเผยต่อสาธารณะอย่างเต็มที่ หากคุณต้องการเพียงการเข้าถึงแบบสาธารณะนั่นคือปัญหา
Marcelo Agimóvel

ระวังให้มาก - ฉันทำสิ่งนี้ให้เป็นสาธารณะและ "แถบความคืบหน้า" ที่ปรากฏขึ้นนั้นละเอียดมากฉันคิดว่าเสร็จแล้ว ฉันตรวจสอบและอาจใช้เวลาหนึ่งชั่วโมงในการทำสิ่งนี้ก่อนที่ฉันจะรู้ว่าคุณคลิกทำให้เป็นสาธารณะและ "แถบความคืบหน้าเล็ก ๆ ที่ละเอียดอ่อนปรากฏขึ้น" ... grrr ... เนื่องจากฉันปิดหน้าต่างเบราว์เซอร์ประมาณ 10 ครั้งฉันคิดว่ามันฆ่ามันทุกครั้ง . ฉันกำลังใช้งานอยู่ตอนนี้ - ค่อนข้างเร็ว - อาจจะ 20 นาทีสำหรับภาพ 120k
Scott

12

การใช้ 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
คุณไม่สามารถใช้ไปป์เพื่อ grep แทนการเขียนลงดิสก์ด้วย files.txt ทั้งหมดได้หรือไม่? นี้ได้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

หากสิ่งนี้ต้องการตัวเอง แต่จำนวนไฟล์ทำให้ช้าในการทำแบบอนุกรม ดังนั้นฉันจึงเขียนสคริปต์ที่ไม่ได้อยู่บนiron.io 's ช่างเหล็กบริการชั่วโมงการคำนวณฟรี 500 ชั่วโมงต่อเดือนของพวกเขาเพียงพอที่จะจัดการกับที่เก็บข้อมูลขนาดใหญ่ได้ (และหากคุณทำเกินราคาก็สมเหตุสมผล) เนื่องจากมันทำแบบขนานมันจะเสร็จสิ้นภายในเวลาไม่ถึงหนึ่งนาทีสำหรับวัตถุ 32,000 ชิ้นที่ฉันมี นอกจากนี้ฉันเชื่อว่าเซิร์ฟเวอร์ของพวกเขาทำงานบน EC2 ดังนั้นการสื่อสารระหว่างงานและ S3 จึงรวดเร็ว

ทุกคนสามารถใช้สคริปต์ของฉันตามความต้องการของตนเองได้


2

ดูBucketExplorerซึ่งจัดการการดำเนินงานจำนวนมากได้เป็นอย่างดีและเป็นไคลเอนต์ S3 ที่มั่นคง


3
ขณะนี้ยังสามารถเปลี่ยนการอนุญาตจำนวนมากใน Cyberduck (ฟรี) ผ่านจานข้อมูล
Taylor Edmiston

BucketExplorer จะมีประโยชน์ก็ต่อเมื่อคุณได้รับอนุญาตให้แสดงรายการที่เก็บข้อมูลทั้งหมด ดีกว่ามากในการใช้ CLI หรือ SDK สำหรับการดำเนินการนี้และปล่อยให้ผู้ใช้ของคุณมีสิทธิ์ที่ จำกัด
perilandmishap

0

คุณคิดว่าพวกเขาจะให้คนทั่วไปอ่านพฤติกรรมเริ่มต้นใช่ไหม :) ฉันแบ่งปันความไม่พอใจของคุณในขณะที่สร้าง API ที่กำหนดเองเพื่อเชื่อมต่อกับ S3 จากโซลูชัน C # นี่คือตัวอย่างข้อมูลที่อัปโหลดอ็อบเจ็กต์ S3 และตั้งค่าเป็นการเข้าถึงแบบอ่านสาธารณะโดยค่าเริ่มต้น:

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));
     }
}

ผลตอบแทนที่ได้ ToACLString (ACL) ฟังก์ชั่นที่สาธารณะอ่าน , BASE_SERVICE_URL เป็นs3.amazonaws.comและคง AWS_ACL_HEADER คือX-AMZ-ACL สิ่งต่างๆของปลั๊กและ DreamMessage อาจดูแปลกสำหรับคุณเนื่องจากเราใช้ Dream framework เพื่อปรับปรุงการสื่อสาร http ของเรา โดยพื้นฐานแล้วเรากำลังทำ http PUT ด้วยส่วนหัวที่ระบุและลายเซ็นส่วนหัวพิเศษตามข้อกำหนดของ aws (ดูหน้านี้ในเอกสาร awsสำหรับตัวอย่างวิธีสร้างส่วนหัวการอนุญาต)

หากต้องการเปลี่ยน ACL ของออบเจ็กต์ 1,000 รายการที่มีอยู่คุณสามารถเขียนสคริปต์ได้ แต่อาจจะง่ายกว่าถ้าใช้เครื่องมือ GUI เพื่อแก้ไขปัญหาเฉพาะหน้า สิ่งที่ดีที่สุดที่ฉันเคยใช้มาจาก บริษัท ชื่อcloudberryสำหรับ S3; ดูเหมือนว่าพวกเขามีการทดลองใช้ฟรี 15 วันสำหรับผลิตภัณฑ์อย่างน้อยหนึ่งอย่าง ฉันเพิ่งตรวจสอบแล้วว่าจะช่วยให้คุณสามารถเลือกหลายวัตถุพร้อมกันและตั้งค่า ACL เป็นสาธารณะผ่านเมนูบริบท สนุกกับคลาวด์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.