rhc 0.95.14 → 0.96.9

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # OpenShift Command Line Tools (RHC) [![Build Status](https://secure.travis-ci.org/openshift/os-client-tools.png)](http://travis-ci.org/openshift/os-client-tools)
1
+ # OpenShift Command Line Tools (RHC) [![Build Status](https://secure.travis-ci.org/openshift/rhc.png)](http://travis-ci.org/openshift/rhc)
2
2
 
3
3
  The OpenShift command line tools allow you to manage your OpenShift
4
4
  applications from the command line. The [Getting Started
@@ -20,19 +20,18 @@ DEPENDENCIES:
20
20
  * ruby (1.8.7 or later)
21
21
  * rubygems
22
22
 
23
- Step 1: Create a domain to under which your applications will live:
23
+ Step 1: Run the setup command to configure your system:
24
24
 
25
- $ rhc domain create -n desirednamespace -l rhlogin
25
+ $ rhc setup
26
26
 
27
- The name you choose here will form part of your application's public
28
- URL.
27
+ Follow the instructions in setup to set your SSH keys and create a domain. The name you choose for your domain will form part of your application's public URL.
29
28
 
30
29
  Step 2: Create an OpenShift application:
31
30
 
32
- $ rhc app create -l rhlogin -a appname -r /path/to/new/git/repo -t <framework Ex: php-5.3>
31
+ $ rhc app create -a appname -r /path/to/new/git/repo -t <framework Ex: php-5.3>
33
32
 
34
33
  Once that's complete, follow the directions printed at the end of running
35
- rhc app create
34
+ rhc app create.
36
35
 
37
36
 
38
37
  ## Making changes to your application
@@ -46,6 +45,7 @@ git repo. Commit them, then push. For example:
46
45
 
47
46
  Then just reload your web page to see the changes.
48
47
 
48
+
49
49
  ## OS X Notes:
50
50
 
51
51
  git:
@@ -64,6 +64,7 @@ Installing git from MacPorts/HomeBrew/Fink/etc requires Xcode.
64
64
  Now obtain the client code, either via 'git clone' as above
65
65
  or via the rhc gem.
66
66
 
67
+
67
68
  ## Developing / Contributing
68
69
  We expect code contributions to follow these standards:
69
70
 
@@ -73,7 +74,7 @@ We expect code contributions to follow these standards:
73
74
  exec rake spec</code>. Features are in 'features/' and can be run with
74
75
  <code>bundle exec rake features</code> (although these tests runs
75
76
  against the gem installed locally so you will need to gem install
76
- first). See [README.md](https://github.com/openshift/os-client-tools/blob/master/features/README.md) in the features dir for more info.
77
+ first). See [README.md](https://github.com/openshift/rhc/blob/master/features/README.md) in the features dir for more info.
77
78
  3. We maintain 100% line coverage of all newly added code via spec
78
79
  testing. The build will fail if new code is added and it does not
79
80
  have full line coverage. Some old code is currently excluded until it
@@ -354,7 +354,7 @@ class Test3_SSH < Test::Unit::TestCase
354
354
  @@agent_keys ||= (
355
355
  begin
356
356
  Net::SSH::Authentication::Agent.connect.identities
357
- rescue
357
+ rescue Exception
358
358
  nil
359
359
  end
360
360
  )
@@ -362,11 +362,11 @@ class Test3_SSH < Test::Unit::TestCase
362
362
  end
363
363
 
364
364
  def agent_key_names
365
- @@agent_keys.map{|x| File.expand_path(x.comment) }
365
+ @@agent_keys.nil? ? nil : @@agent_keys.map{|x| File.expand_path(x.comment) }
366
366
  end
367
367
 
368
368
  def agent_key_fingerprints
369
- @@agent_keys.map{|x| x.to_s.split("\n")[1..-2].join('') }
369
+ @@agent_keys.nil? ? nil : @@agent_keys.map{|x| x.to_s.split("\n")[1..-2].join('') }
370
370
  end
371
371
 
372
372
  def libra_public_key
@@ -428,13 +428,16 @@ class Test3_SSH < Test::Unit::TestCase
428
428
 
429
429
  private
430
430
  def check_permissions(file,permission)
431
+ # IO#stat is platform-specific, on windows it's usually 644 but in fact it doesn't matter
432
+ permission = /.../ if RHC::Helpers.windows?
433
+
431
434
  file = File.expand_path(file)
432
435
 
433
436
  assert File.exists?(file), error_for(:file_not_found,file)
434
437
 
435
438
  perms = sprintf('%o',File.stat(file).mode)[-3..-1]
436
439
 
437
- assert_match permission, perms, error_for(:bad_permissions,[file,perms],permission.source)
440
+ assert_match(permission, perms, error_for(:bad_permissions,[file,perms],permission.source))
438
441
  end
439
442
  end
440
443
 
@@ -1,8 +1,7 @@
1
1
  $: << File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
2
+
2
3
  require 'rhc/coverage_helper'
3
- SimpleCov.at_exit do
4
- SimpleCov.result.format!
5
- end
4
+ SimpleCov.at_exit{ SimpleCov.result.format! } if defined? SimpleCov
6
5
 
7
6
  require 'rhc_helper'
8
7
  require 'rhc-rest'
@@ -8,6 +8,7 @@ require 'rhc/vendor/sshkey'
8
8
  require 'resolv'
9
9
  require 'uri'
10
10
  require 'highline/import'
11
+ require 'rhc'
11
12
  require 'rhc-rest'
12
13
  require 'rhc/helpers'
13
14
  require 'rhc/config'
@@ -20,7 +21,7 @@ module RHC
20
21
  DEFAULT_MAX_LENGTH = 16
21
22
  APP_NAME_MAX_LENGTH = 32
22
23
  MAX_RETRIES = 7
23
- DEFAULT_DELAY = 2
24
+ DEFAULT_DELAY = 2.0
24
25
  API = "1.1.3"
25
26
  PATTERN_VERSION=/\A\d+\.\d+\.\d+\z/
26
27
  @read_timeout = 120
@@ -362,6 +363,8 @@ end
362
363
 
363
364
  puts "Contacting #{url.scheme}://#{url.host}" if @mydebug
364
365
  req.set_form_data({'json_data' => json_data, 'password' => password})
366
+ req['User-Agent'] = RHC::Helpers.user_agent
367
+
365
368
  http = http.new(url.host, url.port)
366
369
  http.open_timeout = @connect_timeout
367
370
  http.read_timeout = @read_timeout
@@ -519,19 +522,11 @@ end
519
522
  app_uuid = application.uuid
520
523
  result = "Successfully created application: #{app_name}"
521
524
 
522
- # Since health_check_path is not returned, we need to fudge it for now
523
- health_check_path =
524
- case app_type
525
- when /^php/
526
- "health_check.php"
527
- when /^perl/
528
- "health_check.pl"
529
- else
530
- "health"
531
- end
525
+ # health check path now returned by the API
526
+ health_check_path = application.health_check_path
532
527
 
533
528
  puts "DEBUG: '#{app_name}' creation returned success." if @mydebug
534
- rescue Rhc::Rest::ResourceAccessException => e
529
+ rescue Rhc::Rest::ConnectionException, Rhc::Rest::ResourceAccessException => e
535
530
  print_response_err(Struct::FakeResponse.new(e.message,e.code))
536
531
  rescue Rhc::Rest::ValidationException => e
537
532
  validation_error_code = (e.code.nil?) ? 406 : e.code
@@ -737,61 +732,54 @@ IMPORTANT
737
732
  }
738
733
  end
739
734
 
735
+ #
736
+ # An application is considered available if the health check URL unambiguously returns a 1 or 0.
737
+ # Otherwise, if the root URL for the app successfully returns content it is also considered
738
+ # successful. In the future, applications that do not expose a public web interface will need
739
+ # a more advanced check mechanism, or the check should not prevent creation.
740
+ #
740
741
  def self.check_app_available(net_http, app_name, fqdn, health_check_path, result, git_url, repo_dir, no_git)
741
- #
742
- # Test several times, doubling sleep time between attempts.
743
- #
744
- sleep_time = 2
745
- attempt = 0
746
- puts "Confirming application '#{app_name}' is available" if @mydebug
747
- while attempt < MAX_RETRIES
748
- attempt += 1
749
- if @mydebug
750
- puts " Attempt # #{attempt}"
751
- else
752
- print CLEAR_LINE + "Confirming application '#{app_name}' is available: Attempt # #{attempt}"
753
- end
754
- $stdout.flush
755
- url = URI.parse("http://#{fqdn}/#{health_check_path}")
756
-
757
- sleep(2.0)
758
- begin
759
- response = net_http.get_response(url)
760
- rescue Exception => e
761
- response = nil
762
- end
763
- if !response.nil? && response.code == "200" && response.body[0,1] == "1"
764
- puts CLEAR_LINE + "Confirming application '#{app_name}' is available: Success!"
765
- puts ""
766
- puts "#{app_name} published: http://#{fqdn}/"
767
- puts "git url: #{git_url}"
768
-
769
- if @mydebug
770
- unless no_git
771
- puts "To make changes to '#{app_name}', commit to #{repo_dir}/."
772
- else
773
- puts <<LOOKSGOOD
742
+
743
+ available = MAX_RETRIES.times.any? do |i|
744
+ sleep i * DEFAULT_DELAY
745
+
746
+ puts "Checking if the application is available ##{i+1}"
747
+ if health_check_path and !health_check_path.empty?
748
+ value = open("http://#{fqdn}/#{health_check_path}").read[0,1] rescue nil
749
+ # TODO: I should be typed exception ApplicationHealthFailure
750
+ raise "ERROR: The application was unable to start. Please report this issue via the forums or IRC or file a bug through our public bug tracker." if value == '0'
751
+ next true if value == '1'
752
+ end
753
+ open("http://#{fqdn}") rescue nil
754
+ end
755
+
756
+ if available
757
+ puts "Application #{app_name} is available at: http://#{fqdn}/"
758
+ puts " Git URL: #{git_url}"
759
+
760
+ if @mydebug
761
+ unless no_git
762
+ puts "To make changes to '#{app_name}', commit to #{repo_dir}/."
763
+ else
764
+ puts <<LOOKSGOOD
774
765
  To make changes to '#{app_name}', you must first clone it with:
775
- git clone #{git_url}
766
+ git clone #{git_url}
776
767
 
777
768
  LOOKSGOOD
778
- puts "Then run 'git push' to update your OpenShift space."
779
- end
780
- end
781
- if result && !result.empty?
782
- puts "#{result}"
783
- end
784
- return true
785
- end
786
- if !response.nil? && @mydebug
787
- puts "Server responded with #{response.code}"
788
- puts response.body unless response.code == '503'
789
- end
790
- puts " sleeping #{sleep_time} seconds" if @mydebug
791
- sleep sleep_time
792
- sleep_time = delay(sleep_time)
769
+ puts "Then run 'git push' to update your OpenShift space."
770
+ end
793
771
  end
794
- return false
772
+ if result && !result.empty?
773
+ puts "#{result}"
774
+ end
775
+ true
776
+ else
777
+ puts "Application is not available"
778
+ false
779
+ end
780
+ rescue StandardError => e
781
+ puts e
782
+ false
795
783
  end
796
784
 
797
785
  def self.destroy_app(libra_server, net_http, app_name, rhlogin, password)
@@ -10,7 +10,9 @@ require 'rhc-rest/user'
10
10
 
11
11
  module Rhc
12
12
  module Rest
13
+ #API_VERSION = '1.1'
13
14
  @@headers = {:accept => :json}
15
+ #@@headers = {:accept => "application/json;version=#{Rhc::Rest::VERSION}"}
14
16
 
15
17
  def logger
16
18
  Logger.new(STDOUT)
@@ -60,7 +62,7 @@ module Rhc
60
62
  end
61
63
  end
62
64
 
63
- def send(request)
65
+ def request(request)
64
66
  begin
65
67
  response = request.execute
66
68
  #set cookie
@@ -69,10 +71,9 @@ module Rhc
69
71
  @@headers["cookie"] = "rh_sso=#{rh_sso}"
70
72
  end
71
73
  return parse_response(response) unless response.nil? or response.code == 204
72
- rescue RestClient::RequestTimeout, RestClient::ServerBrokeConnection, RestClient::SSLCertificateNotVerified => e
73
- raise ResourceAccessException.new("Failed to access resource: #{e.message}")
74
+ rescue RestClient::RequestTimeout, RestClient::ServerBrokeConnection => e
75
+ raise ConnectionException.new("Connection to server timed out or got interrupted: #{e.message}")
74
76
  rescue RestClient::ExceptionWithResponse => e
75
- #puts "#{e.response}"
76
77
  process_error_response(e.response)
77
78
  rescue Exception => e
78
79
  raise ResourceAccessException.new("Failed to access resource: #{e.message}")
@@ -22,7 +22,7 @@ module Rhc
22
22
  method = @links['ADD_CARTRIDGE']['method']
23
23
  payload = {:name => name}
24
24
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
25
- return send(request)
25
+ return request(request)
26
26
  end
27
27
 
28
28
  #Get all Cartridge for this applications
@@ -31,7 +31,7 @@ module Rhc
31
31
  url = @links['LIST_CARTRIDGES']['href']
32
32
  method = @links['LIST_CARTRIDGES']['method']
33
33
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
34
- return send(request)
34
+ return request(request)
35
35
  end
36
36
 
37
37
  #Start Application
@@ -41,7 +41,7 @@ module Rhc
41
41
  method = @links['START']['method']
42
42
  payload = {:event=> "start"}
43
43
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
44
- return send(request)
44
+ return request(request)
45
45
  end
46
46
 
47
47
  #Stop Application
@@ -55,7 +55,7 @@ module Rhc
55
55
  payload = {:event=> "stop"}
56
56
  end
57
57
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
58
- return send(request)
58
+ return request(request)
59
59
  end
60
60
 
61
61
  #Restart Application
@@ -65,7 +65,7 @@ module Rhc
65
65
  method = @links['RESTART']['method']
66
66
  payload = {:event=> "restart"}
67
67
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
68
- return send(request)
68
+ return request(request)
69
69
  end
70
70
 
71
71
  #Delete Application
@@ -74,7 +74,7 @@ module Rhc
74
74
  url = @links['DELETE']['href']
75
75
  method = @links['DELETE']['method']
76
76
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
77
- return send(request)
77
+ return request(request)
78
78
  end
79
79
  alias :delete :destroy
80
80
  end
@@ -16,7 +16,7 @@ module Rhc
16
16
  method = @links['START']['method']
17
17
  payload = {:event=> "start"}
18
18
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
19
- return send(request)
19
+ return request(request)
20
20
  end
21
21
 
22
22
  #Stop Cartridge
@@ -26,7 +26,7 @@ module Rhc
26
26
  method = @links['STOP']['method']
27
27
  payload = {:event=> "stop"}
28
28
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
29
- return send(request)
29
+ return request(request)
30
30
  end
31
31
 
32
32
  #Restart Cartridge
@@ -36,7 +36,7 @@ module Rhc
36
36
  method = @links['RESTART']['method']
37
37
  payload = {:event=> "restart"}
38
38
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
39
- return send(request)
39
+ return request(request)
40
40
  end
41
41
 
42
42
  #Reload Cartridge
@@ -46,7 +46,7 @@ module Rhc
46
46
  method = @links['RESTART']['method']
47
47
  payload = {:event=> "reload"}
48
48
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
49
- return send(request)
49
+ return request(request)
50
50
  end
51
51
 
52
52
  #Delete Cartridge
@@ -55,7 +55,7 @@ module Rhc
55
55
  url = @links['DELETE']['href']
56
56
  method = @links['DELETE']['method']
57
57
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
58
- return send(request)
58
+ return request(request)
59
59
  end
60
60
  alias :delete :destroy
61
61
  alias :delete :destroy
@@ -9,13 +9,14 @@ module Rhc
9
9
  logger.debug "Connecting to #{end_point}" if @mydebug
10
10
  credentials = Base64.encode64("#{username}:#{password}")
11
11
  @@headers["Authorization"] = "Basic #{credentials}"
12
+ @@headers["User-Agent"] = RHC::Helpers.user_agent rescue nil
12
13
  #first get the API
13
14
  RestClient.proxy = ENV['http_proxy']
14
15
  request = RestClient::Request.new(:url => end_point, :method => :get, :headers => @@headers)
15
16
  begin
16
17
  response = request.execute
17
18
  result = RHC::Json.decode(response)
18
- @links = send(request)
19
+ @links = request(request)
19
20
  rescue RestClient::ExceptionWithResponse => e
20
21
  logger.error "Failed to get API #{e.response}"
21
22
  rescue Exception => e
@@ -30,7 +31,7 @@ module Rhc
30
31
  method = @links['ADD_DOMAIN']['method']
31
32
  payload = {:id => id}
32
33
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
33
- return send(request)
34
+ return request(request)
34
35
  end
35
36
 
36
37
  #Get all Domain
@@ -39,7 +40,7 @@ module Rhc
39
40
  url = @links['LIST_DOMAINS']['href']
40
41
  method = @links['LIST_DOMAINS']['method']
41
42
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
42
- return send(request)
43
+ return request(request)
43
44
  end
44
45
 
45
46
  #Find Domain by namesapce
@@ -76,7 +77,7 @@ module Rhc
76
77
  url = @links['LIST_CARTRIDGES']['href']
77
78
  method = @links['LIST_CARTRIDGES']['method']
78
79
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
79
- return send(request)
80
+ return request(request)
80
81
  end
81
82
 
82
83
  #Find Cartridge by name
@@ -97,7 +98,7 @@ module Rhc
97
98
  url = @links['GET_USER']['href']
98
99
  method = @links['GET_USER']['method']
99
100
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
100
- return send(request)
101
+ return request(request)
101
102
  end
102
103
 
103
104
  #find Key by name
@@ -27,7 +27,7 @@ module Rhc
27
27
  timeout = 300 # 5 minute timeout for scalable app
28
28
  end
29
29
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload, :timeout => timeout)
30
- return send(request)
30
+ return request(request)
31
31
  end
32
32
 
33
33
  #Get all Application for this domain
@@ -36,7 +36,7 @@ module Rhc
36
36
  url = @links['LIST_APPLICATIONS']['href']
37
37
  method = @links['LIST_APPLICATIONS']['method']
38
38
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers)
39
- return send(request)
39
+ return request(request)
40
40
  end
41
41
 
42
42
  #Update Domain
@@ -46,7 +46,7 @@ module Rhc
46
46
  method = @links['UPDATE']['method']
47
47
  payload = {:id => new_id}
48
48
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
49
- return send(request)
49
+ return request(request)
50
50
  end
51
51
  alias :save :update
52
52
 
@@ -57,7 +57,7 @@ module Rhc
57
57
  method = @links['DELETE']['method']
58
58
  payload = {:force => force}
59
59
  request = RestClient::Request.new(:url => url, :method => method, :headers => @@headers, :payload => payload)
60
- return send(request)
60
+ return request(request)
61
61
  end
62
62
  alias :delete :destroy
63
63
  end