rest_connection 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +7 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/config/rest_api_config.yaml.sample +7 -0
- data/examples/console.rb +10 -0
- data/examples/dev_setup.rb +26 -0
- data/examples/mysql_dev_rollback.rb +29 -0
- data/examples/relaunch_deployment.rb +45 -0
- data/examples/restart_instance_agent.rb +29 -0
- data/examples/right_scale_ec2_instances_api_test.rb +51 -0
- data/examples/run_ebs_sequence.rb +95 -0
- data/examples/run_ebs_terminate.rb +40 -0
- data/examples/run_mysql_chef_sequence.rb +43 -0
- data/examples/run_php_chef_sequence.rb +109 -0
- data/examples/set_deployment_template_href.rb +14 -0
- data/lib/rest_connection.rb +208 -0
- data/lib/rest_connection/mechanize_connection.rb +43 -0
- data/lib/rest_connection/rightscale/deployment.rb +36 -0
- data/lib/rest_connection/rightscale/executable.rb +49 -0
- data/lib/rest_connection/rightscale/instance.rb +43 -0
- data/lib/rest_connection/rightscale/right_script.rb +42 -0
- data/lib/rest_connection/rightscale/rightscale_api_base.rb +120 -0
- data/lib/rest_connection/rightscale/rightscale_api_resources.rb +22 -0
- data/lib/rest_connection/rightscale/server.rb +121 -0
- data/lib/rest_connection/rightscale/server_template.rb +31 -0
- data/lib/rest_connection/rightscale/status.rb +26 -0
- data/lib/rest_connection/ssh_hax.rb +141 -0
- data/rest_connection.gemspec +81 -0
- metadata +109 -0
data/README
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
RestConnection is a library designed to facilitate Restful connections to APIs using Basic auth and more. However! If you've done any API work you know that every API is different. The goal of RestConnection is to be as lean as possible and a EXAMPLE of how to use Net::HTTP in a restful way. Right now RestConnection uses JSON and Basic Auth, this is easy to change or expand on and it's written to give more control to the user of the library (You).
|
2
|
+
|
3
|
+
My hope is to include 'helper resources' for common API endpoints while maintaining a somewhat universal 'Connection' class that can be easily understood and modified to suit any Restful API needs. These resources will have a similar usage to ActiveResource.
|
4
|
+
|
5
|
+
The first API we will be supporting is the RightScale API.
|
6
|
+
|
7
|
+
I welcome any contributions or suggestions. Thanks!
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "rest_connection"
|
5
|
+
gemspec.summary = "lib for restful connections to the rightscale api"
|
6
|
+
gemspec.description = "provides rest_connection"
|
7
|
+
gemspec.email = "jeremy@rubyonlinux.org"
|
8
|
+
gemspec.homepage = "http://github.com/jeremyd/rest_connection"
|
9
|
+
gemspec.authors = ["Jeremy Deininger"]
|
10
|
+
gemspec.add_dependency('mechanize', '>= 0.9.3')
|
11
|
+
gemspec.add_dependency('activesupport')
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/examples/console.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
opts = Trollop::options do
|
8
|
+
opt :deployment, "deployment nickname", :type => :string, :required => true
|
9
|
+
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
10
|
+
opt :growl, "use growl notification (string) when servers are all operational, requires ruby-growl gem", :type => :string, :required => false
|
11
|
+
end
|
12
|
+
|
13
|
+
# find all servers in the deployment (the fast way)
|
14
|
+
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
15
|
+
servers = deployment.servers_no_reload
|
16
|
+
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
17
|
+
|
18
|
+
servers.each do |s|
|
19
|
+
s.wait_for_operational_with_dns
|
20
|
+
|
21
|
+
Net::SSH.start(s.dns_name, 'root', :keys => ['~/.ssh/publish-test']) do |ssh|
|
22
|
+
puts "setting up devmode: dropbox::install && devmode::setup_cookbooks"
|
23
|
+
puts ssh.exec!("rs_run_recipe -n 'dropbox::install'")
|
24
|
+
puts ssh.exec!("rs_run_recipe -n 'devmode::setup_cookbooks'")
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
opts = Trollop::options do
|
8
|
+
opt :deployment, "deployment nickname", :type => :string, :required => true
|
9
|
+
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
10
|
+
opt :hard, "hard reset, uninstalls right_resources premium gem (for code update), and restarts the instance agent", :type => :bool, :required => false
|
11
|
+
end
|
12
|
+
|
13
|
+
# find all servers in the deployment (the fast way)
|
14
|
+
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
15
|
+
servers = deployment.servers_no_reload
|
16
|
+
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
17
|
+
|
18
|
+
servers.each do |s|
|
19
|
+
s.wait_for_operational_with_dns
|
20
|
+
if opts[:hard]
|
21
|
+
s.spot_check("gem uninstall right_resources_premium") do |result|
|
22
|
+
puts result
|
23
|
+
end
|
24
|
+
s.spot_check("monit restart instance") do |result|
|
25
|
+
puts result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
s.run_recipe("database_test::dev_pristine_restore")
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
|
6
|
+
opts = Trollop::options do
|
7
|
+
opt :deployment, "deployment nickname", :type => :string, :required => false
|
8
|
+
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
9
|
+
opt :growl, "use growl notification (string) when servers are all operational, requires ruby-growl gem", :type => :string, :required => false
|
10
|
+
opt :id, "deployment id", :type => :string, :required => false
|
11
|
+
end
|
12
|
+
|
13
|
+
# find all servers in the deployment (the fast way)
|
14
|
+
if opts[:id]
|
15
|
+
deployment = Deployment.find_by_id(opts[:id])
|
16
|
+
else
|
17
|
+
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
18
|
+
end
|
19
|
+
servers = deployment.servers_no_reload
|
20
|
+
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
21
|
+
servers.each do |s|
|
22
|
+
# send stop
|
23
|
+
s.relaunch
|
24
|
+
end
|
25
|
+
|
26
|
+
# wait for termination
|
27
|
+
#servers.each do |s|
|
28
|
+
# s.wait_for_state('stopped')
|
29
|
+
#end
|
30
|
+
|
31
|
+
# relaunch
|
32
|
+
#servers.each do |s|
|
33
|
+
# s.start
|
34
|
+
#end
|
35
|
+
|
36
|
+
#if opts[:growl]
|
37
|
+
# require 'ruby-growl'
|
38
|
+
# servers.each do |s|
|
39
|
+
# s.wait_for_state('booting')
|
40
|
+
# end
|
41
|
+
# g = Growl.new "localhost", "ruby-growl",
|
42
|
+
# ["ruby-growl Notification"]
|
43
|
+
#g.notify "ruby-growl Notification", "It Came From Ruby-Growl",
|
44
|
+
# "Greetings!"
|
45
|
+
#end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
opts = Trollop::options do
|
8
|
+
opt :deployment, "deployment nickname", :type => :string, :required => true
|
9
|
+
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
10
|
+
opt :hard, "hard reset, uninstalls right_resources premium gem (for code update), and restarts the instance agent", :type => :bool, :required => false
|
11
|
+
end
|
12
|
+
|
13
|
+
# find all servers in the deployment (the fast way)
|
14
|
+
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
15
|
+
servers = deployment.servers_no_reload
|
16
|
+
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
17
|
+
|
18
|
+
servers.each do |s|
|
19
|
+
s.wait_for_operational_with_dns
|
20
|
+
if opts[:hard]
|
21
|
+
s.spot_check("gem uninstall right_resources_premium") do |result|
|
22
|
+
puts result
|
23
|
+
end
|
24
|
+
s.spot_check("monit restart instance") do |result|
|
25
|
+
puts result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
s.run_recipe("database_test::dev_pristine_restore")
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rest_connection'
|
3
|
+
require 'spec'
|
4
|
+
require '/var/spool/ec2/user-data'
|
5
|
+
|
6
|
+
describe Instance, "run this from an ec2_instance" do
|
7
|
+
before(:all) do
|
8
|
+
@this_instance = Instance.new
|
9
|
+
@this_instance.connection.settings[:api_url] = ENV['RS_API_URL']
|
10
|
+
@this_instance.connection.settings[:common_headers] = { 'X_API_VERSION' => '1.0' }
|
11
|
+
# when tests fail, we need this to ensure a fresh run
|
12
|
+
x = @this_instance.detach_ebs_volume(:device => '/dev/sdp')
|
13
|
+
sleep 10 if x
|
14
|
+
end
|
15
|
+
it "should create,attach,detach,delete an ebs_volume" do
|
16
|
+
sleep 2
|
17
|
+
result = @this_instance.create_ebs_volume({
|
18
|
+
:nickname => "ebs_test_candelete#{rand(1000)}",
|
19
|
+
:description => "created by ebs integration",
|
20
|
+
:size => "1" })
|
21
|
+
vol_aws_id = result['aws_id']
|
22
|
+
vol_aws_id.should_not == nil
|
23
|
+
@this_instance.attach_ebs_volume(:aws_id => result['aws_id'], :device => "/dev/sdp")
|
24
|
+
sleep 10
|
25
|
+
@this_instance.create_ebs_snapshot(:aws_id => vol_aws_id)
|
26
|
+
sleep 5
|
27
|
+
@this_instance.detach_ebs_volume(:device => '/dev/sdp')
|
28
|
+
sleep 10
|
29
|
+
@this_instance.delete_ebs_volume(:aws_id => vol_aws_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
=begin
|
35
|
+
#ROUTES REFERENCE GUIDE
|
36
|
+
map.api_inst_resources 'ec2_instances', :member => { :find_latest_ebs_snapshot => :get,
|
37
|
+
:find_ebs_snapshots => :get,
|
38
|
+
:create_ebs_volume_from_snap => :post,
|
39
|
+
:create_ebs_volume => :post,
|
40
|
+
:delete_ebs_volume => :delete,
|
41
|
+
:detach_ebs_volume => :put,
|
42
|
+
:attach_ebs_volume => :put,
|
43
|
+
:cleanup_ebs_snapshots => :put,
|
44
|
+
:create_ebs_snapshot => :post,
|
45
|
+
:update_ebs_snapshot => :put,
|
46
|
+
:create_ebs_backup => :post,
|
47
|
+
:find_latest_ebs_backup => :get,
|
48
|
+
:cleanup_ebs_backups => :put,
|
49
|
+
:set_custom_lodgement => :put # should we be using :post or :put ???
|
50
|
+
}
|
51
|
+
=end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
#
|
6
|
+
# EBS regression test
|
7
|
+
#
|
8
|
+
# prerequirements: run the macro for EBS stripe deployment
|
9
|
+
# enter the deployment name below
|
10
|
+
#
|
11
|
+
|
12
|
+
opts = Trollop::options do
|
13
|
+
opt :deployment, "deployment nickname", :type => :string, :required => true
|
14
|
+
end
|
15
|
+
|
16
|
+
#ebs_deployment = Deployment.find_by_nickname_speed("Regression Test - MySQL -STRIPE").first
|
17
|
+
ebs_deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
18
|
+
|
19
|
+
# select servers by nickname!
|
20
|
+
mysql_s3 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL S3 US db1/i }
|
21
|
+
mysql_db1 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL EBS db1/i }
|
22
|
+
mysql_db2 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL EBS Stripe db1/i }
|
23
|
+
mysql_db3 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL EBS Stripe db2/i }
|
24
|
+
|
25
|
+
# we must reload, so the server can populate it's state. we took a shortcut
|
26
|
+
# by grabbing the servers from the deployment's json (the rightscale default response)
|
27
|
+
mysql_s3.reload
|
28
|
+
mysql_db1.reload
|
29
|
+
mysql_db2.reload
|
30
|
+
mysql_db3.reload
|
31
|
+
|
32
|
+
# tweak: (this is closer to an actual user story) setup mysql_db1 for regular EBS
|
33
|
+
# the rest of the deployment is normally set to text:2
|
34
|
+
# mysql_db1 is [rev 13] so it needs the old input name
|
35
|
+
|
36
|
+
#mysql_db1.set_input("OPT_EBS_STRIPE_COUNT", "ignore:$ignore")
|
37
|
+
#mysql_db1.set_input("DB_EBS_PREFIX", "text:shouldnotmatter-candelete652")
|
38
|
+
#mysql_db1.set_input("DB_LINEAGE_NAME", "text:shouldnotmatter-candelete652")
|
39
|
+
#mysql_db2.set_input("DB_LINEAGE_NAME", "text:shouldnotmatter-candelete652")
|
40
|
+
#mysql_db3.set_input("DB_LINEAGE_NAME", "text:shouldnotmatter-candelete652")
|
41
|
+
|
42
|
+
# launch all
|
43
|
+
mysql_s3.start
|
44
|
+
mysql_db1.start
|
45
|
+
mysql_db2.start
|
46
|
+
mysql_db3.start
|
47
|
+
|
48
|
+
# wait for operational
|
49
|
+
mysql_s3.wait_for_state('operational')
|
50
|
+
mysql_db1.wait_for_state('operational')
|
51
|
+
mysql_db2.wait_for_state('operational')
|
52
|
+
mysql_db3.wait_for_state('operational')
|
53
|
+
|
54
|
+
sleep 10 #make sure they are operational
|
55
|
+
|
56
|
+
# we need better api support, but for now we can get our RightScripts from info.yml on an instance (or in the current dir)
|
57
|
+
template_scripts = RightScript.from_instance_info
|
58
|
+
|
59
|
+
# scripts from EBS [rev13]
|
60
|
+
slave_init_non_ebs_rev4 = RightScript.new('href' => 'right_scripts/45320')
|
61
|
+
slave_init_non_ebs_v1_rev6 = RightScript.new('href' => 'right_scripts/41484')
|
62
|
+
restore_rev4 = RightScript.new('href' => 'right_scripts/45319')
|
63
|
+
|
64
|
+
# see how easy this is to cherry pick the scripts by name? this means no resetting of ids across different templates
|
65
|
+
restore_script = template_scripts.detect { |script| script.name =~ /restore/i }
|
66
|
+
slave_init_non_ebs = template_scripts.detect { |script| script.name =~ /DB EBS slave init from non-EBS master v1/ }
|
67
|
+
slave_init_non_stripe = template_scripts.detect { |script| script.name =~ /DB EBS stripe slave init from EBS non-stripe master/i }
|
68
|
+
promote = template_scripts.detect { |script| script.name =~ /promote/i }
|
69
|
+
slave_init = template_scripts.detect { |script| script.name == "DB EBS slave init (Stripe alpha)" }
|
70
|
+
backup = template_scripts.detect { |script| script.name =~ /DB EBS backup/i }
|
71
|
+
|
72
|
+
# breathing room is needed below *only to let the servers
|
73
|
+
# settle after fail-over operations. wait_for_completed returns
|
74
|
+
# when the right_script status is 'success' or 'fail'
|
75
|
+
|
76
|
+
status = mysql_db1.run_script(slave_init_non_ebs_v1_rev6)
|
77
|
+
status = mysql_db1.run_script(slave_init_non_ebs_rev4)
|
78
|
+
status.wait_for_completed(mysql_db1.audit_link)
|
79
|
+
sleep 220 #breathing room
|
80
|
+
|
81
|
+
status = mysql_db1.run_script(promote)
|
82
|
+
status.wait_for_completed(mysql_db1.audit_link)
|
83
|
+
sleep 220 #breathing room
|
84
|
+
|
85
|
+
status = mysql_db2.run_script(slave_init_non_stripe)
|
86
|
+
status.wait_for_completed(mysql_db2.audit_link)
|
87
|
+
sleep 220 # breathing room
|
88
|
+
|
89
|
+
status = mysql_db2.run_script(promote)
|
90
|
+
status.wait_for_completed(mysql_db2.audit_link)
|
91
|
+
sleep 220 #breathing room
|
92
|
+
|
93
|
+
status = mysql_db3.run_script(slave_init)
|
94
|
+
status.wait_for_completed(mysql_db3.audit_link)
|
95
|
+
puts "done!"
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'rightscale_api_resources')
|
5
|
+
|
6
|
+
#
|
7
|
+
# EBS regression test
|
8
|
+
#
|
9
|
+
# prerequirements: run the macro for EBS stripe deployment
|
10
|
+
# enter the deployment name below
|
11
|
+
#
|
12
|
+
|
13
|
+
opts = Trollop::options do
|
14
|
+
opt :deployment, "deployment nickname", :type => :string, :required => true
|
15
|
+
end
|
16
|
+
|
17
|
+
ebs_deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
18
|
+
# select servers by nickname!
|
19
|
+
mysql_s3 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL S3 US db1/i }
|
20
|
+
mysql_db1 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL EBS db1/i }
|
21
|
+
mysql_db2 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL EBS Stripe db1/i }
|
22
|
+
mysql_db3 = ebs_deployment.servers.detect { |s| s.nickname =~ /MySQL EBS Stripe db2/i }
|
23
|
+
|
24
|
+
# we must reload, so the server can populate it's state
|
25
|
+
mysql_s3.reload
|
26
|
+
mysql_db1.reload
|
27
|
+
mysql_db2.reload
|
28
|
+
mysql_db3.reload
|
29
|
+
|
30
|
+
# stop all
|
31
|
+
mysql_s3.stop
|
32
|
+
mysql_db1.stop
|
33
|
+
mysql_db2.stop
|
34
|
+
mysql_db3.stop
|
35
|
+
|
36
|
+
# wait for stopped
|
37
|
+
mysql_s3.wait_for_state('stopped')
|
38
|
+
mysql_db1.wait_for_state('stopped')
|
39
|
+
mysql_db2.wait_for_state('stopped')
|
40
|
+
mysql_db3.wait_for_state('stopped')
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
opts = Trollop::options do
|
8
|
+
opt :deployment, "deployment nickname", :type => :string, :required => false
|
9
|
+
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
10
|
+
opt :id, "deployment id", :type => :string, :required => false
|
11
|
+
end
|
12
|
+
|
13
|
+
# find all servers in the deployment (the fast way)
|
14
|
+
if opts[:id]
|
15
|
+
deployment = Deployment.find_by_id(opts[:id])
|
16
|
+
else
|
17
|
+
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
18
|
+
end
|
19
|
+
servers = deployment.servers_no_reload
|
20
|
+
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
21
|
+
|
22
|
+
raise "need at least 2 servers to start, only have: #{servers.size}" if servers.size < 2
|
23
|
+
|
24
|
+
# wait for servers to be ready
|
25
|
+
servers.each do |s|
|
26
|
+
s.start
|
27
|
+
while(1)
|
28
|
+
puts "waiting for dns-name for #{s.nickname}"
|
29
|
+
break if s['dns-name'] && !s['dns-name'].empty?
|
30
|
+
s.reload
|
31
|
+
sleep 2
|
32
|
+
end
|
33
|
+
puts "DNS: #{s['dns-name']}"
|
34
|
+
|
35
|
+
s.wait_for_state('operational')
|
36
|
+
end
|
37
|
+
|
38
|
+
servers[0].run_recipe("db_mysql::do_restore_and_become_master")
|
39
|
+
|
40
|
+
sleep(10)
|
41
|
+
|
42
|
+
servers[1].run_recipe("db_mysql::do_init_slave")
|
43
|
+
servers[1].run_recipe("db_mysql::do_promote_to_master")
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'trollop'
|
4
|
+
require 'rest_connection'
|
5
|
+
require 'net/ssh'
|
6
|
+
|
7
|
+
def run_recipe(recipe, host_dns, continue=false)
|
8
|
+
STDOUT.puts "sshing to #{host_dns}"
|
9
|
+
result = nil
|
10
|
+
tail_command ="tail -f -n1 /var/log/messages"
|
11
|
+
expect = /RightLink.*RS> ([completed|failed]+: < #{recipe} >)/
|
12
|
+
|
13
|
+
Net::SSH.start(host_dns, 'root', :keys => ['~/.ssh/publish-test']) do |ssh|
|
14
|
+
STDOUT.puts ssh.exec!("rs_run_recipe -n '#{recipe}'")
|
15
|
+
log_channel = ssh.open_channel do |ch|
|
16
|
+
ch.exec tail_command do |ch, success|
|
17
|
+
raise "could not execute command" unless success
|
18
|
+
# "on_data" is called when the process writes something to stdout
|
19
|
+
ch.on_data do |c, data|
|
20
|
+
STDOUT.print data
|
21
|
+
if data =~ expect
|
22
|
+
STDOUT.puts "FOUND EXPECTED DATA, closing channel"
|
23
|
+
result = $1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
# "on_extended_data" is called when the process writes something to stderr
|
27
|
+
ch.on_extended_data do |c, type, data|
|
28
|
+
STDERR.print data
|
29
|
+
end
|
30
|
+
ch.on_close do
|
31
|
+
STDOUT.puts "closed channel"
|
32
|
+
end
|
33
|
+
ch.on_process do |c|
|
34
|
+
if result
|
35
|
+
STDOUT.puts "attempting close"
|
36
|
+
ch.close
|
37
|
+
ssh.exec("killall tail")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
log_channel.wait
|
43
|
+
end
|
44
|
+
raise "FATAL: halting execution, script #{result}" if result.include?('failed') && continue == false
|
45
|
+
return result
|
46
|
+
end
|
47
|
+
|
48
|
+
def spot_check(command, host_dns, &block)
|
49
|
+
Net::SSH.start(host_dns, 'root', :keys => ['~/.ssh/publish-test']) do |ssh|
|
50
|
+
result = ssh.exec!(command)
|
51
|
+
yield result
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
opts = Trollop::options do
|
56
|
+
opt :deployment, "deployment nickname", :type => :string, :required => false
|
57
|
+
opt :id, "deployment id", :type => :string, :required => false
|
58
|
+
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
59
|
+
end
|
60
|
+
if opts[:id]
|
61
|
+
deployment = Deployment.find_by_id(opts[:id])
|
62
|
+
else
|
63
|
+
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
64
|
+
end
|
65
|
+
servers = deployment.servers_no_reload
|
66
|
+
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
67
|
+
|
68
|
+
raise "need at least 4 servers to start, only have: #{servers.size}" if servers.size < 4
|
69
|
+
# wait for servers to be ready
|
70
|
+
servers.each do |s|
|
71
|
+
while(1)
|
72
|
+
puts "waiting for dns-name for #{s.nickname}"
|
73
|
+
break if s['dns-name'] && !s['dns-name'].empty?
|
74
|
+
s.reload
|
75
|
+
sleep 2
|
76
|
+
end
|
77
|
+
puts "DNS: #{s['dns-name']}"
|
78
|
+
|
79
|
+
s.wait_for_state('operational')
|
80
|
+
end
|
81
|
+
|
82
|
+
servers.each do |s|
|
83
|
+
puts run_recipe("lb_haproxy::do_attach_request", s.dns_name)
|
84
|
+
end
|
85
|
+
sleep 20
|
86
|
+
|
87
|
+
a_frontend = servers.detect {|d| d.nickname.include?("FE")}
|
88
|
+
a_frontend.reload
|
89
|
+
raise "couldn't find a frontend with FE in the nickname!" unless a_frontend
|
90
|
+
puts a_frontend.dns_name
|
91
|
+
spot_check("cat /home/haproxy/rightscale_lb.cfg |grep server|grep -v '#'|wc -l", a_frontend.dns_name) do |result|
|
92
|
+
puts "found attached servers: #{result}"
|
93
|
+
raise "not enough servers #{result}" unless result.to_i == 4
|
94
|
+
end
|
95
|
+
|
96
|
+
servers.each do |s|
|
97
|
+
run_recipe("app_php::do_update_code", s.dns_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
servers.each do |s|
|
101
|
+
run_recipe("lb_haproxy::do_detach_request", s.dns_name)
|
102
|
+
end
|
103
|
+
sleep 20
|
104
|
+
spot_check("cat /home/haproxy/rightscale_lb.cfg |grep server|grep -v '#'|wc -l", a_frontend.dns_name) do |result|
|
105
|
+
puts "found attached servers: #{result}"
|
106
|
+
raise "should be zero servers but was #{result}" unless result.to_i == 0
|
107
|
+
end
|
108
|
+
|
109
|
+
|