2010-02-14 31 views
7

tôi appologise trước cho độ dài của bài viết này ....Lưu trữ thông tin Amazon S3 trong các biến environemental .bashrc gây Rails app thất bại

Tôi đang phát triển một ứng dụng Rais có sử dụng kẹp giấy để lưu trữ nội dung trên Amazon S3. Ứng dụng được lưu trữ trên Heroku. Tôi đang phát triển trên Ubuntu Karmic.

Sự cố mà tôi sắp mô tả xảy ra trong quá trình phát triển (trên máy chủ cục bộ của tôi) và sản xuất (trên Heroku).


Cách tiêu chuẩn của truyền creds S3 để kẹp giấy là bằng cách đặt chúng trong config/s3.yml như vậy:

access_key_id: 12345678 
secret_access_key: 903490409fdf09fshsfdoif/43432 

Khi tôi làm điều này, mọi thứ hoạt động tốt. Nhưng điều này làm cho việc chia sẻ mã của tôi với những người khác trở nên khó khăn nên Heroku đề xuất một phương pháp thay thế - http://docs.heroku.com/config-vars.

Họ khuyên bạn nên đặt S3_KEY và S3_SECRET của bạn vào .bashrc của bạn như vậy:

S3_KEY=12345678 
export S3_KEY 
S3_SECRET=903490409fdf09fshsfdoif/43432 
export S3_SECRET 

Sau đó, họ đề nghị bạn nên tạo config/initializers/s3.yml (lưu ý đường dẫn hơi khác nhau) và đặt sau đây vào tập tin đó:

AWS::S3::Base.establish_connection!(
    :access_key_id  => ENV['S3_KEY'], 
    :secret_access_key => ENV['S3_SECRET'] 
) 

NHƯNG, Khi tôi làm điều này, kẹp giấy ném một người hay do dự và spits ra thông báo lỗi sau:

