I appologise z góry za długość tego postu ....Przechowywanie poświadczeń Amazon S3 w .bashrc zmiennych environemental powoduje Rails app niepowodzenie
Zajmuję się tworzeniem aplikacji Rais, który używa spinacz do przechowywania rzeczy na Amazon S3. Aplikacja jest hostowana na Heroku. Pracuję nad Ubuntu Karmic.
Problem, który zamierzam opisać, pojawia się w fazie rozwoju (w moim lokalnym hostelu) i produkcji (na Heroku).
Standardowy sposób przekazywania creds S3 spinacza jest przez umieszczenie ich w config/s3.yml tak:
access_key_id: 12345678
secret_access_key: 903490409fdf09fshsfdoif/43432
Kiedy to zrobić, wszystko działa dobrze. Ale to utrudnia dzielenie się moim kodem z innymi, więc Heroku sugeruje alternatywną metodę - http://docs.heroku.com/config-vars.
Radzą, które należy umieścić S3_KEY i S3_SECRET do swojego .bashrc tak:
S3_KEY=12345678
export S3_KEY
S3_SECRET=903490409fdf09fshsfdoif/43432
export S3_SECRET
Następnie sugerują, że tworzenie config/inicjalizatory/s3.yml (zwróć uwagę na nieco inną drogą) i umieścić następujące w tym pliku:
AWS::S3::Base.establish_connection!(
:access_key_id => ENV['S3_KEY'],
:secret_access_key => ENV['S3_SECRET']
)
ale kiedy to zrobić, spinacz rzuca woblera i wypluwa następujący komunikat o błędzie:
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
Wyraźnie wszystko zaczyna się w module storage.rb. Krocząc przez śladu stosu:
Sposób parse_credentials na linii 176 jest oznaczony - oto wezwanie, gdyż pojawia się w kodzie:
def parse_credentials creds
creds = find_credentials(creds).stringify_keys
(creds[RAILS_ENV] || creds).symbolize_keys
end
Sposób parse_credentials próbuje wywołać inną metodą find_credentials, a to gdzie wierzę, że problem leży. Herezje kod 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
nie widzę, w jaki sposób metoda find_credentials jest przystosowany do odczytu wartości z mojego pliku .bashrc. Ma dwa przypadki, w których może czytać z YAML i jeden, gdzie szuka hasha.
Mój model odwołuje poświadczenia tak:
has_attached_file :photo,
(some code removed)
:s3_credentials => "#{RAILS_ROOT}/config/initializers/s3.yml",
Jeśli usunąć: s3_credentials skrót od modelu, błąd stringify_keys odchodzi i konsola szyny wyrzuca komunikat o błędzie, który pojawia się na końcu metoda find_credentials: tzn. "Poświadczenia nie są ścieżką, plikiem ani hash".
Więc jestem zakłopotany. Zdaję sobie sprawę, że jest to prawdopodobnie pytanie dla chłopaków z Heroku (do kogo mam zamiar wysłać ten link w nadziei, że mogą na nie odpowiedzieć) i jest to prawdopodobnie również pytanie do doodów w thinkbot, ale pomyślałem, że StackOverflow może być najlepszym miejscem, aby o to zapytać, ponieważ okazało się, że w przeszłości było to dość wiarygodne forum.
Jak już powiedziałem na początku, moja aplikacja działa poprawnie, gdy przyjmuję standardowe podejście do wtrącania klucza i sekretu do config/s3.yml, ale wolałbym użyć metody, którą sugeruje Heroku, ponieważ sprawia ona, że WAY łatwiejsze dla mnie i oznacza to, że mogę przechowywać moje repo na mojej publicznej stronie github, aby inni mogli z niego korzystać bez konieczności pisania jakichkolwiek sterowników scalających klientów w Git, aby zachować moje klucze APi z domeny publicznej.
Jeszcze raz przepraszam za długotrwały post, a jeśli dotarłeś tak daleko, pochwalam cię. Czy ktoś ma jakieś pomysły?
Próbowałem trzymać zmienne ENV w etc/bash.bashrc, a także ~/.bashrc i po ponownym uruchomieniu komputera nadal mam ten sam problem. Problemy pojawiają się na maszynie programistycznej, a także na Heroku. Upewniłem się również, aby wyposażyć moje config-vars również w Heroku.
Byłem w tym przez 8 godzin prosto! Pójdę teraz obejrzeć piłkę nożną.
Myślę, że to jest powód! – klew
Przepraszam, ludzie, to nie działa. ten sam problem, ten sam komunikat o błędzie. Wiem, że plik jest czytany, gdy otrzymam błąd nie znaleziono pliku, jeśli zmienię jego nazwę. Wiem również, że zmienne ENV są odczytywane, ponieważ otrzymuję wyjątek, jeśli zmienię nazwę klucza w S3.rb. W każdym razie, to nie koniec świata hte i myślę, że po prostu przejdę dalej i zostawię to w spokoju. Oznacza to po prostu, że będę musiał być bardzo ostrożny przy wkładaniu githuba, ale mogę z tym żyć. Dzięki za pomoc. Jeśli zadzwonię, dam ci znać. – stephenmurdoch
również - umieszcza ENV ['S3_KEY'] z konsoli szyn działa dobrze - więc myślę, że to może być tylko kwestia spinacza - i tak dziękuję – stephenmurdoch