Skip to content
Browse files

Super long and informative post install documentation.

  • Loading branch information...
1 parent b499c40 commit 21e472f9a86cb68da121a9b1a54524575737625b @martinemde martinemde committed Aug 14, 2012
Showing with 90 additions and 58 deletions.
  1. +9 −3 PostInstall.txt
  2. +12 −0 lib/engineyard/cli.rb
  3. +66 −44 lib/engineyard/cli/api.rb
  4. +1 −5 lib/engineyard/eyrc.rb
  5. +1 −1 spec/engineyard/eyrc_spec.rb
  6. +0 −4 spec/spec_helper.rb
  7. +1 −1 spec/support/helpers.rb
View
12 PostInstall.txt
@@ -2,23 +2,29 @@ Thank you for downloading engineyard gem version 2!
############ NOTICE when upgrading from 1.x to 2.x ############
-* IMPORTANT: eydeploy.rb modifications MUST be verified!
+First, if you have any trouble, you can uninstall this version to downgrade.
+This version of the CLI does not affect the web deploy system.
+Please file a support ticket if you have any issues at: support.cloud.engineyard.com
+
+* IMPORTANT: eydeploy.rb modifications MUST be verified in staging!
Many internals have changed that could break eydeploy.rb!
-* The order of compile assets has *changed*. It now runs before
+* The order of compile_assets has *changed*. It now runs before
the maintenance page is enabled, to reduce downtime.
* ey.yml files should be checked in to your repository.
-* Default bundler version is now 1.1.3.
+* Default bundler version is now 1.1.5.
A few other nice changes:
* All CLI commands are significantly faster. Woo!
* Deploy hooks now have access to `account_name` and `environment_name`.
+* Deploy hooks can now use run! and sudo! to abort on failure.
* Supports new ey.yml options when ey.yml is committed:
* maintenance_on_restart: true/false (default: false except for glassfish and mongrel)
* maintenance_on_migrate: true/false (default: true)
* precompile_assets: true/false (default: inferred using app/assets and config/application.rb)
* ignore_database_adapter_warning: true (hides adapter warning)
* Don't remove maintenance pages that weren't put up during this deploy if maintenance options (above) are set to false.
+* ey web restart - restarts web servers without deploying.
Deploying for the first time? The Engine Yard Pandas want to help you!
Email pandas@engineyard.com with your questions.
View
12 lib/engineyard/cli.rb
@@ -458,6 +458,18 @@ def whoami
end
desc "login", "Log in and verify access to Engine Yard Cloud."
+ long_desc <<-DESC
+ You may run this command to log in to EY Cloud without performing
+ any other action.
+
+ Once you are logged in, a file will be stored at ~/.eyrc with your
+ API token. You may override the location of this file using the
+ $EYRC environment variable.
+
+ Instead of logging in, you may specify a token on the command line
+ with --api-token or using the $ENGINEYARD_API_TOKEN environment
+ variable.
+ DESC
def login
whoami
end
View
110 lib/engineyard/cli/api.rb
@@ -5,71 +5,93 @@
module EY
class CLI
class API
- def self.authenticate(ui)
- ui.info("We need to fetch your API token; please log in.")
- begin
- email = ui.ask("Email: ")
- password = ui.ask("Password: ", true)
- token = EY::CloudClient.authenticate(email, password, ui)
- EY::EYRC.load.api_token = token
- token
- rescue EY::CloudClient::InvalidCredentials
- ui.warn "Invalid username or password; please try again."
- retry
- end
- end
+ USER_AGENT = "EngineYard/#{EY::VERSION}"
attr_reader :token
def initialize(endpoint, ui, token = nil)
+ @client = EY::CloudClient.new(:endpoint => endpoint, :output => ui.out, :user_agent => USER_AGENT)
@ui = ui
- EY::CloudClient.endpoint = endpoint
-
- # If the token is specified, we don't ask for authentication when
- # the token is reject, we just exit.
- if @token = token
- @specified = true
- @source = 'token from --api-token'
- elsif @token = ENV['ENGINEYARD_API_TOKEN']
- @specified = true
- @source = 'token from $ENGINEYARD_API_TOKEN'
- elsif @token = EY::EYRC.load.api_token
- @specified = false
- @source = "api_token in #{EY::EYRC.load.path}"
- elsif @token = self.class.authenticate(ui)
- @specified = false
- @source = 'credentials'
- else
- raise EY::Error, "Sorry, we couldn't get your API token."
- end
-
- @api = EY::CloudClient.new(@token, @ui)
+ @eyrc = EY::EYRC.load
+ token_from('--api-token') { token } ||
+ token_from('$ENGINEYARD_API_TOKEN') { ENV['ENGINEYARD_API_TOKEN'] } ||
+ token_from(@eyrc.path, false) { @eyrc.api_token } ||
+ authenticate ||
+ token_not_loaded
end
def respond_to?(*a)
- super or @api.respond_to?(*a)
+ super or @client.respond_to?(*a)
end
protected
def method_missing(meth, *args, &block)
- if @api.respond_to?(meth)
- @api.send(meth, *args, &block)
+ if @client.respond_to?(meth)
+ with_reauthentication { @client.send(meth, *args, &block) }
else
super
end
- rescue EY::CloudClient::InvalidCredentials
- if @specified
- ui.error "Authentication failed: Invalid #{@source}."
- exit(255)
+ end
+
+ def with_reauthentication
+ begin
+ yield
+ rescue EY::CloudClient::InvalidCredentials
+ if @specified || !@ui.interactive?
+ # If the token is specified, we raise immediately if it is rejected.
+ raise EY::Error, "Authentication failed: Invalid #{@source}."
+ else
+ @ui.warn "Authentication failed: Invalid #{@source}."
+ authenticate
+ retry
+ end
+ end
+ end
+
+ # Get the token from the provided block, saving it if it works.
+ # Returns true if it gets a token.
+ # Returns false if there is no token.
+ def token_from(source, specified = true)
+ token = yield
+ if token
+ @client.token = token
+ @specified = specified
+ @source = "token from #{source}"
+ @token = token
+ true
else
- ui.warn "Authentication failed: Invalid #{@source}. Retrying..."
- @token = self.class.authenticate(@ui)
- @api = EY::CloudClient.new(@token, @ui)
+ false
+ end
+ end
+
+ # Load the token from EY Cloud if interactive and
+ # token wasn't explicitly specified previously.
+ def authenticate
+ if @specified
+ return false
+ end
+
+ @source = "credentials"
+ @specified = false
+
+ @ui.info("We need to fetch your API token; please log in.")
+ begin
+ email = @ui.ask("Email: ")
+ passwd = @ui.ask("Password: ", true)
+ @token = @client.authenticate!(email, passwd)
+ @eyrc.api_token = @token
+ true
+ rescue EY::CloudClient::InvalidCredentials
+ @ui.warn "Authentication failed. Please try again."
retry
end
end
+ # Occurs when all avenues for getting the token are exhausted.
+ def token_not_loaded
+ raise EY::Error, "Sorry, we couldn't get your API token."
+ end
end
end
end
View
6 lib/engineyard/eyrc.rb
@@ -9,7 +9,7 @@ def self.load
end
def initialize(path)
- self.path = path
+ @path = Pathname.new(path)
end
def exist?
@@ -30,10 +30,6 @@ def api_token=(token)
private
- def path=(p)
- @path = Pathname.new(p).expand_path
- end
-
def [](key)
read_data[key.to_s]
end
View
2 spec/engineyard/eyrc_spec.rb
@@ -11,7 +11,7 @@
it "looks for .eyrc in $HOME/.eyrc by default" do
ENV.delete('EYRC')
- EY::EYRC.load.path.should == Pathname.new("~/.eyrc").expand_path
+ EY::EYRC.load.path.should == Pathname.new("~/.eyrc")
end
end
View
4 spec/spec_helper.rb
@@ -72,10 +72,6 @@ def clean_eyrc
ENV["NO_SSH"] = "true"
end
- config.before(:each) do
- EY::CloudClient.default_endpoint!
- end
-
config.after(:all) do
clean_eyrc
end
View
2 spec/support/helpers.rb
@@ -75,7 +75,7 @@ def initialize(stdout, stderr)
ZeroExitStatus = Class.new(UnexpectedExit)
def ey_api
- @api ||= EY::CloudClient.new('asdf', EY::CLI::UI.new)
+ @api ||= EY::CloudClient.new(:token => 'asdf')
end
def ensure_eyrc

0 comments on commit 21e472f

Please sign in to comment.
Something went wrong with that request. Please try again.