undefined method `stringify_keys' for #<String:0xb6d6c3f4> 

/vendor/plugins/paperclip/lib/paperclip/storage.rb:176:in `parse_credentials' 
/vendor/plugins/paperclip/lib/paperclip/storage.rb:138:in `extended' 
/vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `instance_eval' 
/vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `extended' 

.... other stuff 

Vì vậy, rõ ràng tất cả đều khởi động bên trong mô-đun lưu trữ.rb. Bước qua stack trace:

Phương pháp parse_credentials trên Line 176 được đánh dấu - đây là cuộc gọi như nó xuất hiện trong các mã:

def parse_credentials creds 
    creds = find_credentials(creds).stringify_keys 
    (creds[RAILS_ENV] || creds).symbolize_keys 
end 

Phương pháp parse_credentials cố gắng gọi một phương pháp khác, find_credentials, và đây là nơi tôi tin rằng vấn đề nằm. Heres mã cho find_credentials:

def find_credentials creds 
    case creds 
    when File 
     YAML::load(ERB.new(File.read(creds.path)).result) 
    when String 
     YAML::load(ERB.new(File.read(creds)).result) 
    when Hash 
     creds 
    else 
     raise ArgumentError, "Credentials are not a path, file, or hash." 
    end 
end 

Tôi không thể thấy phương thức find_credentials được trang bị để đọc các giá trị từ tệp .bashrc của tôi. Nó có hai trường hợp mà nó có thể đọc từ YAML và một trong những nơi mà nó đang tìm kiếm một băm.

Mô hình của tôi tham khảo các thông tin như sau:

has_attached_file :photo, 
       (some code removed) 
       :s3_credentials => "#{RAILS_ROOT}/config/initializers/s3.yml", 

Nếu tôi tháo: s3_credentials băm từ mô hình, lỗi stringify_keys biến mất và đường ray console ném được thông báo lỗi xuất hiện ở phần cuối của phương thức find_credentials: nghĩa là "Thông tin xác thực không phải là đường dẫn, tệp hoặc băm".

Vì vậy, tôi bị bối rối. Tôi nhận ra rằng đây có thể là một câu hỏi cho những người ở Heroku (tôi thực sự sẽ gửi email liên kết này đến với hy vọng rằng họ có thể trả lời) và nó cũng có thể là một câu hỏi cho các doods tại thinkbot, nhưng tôi nghĩ rằng StackOverflow có thể là nơi tốt nhất để hỏi điều này vì nó đã được chứng minh là một diễn đàn khá đáng tin cậy đối với tôi trong quá khứ.Như tôi đã nói lúc đầu, ứng dụng của tôi hoạt động tốt khi tôi sử dụng cách tiếp cận chuẩn của việc gắn chìa khóa và bí mật vào config/s3.yml, nhưng tôi thích sử dụng phương pháp mà Heroku đề xuất vì nó làm cho mọi thứ WAY dễ dàng hơn cho tôi và nó có nghĩa là tôi có thể lưu trữ repo của tôi trên trang github công khai của tôi để người khác sử dụng mà không cần phải viết bất kỳ trình điều khiển hợp nhất khách hàng nào trong Git để giữ các khóa api của tôi ra khỏi miền công cộng.

Một lần nữa, xin lỗi vì bài đăng dài và nếu bạn đã thực hiện điều này, tôi hoan nghênh bạn. Bất cứ ai có bất kỳ ý tưởng?

Tôi đã thử gắn các biến ENV trong etc/bash.bashrc cũng như ~/.bashrc và sau khi khởi động lại, tôi vẫn gặp sự cố tương tự. Các vấn đề xảy ra trên máy phát triển cũng như trên Heroku. Tôi cũng đã đảm bảo đẩy các cấu hình-vars của mình lên Heroku.

Tôi đã ở đó trong 8 giờ liên tục !! Tôi sẽ đi xem bóng đá ngay bây giờ.

Trả lời

13

Sau nhiều tìm kiếm tôi tìm thấy câu trả lời ở đây - http://tammersaleh.com/posts/managing-heroku-environment-variables-for-local-development

Bí quyết là để loại bỏ tập tin hoàn toàn các S3.rb và chỉ đề cập đến các biến ENV trong mô hình như vậy:

has_attached_file :photo, 
        #... 
        :storage  => :s3, 
        :bucket   => ENV['S3_BUCKET'], 
        :s3_credentials => { :access_key_id  => ENV['S3_KEY'], 
             :secret_access_key => ENV['S3_SECRET'] } 

Dù sao , David, cảm ơn đề nghị của bạn. Tôi không biết nếu bạn muốn cập nhật các tài liệu Heroku để nói rằng một số người dùng đã phải làm theo cách này. Cảm ơn một lần nữa mặc dù.

2

Đổi tên tệp config/initializers/s3.yml thành config/initializers/s3.rb và dùng thử.

+0

Tôi nghĩ rằng đây là lý do! – klew

+0

Xin lỗi, nó không hoạt động. cùng một vấn đề, cùng một thông báo lỗi. Tôi biết rằng các tập tin đang được đọc như tôi nhận được một lỗi không tìm thấy tập tin nếu tôi thay đổi tên của nó. Tôi cũng biết rằng các biến ENV đang được đọc khi tôi nhận được một ngoại lệ nếu tôi thay đổi tên của khóa trong S3.rb. Dù sao, nó không phải là kết thúc của thế giới hte và tôi nghĩ rằng tôi sẽ chỉ di chuyển từ đây và để nó một mình. Nó chỉ có nghĩa là tôi sẽ phải rất cẩn thận khi đưa công cụ vào github nhưng tôi có thể sống với điều đó. Cảm ơn bạn đã giúp đỡ. Nếu tôi nhận được nó làm việc tôi sẽ cho bạn biết tất cả. – stephenmurdoch

+0

cũng - đặt ENV ['S3_KEY'] từ giao diện điều khiển đường ray hoạt động tốt - vì vậy tôi nghĩ rằng nó có thể chỉ là một vấn đề kẹp giấy - cảm ơn anyway – stephenmurdoch

1

Dưới đây là vấn đề của bạn:

:bucket   => ENV['S3_BUCKET'], 

cần phải được

:bucket   => <%= ENV['S3_BUCKET'] %>, 

ví dụ: các bài tập không được giải thích.

Các vấn đề liên quan