Module: Heaven

Defined in:
lib/heaven.rb,
lib/heaven/version.rb

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.all_available_applicationsObject

List all available applications by name

Returns an array of applications you can ship



126
127
128
# File 'lib/heaven.rb', line 126

def self.all_available_applications
  (available_capistrano_applications | available_heroku_applications | available_constructable_applications).sort
end

.app_for(name) ⇒ Object

Find a deployable application by name

Needs to be defined in config/apps.yml



10
11
12
# File 'lib/heaven.rb', line 10

def self.app_for(name)
  Heaven::App.app_for(name)
end

.available_capistrano_applicationsObject

List the available receipts

Returns an array of available rackspace application names



105
106
107
# File 'lib/heaven.rb', line 105

def self.available_capistrano_applications
  Heaven::Targets::Capistrano.available_applications
end

.available_constructable_applicationsObject

List the available constructable speakeasy applications

Returns an array of available constructable speakeasy application names



119
120
121
# File 'lib/heaven.rb', line 119

def self.available_constructable_applications
  Heaven::Targets::Speakeasy.all.map { |app| app.name.downcase }
end

.available_heroku_applicationsObject

List the available heroku applications

Returns an array of available heroku application names



112
113
114
# File 'lib/heaven.rb', line 112

def self.available_heroku_applications
  Heaven::Targets::Heroku.deployments.map { |app| app.name }
end

.baseObject

The installed gems base directory

We reference files inside of the gem after installation. This gives you easy access to files in local development and when installed via rubygems



38
39
40
# File 'lib/heaven.rb', line 38

def self.base
  File.expand_path("../", __FILE__)
end

.current_shaObject

The current sha1 that the code is running under

Returns the short sha for the running process



23
24
25
# File 'lib/heaven.rb', line 23

def self.current_sha
  @current_sha ||= `cd #{root} && git rev-parse HEAD`[0..7]
end

.deploy_userObject

The user on the remote system that capistrano commands are issued as

If you’re not running inside the VPN, your user probably isn’t git

Returns the UNIX username of the deploy user on the remote system



47
48
49
# File 'lib/heaven.rb', line 47

def self.deploy_user
  @deploy_user ||= 'git'
end

.deploy_user=(username) ⇒ Object

Set the deploy user capistrano commands are invoked as

If you’re not running inside the VPN, your user probably isn’t git. Use this method to set the user.

Returns the UNIX username of the deploy user on the remote system



57
58
59
# File 'lib/heaven.rb', line 57

def self.deploy_user=(username)
  @deploy_user = username
end

.domain_suffix(environment) ⇒ Object

Domain suffix based on environment



145
146
147
148
149
150
151
152
# File 'lib/heaven.rb', line 145

def self.domain_suffix(environment)
  case environment
  when "production","lab"
    ".rs.github.com"
  else
    ".stg.github.com"
  end
end

.expand_hosts(prefixes, environment) ⇒ Object

Expand requested hosts to wildcard match for convenience

For subset deployments you can specify the hosts you want as comma delimited matches

“fe”

> [“fe1.rs.github.com”, “fe2.rs.github.com”, “fe3.rs.github.com”,

"fe4.rs.github.com", "fe5.rs.github.com", "fe6.rs.github.com", "fe7.rs.github.com"]
“fe1”,“fe2”

> [“fe1.rs.github.com”, “fe2.rs.github.com”]

“fs”

> [“fs1a.rs.github.com”, “fs1b.rs.github.com”, “fs2a.rs.github.com”, “fs2b.rs.github.com”, … ]

“fe1”,“fs2”

> [“fe1.rs.github.com”, “fs2a.rs.github.com”, “fs2b.rs.github.com”]



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/heaven.rb', line 242

def self.expand_hosts(prefixes, environment)
  suffix = domain_suffix(environment)
  prefixes.map do |host_prefix|
    case host_prefix
    when /fe$/
      hosts_for_fes(environment)
    when /fs$/
      hosts_for_fses(environment)
    when /worker$/
      hosts_for_workers(environment)
    when /fs\d+$/
      "#{host_prefix}a#{suffix},#{host_prefix}b#{suffix}"
    when /staff$/
      "#{host_prefix}1#{suffix}"
    when /\.aws\.github\.net$/
      host_prefix
    else
      "#{host_prefix}#{suffix}"
    end
  end.join(",")
end

.file_servers(environment) ⇒ Object

Get all file servers in the given environment

Returns an array of full domain names for all file servers



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/heaven.rb', line 166

def self.file_servers(environment)
  if environment == 'machine-room'
    return [
      'github-fs102a-cp1-prd.iad.github.net',
      'github-fs102b-cp1-prd.iad.github.net'
    ]
  end
  hosts  = [ ]
  suffix = domain_suffix(environment)
  1.upto(host_info[environment]["fs"]) do |i|
    hosts << "fs#{i}a#{suffix}"
    hosts << "fs#{i}b#{suffix}"
  end
  filter_hosts(hosts)
