This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
ci.rake
199 lines (165 loc) · 7.19 KB
/
ci.rake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
namespace :ci do
desc "Spin up CI server on amazon"
task :server_start do
require 'fog'
require 'yaml'
require 'socket'
aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
aws_conf = YAML.load_file(aws_conf_location)
aws_credentials = aws_conf['credentials']
ec2_server_access = aws_conf['ec2_server_access']
server_config = aws_conf['server']
security_group_name = server_config['security_group']
aws_connection = Fog::Compute.new(
:provider => aws_credentials['provider'],
:aws_access_key_id => aws_credentials['aws_access_key_id'],
:aws_secret_access_key => aws_credentials['aws_secret_access_key']
)
security_group = aws_connection.security_groups.get(security_group_name)
if security_group.nil?
puts "Could not find security group named '#{security_group_name}'. Creating..."
security_group = aws_connection.security_groups.new(:name => security_group_name, :description => 'ci servers group auto-created by lobot')
security_group.save
security_group.reload
p security_group
end
PORTS_TO_OPEN = [22, 443, 80]
PORTS_TO_OPEN.each do |port|
is_in_security_group = !!security_group.ip_permissions.detect{|group| (group['fromPort']..group['toPort']).include?(port) && group['ipRanges'].detect{|range| range["cidrIp"]== "0.0.0.0/0" } }
unless is_in_security_group
puts "Allowing port #{port} into '#{security_group_name}' security group"
security_group.authorize_port_range(port..port)
end
end
ec2_key_pair_name = ec2_server_access['key_pair_name'] || "ci"
public_key_local_path = "#{ec2_server_access['id_rsa_path']}.pub"
current_key_pair = aws_connection.key_pairs.get(ec2_key_pair_name)
if current_key_pair
puts "Using existing '#{ec2_key_pair_name}' keypair"
else
puts "Creating '#{ec2_key_pair_name}' keypair, uploading #{public_key_local_path} to aws"
aws_connection.key_pairs.new(
:name => ec2_key_pair_name,
:public_key => File.read(File.expand_path("#{public_key_local_path}"))
).save
end
number_of_servers = aws_connection.servers.select{ |server| server.state == 'running' }.length
puts "you have #{number_of_servers} server(s) already running in this account" if number_of_servers > 0
puts "Launching server... (this costs money until you stop it)"
server = aws_connection.servers.create(
:image_id => 'ami-e358958a',
:flavor_id => server_config['flavor_id'] || 'm1.large',
:key_name => ec2_key_pair_name,
:groups => [security_group_name]
)
unless aws_conf['server']['elastic_ip'] =~ /\d.\.\d.\.\d.\.\d./
elastic_ip = aws_connection.addresses.create
aws_conf['server']['elastic_ip'] = elastic_ip.public_ip
puts "Allocated elastic IP address #{aws_conf['server']['elastic_ip']}"
end
server.wait_for { ready? }
aws_connection.associate_address(server.id, aws_conf['server']['elastic_ip'])
socket = false
Timeout::timeout(120) do
p "Server booted, waiting for SSH."
until socket
begin
socket = TCPSocket.open(aws_conf['server']['elastic_ip'], 22)
rescue Errno::ECONNREFUSED
STDOUT << "."
STDOUT.flush
sleep 1
end
end
end
p server
puts "Server is ready"
p "Writing server instance_id(#{server.id}) and elastic IP(#{aws_conf['server']['elastic_ip']}) to ci.yml"
aws_conf["server"].merge!("instance_id" => server.id)
f = File.open(aws_conf_location, "w")
f.write(aws_conf.to_yaml)
f.close
end
desc "stop(suspend) the CI Server"
task :stop do
require 'fog'
require 'yaml'
require 'socket'
aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
aws_conf = YAML.load_file(aws_conf_location)
aws_credentials = aws_conf['credentials']
server_config = aws_conf['server']
aws_connection = Fog::Compute.new(
:provider => aws_credentials['provider'],
:aws_access_key_id => aws_credentials['aws_access_key_id'],
:aws_secret_access_key => aws_credentials['aws_secret_access_key']
)
aws_connection.servers.new(:id => server_config['instance_id']).stop
end
desc "start(resume) the CI Server"
task :start do
require 'fog'
require 'yaml'
require 'socket'
aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
aws_conf = YAML.load_file(aws_conf_location)
aws_credentials = aws_conf['credentials']
server_config = aws_conf['server']
aws_connection = Fog::Compute.new(
:provider => aws_credentials['provider'],
:aws_access_key_id => aws_credentials['aws_access_key_id'],
:aws_secret_access_key => aws_credentials['aws_secret_access_key']
)
server = aws_connection.servers.new(:id => server_config['instance_id'])
server.start
server.wait_for { ready? }
aws_connection.associate_address(server_config['instance_id'], server_config['elastic_ip']) if server_config['elastic_ip']
end
desc "open the CI interface in a browser"
task :open do
aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
aws_conf = YAML.load_file(aws_conf_location)
server_config = aws_conf['server']
exec "open http://#{server_config['elastic_ip']}"
end
desc "ssh to CI"
task :ssh do
aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
aws_conf = YAML.load_file(aws_conf_location)
server_config = aws_conf['server']
exec "ssh -i #{aws_conf['ec2_server_access']['id_rsa_path']} #{aws_conf['app_user']}@#{server_config['elastic_ip']}"
end
desc "Get build status"
task :status do
require 'nokogiri'
aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
ci_conf = YAML.load_file(aws_conf_location)
jenkins_rss_feed = `curl -s --user #{ci_conf['basic_auth'][0]['username']}:#{ci_conf['basic_auth'][0]['password']} --anyauth http://#{ci_conf['server']['elastic_ip']}/rssAll`
latest_build = Nokogiri::XML.parse(jenkins_rss_feed.downcase).css('feed entry:first').first
status = !!(latest_build.css("title").first.content =~ /success|stable|back to normal/)
if status
p "Great Success"
else
p "Someone needs to fix the build"
end
status ? exit(0) : exit(1)
end
desc "Print cimonitor and ccmenu setup information"
task :info do
ci_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
ci_conf = YAML.load_file(ci_conf_location)
puts "CI Monitor Config:"
puts "\tURL:\t\thttp://#{ci_conf['server']['elastic_ip']}/job/#{ci_conf['app_name']}/rssAll"
puts "\tProject Type:\tHudson/Jenkins"
puts "\tFeed Username:\t#{ci_conf['basic_auth'][0]['username']}"
puts "\tFeed Password:\t#{ci_conf['basic_auth'][0]['password']}"
puts "\t-- Lobot Setup --"
puts "\tEC2 Instance ID:\t#{ci_conf['server']['instance_id']}"
puts "\tEC2 Elastic IP Address:\t#{ci_conf['server']['elastic_ip']}"
puts "\tEC2 Access Key ID:\t#{ci_conf['credentials']['aws_access_key_id']}"
puts "\tEC2 Secret Access Key :\t#{ci_conf['credentials']['aws_secret_access_key']}"
puts ""
puts "CC Menu Config:"
puts "\tURL:\thttp://#{ci_conf['basic_auth'][0]['username']}:#{ci_conf['basic_auth'][0]['password']}@#{ci_conf['server']['elastic_ip']}/cc.xml"
end
end