Хранение учетных данных Amazon S3 в переменных среды .bashrc приводит к сбою приложения Rails - PullRequest
8 голосов
/ 14 февраля 2010

Я разрабатываю приложение rails, которое использует скрепку для хранения вещей на Amazon S3. Приложение размещено на Heroku. Я занимаюсь разработкой Ubuntu Karmic.

Проблема, которую я собираюсь описать, возникает в разработке (на моем локальном хосте) и в производстве (на Heroku).


Стандартный способ передачи кредитов S3 в paperclip - поместить их в config / s3.yml следующим образом:

access_key_id: 12345678
secret_access_key: 903490409fdf09fshsfdoif/43432

Когда я делаю это, все работает просто отлично. Но это затрудняет передачу моего кода другим, поэтому Heroku предлагает альтернативный метод - http://docs.heroku.com/config-vars.

Они советуют вам поместить ваши S3_KEY и S3_SECRET в ваш .bashrc следующим образом:

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

Затем они предлагают вам создать config / initializers / s3.yml (обратите внимание на немного другой путь) и поместить в этот файл следующее:

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

НО, когда я это делаю, скрепка выбрасывает воблер и выплевывает следующее сообщение об ошибке:

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 

Очевидно, что все начинается в модуле storage.rb. Переход по трассе стека:

Метод parse_credentials в строке 176 помечен - вот вызов, как показано в коде:

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

Метод parse_credentials пытается вызвать другой метод, find_credentials, и именно здесь я считаю, что проблема заключается в этом. Вот код для 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

Я не вижу, как устроен метод find_credentials для чтения значений из моего файла .bashrc. У него есть два случая, когда он может читать из YAML, и один, где он ищет хеш.

Моя модель ссылается на учетные данные примерно так:

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

Если я удалю хеш: s3_credentials из модели, ошибка stringify_keys исчезнет, ​​и консоль rails выдаст сообщение об ошибке, которое появляется в конце метода find_credentials: т. Е. «Учетные данные не являются путем, файлом или хэшем» .

Так что я в тупике. Я понимаю, что это, возможно, вопрос к парням из Heroku (кому я действительно собираюсь отправить эту ссылку по электронной почте в надежде, что они могут ответить на него), и, возможно, это также вопрос для doods в thinkbot.

Как я уже говорил в начале, мое приложение работает нормально, когда я использую стандартный подход, в котором мой ключ и секрет вставляются в config / s3.yml, но я бы предпочел использовать метод, предложенный Heroku, потому что он облегчает работу. для меня, и это означает, что я могу хранить репо на своей общедоступной странице github, чтобы другие могли использовать его без необходимости писать какие-либо драйверы слияния клиентов в Git, чтобы мои ключи API были недоступны для общего доступа.

Я пытался вставить переменные ENV в etc / bash.bashrc, а также ~ / .bashrc, и после перезагрузки у меня все еще остается та же проблема. Проблемы возникают как на машине разработки, так и на Heroku. Я позаботился о том, чтобы перенести мои конфиг-вары в Heroku.

Ответы [ 3 ]

13 голосов
/ 17 февраля 2010

После долгих поисков я нашел ответ здесь - http://tammersaleh.com/posts/managing-heroku-environment-variables-for-local-development

Хитрость заключается в том, чтобы полностью удалить файл S3.rb и просто обратиться к переменным ENV в модели следующим образом:

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

В любом случае, Дэвид, спасибо за ваше предложение. Я не знаю, хотите ли вы обновить документы Heroku, чтобы сказать, что некоторым пользователям приходилось делать это таким образом. Еще раз спасибо.

2 голосов
/ 16 февраля 2010

Переименуйте файл config/initializers/s3.yml в config/initializers/s3.rb и попробуйте.

1 голос
/ 03 мая 2011

Вот ваша проблема:

:bucket         => ENV['S3_BUCKET'],

должно быть

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

, т.е. назначения не интерпретируются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...