end

.filter_hosts(hosts) ⇒ Object

Given a list of hosts, exclude the current offline hosts

Returns a filtered list of full hostnames to deploy to



157
158
159
160
161
# File 'lib/heaven.rb', line 157

def self.filter_hosts(hosts)
  hosts.map do |host|
    offline_hosts.include?(host) ? nil : host
  end.compact
end

.frontends(environment) ⇒ Object

Get all frontends in the given environment

Returns an array of full domain names for all frontends



185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/heaven.rb', line 185

def self.frontends(environment)
  return ['github-staff2-pe1-prd.aws.github.net'] if environment == 'garage'
  return ['github-staff3-pe1-prd.aws.github.net'] if environment == 'spider-skull-island'
  return ['github-staff4-cp1-prd.iad.github.net'] if environment == 'machine-room'

  hosts  = [ ]
  prefix = environment == 'lab' ? 'staff' : 'fe'
  suffix = domain_suffix(environment)
  1.upto(host_info[environment]["fe"]) do |i|
    hosts << "#{prefix}#{i}#{suffix}"
  end
  filter_hosts(hosts)
end

.host_infoObject

The number of fe and fs machines we have for an environment

fe3.stg.github.com is available but excluded because its rebuild so often

A Hash based on environment keys that keeps count



66
67
68
69
70
71
72
73
74
75
# File 'lib/heaven.rb', line 66

def self.host_info
  @host_info ||= {
    'staging'              => { 'fe' => 2,  'fs' => 1,  'worker' => 0 },
    'production'           => { 'fe' => 19, 'fs' => 37, 'worker' => 6 },
    'lab'                  => { 'fe' => 1,  'fs' => 0,  'worker' => 0 },
    'garage'               => { 'fe' => 1,  'fs' => 0,  'worker' => 0 },
    'spider-skull-island'  => { 'fe' => 1,  'fs' => 0,  'worker' => 0 },
    'machine-room'         => { 'fe' => 1,  'fs' => 1,  'worker' => 0 },
  }
end

.hosts_for_fes(environment) ⇒ Object

Get all frontends in the given environment

Returns a comma delimited string of of the full hostnames for all frontends



215
216
217
# File 'lib/heaven.rb', line 215

def self.hosts_for_fes(environment)
  frontends(environment).join(",")
end

.hosts_for_fses(environment) ⇒ Object

Get all file servers in the given environment

Returns a comma delimited string of of the full hostnames for all frontends



222
223
224
# File 'lib/heaven.rb', line 222

def self.hosts_for_fses(environment)
  file_servers(environment).join(",")
end

.hosts_for_workers(environment) ⇒ Object

Get all worker servers in the given environment

Returns a comma delimited string of of the full hostnames for all frontends



229
230
231
# File 'lib/heaven.rb', line 229

def self.hosts_for_workers(environment)
  workers(environment).join(",")
end

.loggerObject

Logger for sending output to syslog easily



16
17
18
# File 'lib/heaven.rb', line 16

def self.logger
  @logger ||= Syslog.open("heaven")
end

.offline_hostsObject

List of full hostnames that are offline for now

Can be comma delimited for more than one host Only useful for fileserver and frontends

Returns an array of full hostnames



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/heaven.rb', line 83

def self.offline_hosts
  @offline_hosts ||= %w(fe5.rs.github.com
                        fe6.rs.github.com
                        fe7.rs.github.com
                        fe8.rs.github.com
                        fe9.rs.github.com
                        fe10.rs.github.com
                        fe11.rs.github.com
                        fe12.rs.github.com
                        fe14.rs.github.com
                        fe15.rs.github.com
                        db2a.rs.github.com
                        fe1.stg.github.com
                        fs1a.rs.github.com
                        fs1b.rs.github.com
                        fs24a.rs.github.com
                        fs24b.rs.github.com)
end

Print the apps that you can deploy

Defaults to stdout

Returns nil



135
136
137
138
139
140
141
142
# File 'lib/heaven.rb', line 135

def self.print_available_applications(out = $stdout)
  out.puts "Available Applications:"
  out.puts "-" * 23
  Heaven.all_available_applications.each do |app|
    out.printf "%023s\n", app
  end
  out.puts
end

.rootObject

The root of the heaven project directory

Returns the absolute path to the heaven project on disk



30
31
32
# File 'lib/heaven.rb', line 30

def self.root
  @root ||= File.expand_path(File.join(File.dirname(__FILE__), ".."))
end

.workers(environment) ⇒ Object

Get all workers in the given environment

Returns an array of full domain names for all frontends



202
203
204
205
206
207
208
209
210
# File 'lib/heaven.rb', line 202

def self.workers(environment)
  hosts  = [ ]
  suffix = domain_suffix(environment)
  1.upto(host_info[environment]["worker"]) do |i|
    hosts << "worker#{i}#{suffix}"
  end
  hosts << "github-worker7-cp1-prd.iad.github.net" if environment == "production"
  filter_hosts(hosts)
end