meroku 0.0.0 → 0.1.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/meroku +5 -0
- data/lib/meroku/app/collaborator.rb +18 -0
- data/lib/meroku/app.rb +12 -0
- data/lib/meroku/application_record.rb +8 -0
- data/lib/meroku/apps_controller.rb +112 -0
- data/lib/meroku/cli/certs.rb +30 -0
- data/lib/meroku/cli/certs.rb~ +14 -0
- data/lib/meroku/cli/cli.rb +97 -0
- data/lib/meroku/cli/config.rb +111 -0
- data/lib/meroku/cli/domains.rb +69 -0
- data/lib/meroku/cli/keys.rb +38 -0
- data/lib/meroku/cli/remote.rb +13 -0
- data/lib/meroku/cli/remote.rb~ +12 -0
- data/lib/meroku/cli/server.rb +159 -0
- data/lib/meroku/cli/server.rb~ +4 -0
- data/lib/meroku/cli.rb +8 -0
- data/lib/meroku/config.rb +6 -0
- data/lib/meroku/configs_controller.rb +62 -0
- data/lib/meroku/core_ext.rb +30 -0
- data/lib/meroku/domain.rb +6 -0
- data/lib/meroku/domains_controller.rb +83 -0
- data/lib/meroku/error.rb +6 -0
- data/lib/meroku/key.rb +11 -0
- data/lib/meroku/keys_controller.rb +82 -0
- data/lib/meroku/sanitychecks.rb +19 -0
- data/lib/meroku/user.rb +23 -0
- data/lib/meroku/util.rb +416 -0
- data/lib/meroku/version.rb +3 -0
- data/lib/meroku.rb +20 -4
- metadata +170 -46
data/lib/meroku/util.rb
ADDED
@@ -0,0 +1,416 @@
|
|
1
|
+
module Meroku
|
2
|
+
|
3
|
+
# Methods that doesn't have a proper namespace yet
|
4
|
+
module Util
|
5
|
+
|
6
|
+
require 'open3'
|
7
|
+
class Subprocess
|
8
|
+
def initialize(cmd, &block)
|
9
|
+
# see: http://stackoverflow.com/a/1162850/83386
|
10
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
|
11
|
+
stdin.close
|
12
|
+
# read each stream from a new thread
|
13
|
+
{ :out => stdout, :err => stderr }.each do |key, stream|
|
14
|
+
Thread.new do
|
15
|
+
until (line = stream.gets).nil? do
|
16
|
+
# yield the block depending on the stream
|
17
|
+
if key == :out
|
18
|
+
yield line, nil, thread if block_given?
|
19
|
+
else
|
20
|
+
yield nil, line, thread if block_given?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
thread.join # don't exit until the external process is done
|
27
|
+
raise "ErrorDuringPopen3" if thread.value != 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def additional_env_vars(app_name, dbtype)
|
33
|
+
require 'rest-client'
|
34
|
+
resp = RestClient.post 'https://www.meroku.com/meroku/apps/0/additional_env_vars.json', { :"dbtype" => dbtype, authentication: { app_name: app_name, token: cli_token} }
|
35
|
+
JSON.parse(resp)["data"]
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_authorized_keys_file
|
39
|
+
`sudo -i -u u#{self.user_id} sh -c "echo '#{self.key}' | tee /home/u#{self.user_id}/.ssh/authorized_keys"`
|
40
|
+
end
|
41
|
+
|
42
|
+
def setup_repo
|
43
|
+
app = Meroku::App.find(self.app_id)
|
44
|
+
user = Meroku::User.find(self.user_id)
|
45
|
+
`sudo -i -u u#{user.id} sh -c "mkdir ~/#{app.name}.git"`
|
46
|
+
`sudo -i -u u#{user.id} sh -c "cd ~/#{app.name}.git && git init --bare"`
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def self.add_unix_users
|
51
|
+
puts "DB8 #{Meroku::User.all.size} users to add..."
|
52
|
+
Meroku::User.all.each do |user|
|
53
|
+
puts "DB8 Adding #{user.id} #{user.email}"
|
54
|
+
`sudo adduser --disabled-password --gecos "" u#{user.id}`
|
55
|
+
`sudo usermod -aG meroku u#{user.id}`
|
56
|
+
#`sudo -i -u u#{user.id} sh -c "mkdir ~/.ssh/"`
|
57
|
+
#`sudo -i -u u#{user.id} sh -c "touch ~/.ssh/authorized_keys"`
|
58
|
+
#a = IO.write("/tmp/tmp.txt",user.encrypted_password)
|
59
|
+
#`sudo -i -u u#{user.id} sh -c "cp /tmp/tmp.txt /home/u1/.encrypted_password"`
|
60
|
+
#`sudo -i -u u#{user.id} sh -c "cp /tmp/tmp.txt /home/u1/.encrypted_password 2>&1"`
|
61
|
+
`sudo -i -u u#{user.id} sh -c "git config --global core.hooksPath /opt/githooks"`
|
62
|
+
|
63
|
+
#user.keys.each do |key|
|
64
|
+
# puts "DB8 Adding key #{key.id} #{key.key[0..9]} ..."
|
65
|
+
# `sudo -i -u u#{user.id} sh -c "echo '#{key.key}' | tee /home/u#{user.id}/.ssh/authorized_keys"`
|
66
|
+
#end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# this is a callback called from the User model
|
72
|
+
def add_unix_user
|
73
|
+
`sudo adduser --disabled-password --gecos "" u#{self.id}`
|
74
|
+
`sudo usermod -aG meroku u#{self.id}`
|
75
|
+
`sudo -i -u u#{self.id} sh -c "mkdir ~/.ssh/"`
|
76
|
+
`sudo -i -u u#{self.id} sh -c "touch ~/.ssh/authorized_keys"`
|
77
|
+
Rails.logger.debug "DB8 A"
|
78
|
+
a = IO.write("/tmp/tmp.txt",self.encrypted_password)
|
79
|
+
Rails.logger.debug a
|
80
|
+
Rails.logger.debug `sudo -i -u u#{self.id} sh -c "cp /tmp/tmp.txt /home/u1/.encrypted_password"`
|
81
|
+
Rails.logger.debug `sudo -i -u u#{self.id} sh -c "cp /tmp/tmp.txt /home/u1/.encrypted_password 2>&1"`
|
82
|
+
Rails.logger.debug "DB8 A end"
|
83
|
+
`sudo -i -u u#{self.id} sh -c "git config --global core.hooksPath /opt/githooks"`
|
84
|
+
end
|
85
|
+
|
86
|
+
# this is a callback called from the Meroku::Collaborator model
|
87
|
+
def add_mysql_user
|
88
|
+
user = Meroku::User.find(self.user_id)
|
89
|
+
`sudo mysql -pbitnami -e 'FLUSH PRIVILEGES; set password for "u#{self.user_id}"@"localhost" = PASSWORD("#{user.database_password}"); FLUSH PRIVILEGES;'`
|
90
|
+
Rails.logger.debug "DB8 add_mysql_user db password for user id #{user.id} set to #{user.database_password}"
|
91
|
+
end
|
92
|
+
|
93
|
+
# self is a Meroku::Collaborator
|
94
|
+
def add_mysql_grants
|
95
|
+
app = Meroku::App.find(self.app_id)
|
96
|
+
`sudo mysql -pbitnami -e 'FLUSH PRIVILEGES; GRANT ALL PRIVILEGES ON #{app.name}.* TO "u#{self.user_id}"@"localhost"; FLUSH PRIVILEGES;'`
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_empty_pg_db
|
100
|
+
app = Meroku::App.find(self.app_id)
|
101
|
+
`PGPASSWORD=bitnami psql -U postgres -c "CREATE DATABASE #{app.name};"`
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_pg_user
|
105
|
+
user = Meroku::User.find(self.user_id)
|
106
|
+
`PGPASSWORD=bitnami psql -U postgres -c "CREATE USER u#{self.user_id} WITH PASSWORD '#{user.database_password}';"`
|
107
|
+
end
|
108
|
+
|
109
|
+
def add_pg_grants
|
110
|
+
app = Meroku::App.find(self.app_id)
|
111
|
+
`PGPASSWORD=bitnami psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE #{app.name} TO u#{self.user_id};"`
|
112
|
+
end
|
113
|
+
|
114
|
+
# self is a Meroku::Collaborator
|
115
|
+
def create_empty_mysql_db
|
116
|
+
app = Meroku::App.find(self.app_id)
|
117
|
+
`sudo mysql -pbitnami -e 'CREATE DATABASE #{app.name}'`
|
118
|
+
end
|
119
|
+
|
120
|
+
# self refers to a Meroku::User
|
121
|
+
def install_rvm_for_user
|
122
|
+
`sudo -i -u u#{self.id} /bin/bash -c 'curl -sSL https://get.rvm.io | bash'`
|
123
|
+
end
|
124
|
+
|
125
|
+
def public_key_exists?
|
126
|
+
File.exist?(Dir.home + "/.ssh/id_rsa.pub")
|
127
|
+
end
|
128
|
+
|
129
|
+
def valid_json?(json)
|
130
|
+
JSON.parse(json)
|
131
|
+
return true
|
132
|
+
rescue JSON::ParserError => e
|
133
|
+
return false
|
134
|
+
end
|
135
|
+
|
136
|
+
def cli_logged_in?
|
137
|
+
if File.exist?("/tmp/meroku.token")
|
138
|
+
return true
|
139
|
+
else
|
140
|
+
puts "Not logged in"
|
141
|
+
return false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def cli_token
|
146
|
+
`cat /tmp/meroku.token`.chomp
|
147
|
+
end
|
148
|
+
|
149
|
+
def cli_user_id
|
150
|
+
user_id = `cat /tmp/meroku.id`
|
151
|
+
end
|
152
|
+
|
153
|
+
def app_name
|
154
|
+
git_remote = `git remote get-url meroku`.chomp
|
155
|
+
git_remote =~ /\@www.meroku.com\:(.*?).git\Z/
|
156
|
+
$1
|
157
|
+
end
|
158
|
+
|
159
|
+
def ssh(ip, command)
|
160
|
+
puts `ssh -tt -o "StrictHostKeyChecking=no" -i ~/crypto/meroku/meroku.id_rsa bitnami@#{ip} '#{command}'`
|
161
|
+
end
|
162
|
+
|
163
|
+
def ssh2(ip, command)
|
164
|
+
print "+ #{command} "
|
165
|
+
Meroku::Util::Subprocess.new "ssh -tt -o StrictHostKeyChecking=no -i ~/crypto/meroku/meroku.id_rsa bitnami@#{ip} '#{command}'" do |stdout, stderr, thread|
|
166
|
+
print "."
|
167
|
+
end
|
168
|
+
print "\n"
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
def ssh3(ip, command)
|
173
|
+
puts "+ #{command} "
|
174
|
+
Meroku::Util::Subprocess.new "ssh -tt -o StrictHostKeyChecking=no -i ~/crypto/meroku/meroku.id_rsa bitnami@#{ip} '#{command}'" do |stdout, stderr, thread|
|
175
|
+
print stdout
|
176
|
+
print stderr
|
177
|
+
end
|
178
|
+
print "\n"
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
def ec2_client
|
183
|
+
@ec2_client ||= Aws::EC2::Client.new(
|
184
|
+
region: 'us-east-1',
|
185
|
+
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
|
186
|
+
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
def server_being_built
|
191
|
+
ec2_get_ip_by_instance_id(unused_servers.first)
|
192
|
+
end
|
193
|
+
|
194
|
+
def ec2_get_ip_by_instance_id(instance_id)
|
195
|
+
ec2_client.describe_instances(
|
196
|
+
filters:
|
197
|
+
[
|
198
|
+
{ name: "instance-id", values: [ instance_id ] }
|
199
|
+
]
|
200
|
+
).reservations.first.instances.first.public_ip_address
|
201
|
+
end
|
202
|
+
|
203
|
+
def meroku_servers
|
204
|
+
ec2_client.describe_instances(
|
205
|
+
filters:
|
206
|
+
[
|
207
|
+
{ name: "tag:Name", values: ['meroku'] },
|
208
|
+
{ name: "instance-state-name", values: ['pending', 'running'] }
|
209
|
+
]
|
210
|
+
).reservations
|
211
|
+
.map{ |a| a.instances }
|
212
|
+
.map{ |b|
|
213
|
+
b.map { |c| c.instance_id }
|
214
|
+
}
|
215
|
+
.flatten
|
216
|
+
end
|
217
|
+
|
218
|
+
# Returns the production servers instance id
|
219
|
+
def production_servers
|
220
|
+
ec2_client.describe_instances(
|
221
|
+
filters:
|
222
|
+
[
|
223
|
+
{ name: "ip-address", values: [ Meroku::PRODUCTION_IP ] },
|
224
|
+
{ name: "tag:Name", values: ['meroku'] },
|
225
|
+
{ name: "instance-state-name", values: ['pending', 'running'] }
|
226
|
+
]
|
227
|
+
).map { |x| x.reservations }.flatten.map { |x| x.instances }.flatten.map { |x| x.instance_id }
|
228
|
+
rescue
|
229
|
+
[]
|
230
|
+
end
|
231
|
+
|
232
|
+
def unused_servers
|
233
|
+
meroku_servers - production_servers
|
234
|
+
end
|
235
|
+
|
236
|
+
def terminate_unused_servers
|
237
|
+
unused_servers.each do |server|
|
238
|
+
puts "Terminating #{server}"
|
239
|
+
ec2_client.terminate_instances({ instance_ids: [ server ] })
|
240
|
+
sleep 1
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def ec2_start_instance
|
245
|
+
resp = ec2_client.run_instances(
|
246
|
+
{
|
247
|
+
:image_id => 'ami-52a5dd44', #bitnami 2.4.1
|
248
|
+
:min_count => 1,
|
249
|
+
:max_count => 1,
|
250
|
+
:instance_type => "t2.small",
|
251
|
+
:key_name => "meroku.id_rsa"
|
252
|
+
}
|
253
|
+
)
|
254
|
+
resp[:instances][0][:instance_id]
|
255
|
+
end
|
256
|
+
|
257
|
+
def ec2_tag_instance(instance_id)
|
258
|
+
retries ||= 0
|
259
|
+
puts "create_tags try ##{ retries }"
|
260
|
+
ec2_client.create_tags( resources: [ instance_id ], tags: [ { key: 'Name', value: "meroku"}])
|
261
|
+
rescue
|
262
|
+
sleep 1
|
263
|
+
retry if (retries += 1) < 3
|
264
|
+
end
|
265
|
+
|
266
|
+
def ec2_await_boot(instance_id)
|
267
|
+
wait_timeout = 60
|
268
|
+
ec2_client.wait_until(:instance_running, instance_ids:[ instance_id ]) do |w|
|
269
|
+
w.max_attempts = 10
|
270
|
+
w.interval = wait_timeout/10
|
271
|
+
w.before_attempt do |n|
|
272
|
+
print "#{n}/10 "
|
273
|
+
end
|
274
|
+
end
|
275
|
+
public_ip_address = ec2_client.describe_instances(instance_ids: [instance_id])[0][0].instances[0].public_ip_address
|
276
|
+
puts public_ip_address
|
277
|
+
wait_time=40
|
278
|
+
10.times do |i|
|
279
|
+
port_is_open = Socket.tcp(public_ip_address, 22, connect_timeout: 6) { true } rescue false
|
280
|
+
print "#{i}/10 "
|
281
|
+
break if port_is_open
|
282
|
+
sleep 8
|
283
|
+
end
|
284
|
+
print "\n"
|
285
|
+
puts `ssh -o "StrictHostKeyChecking=no" -i ~/crypto/meroku/meroku.id_rsa ubuntu@#{public_ip_address} uptime 2>/dev/null`
|
286
|
+
end
|
287
|
+
|
288
|
+
def self.shell_exec(command)
|
289
|
+
require 'open3'
|
290
|
+
Open3.popen2e(command) do |stdin, stdout_err, wait_thr|
|
291
|
+
while line = stdout_err.gets
|
292
|
+
IO.write("/home/bitnami/meroku/rails_app/log/nginx_rebuild.log", line, mode: 'a')
|
293
|
+
end
|
294
|
+
exit_status = wait_thr.value
|
295
|
+
unless exit_status.success?
|
296
|
+
raise "FAILED !!!"
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def self.nginx_rebuild
|
302
|
+
IO.write("/home/bitnami/meroku/rails_app/log/nginx_rebuild.log", "ngin_rebuild() started\n")
|
303
|
+
command = <<-'HEREDOC'
|
304
|
+
set -ex;
|
305
|
+
sudo rm -vf /opt/bitnami/nginx/conf/vhosts/*;
|
306
|
+
sudo rm -vf /opt/bitnami/nginx/keys/clients/*;
|
307
|
+
HEREDOC
|
308
|
+
shell_exec(command)
|
309
|
+
IO.write("/tmp/www.conf", generate_nginx_config("www.meroku.com", "3000", nil) )
|
310
|
+
IO.write("/tmp/_.conf",nginx_fallback_vhost)
|
311
|
+
|
312
|
+
command = <<-'HEREDOC'
|
313
|
+
set -ex;
|
314
|
+
sudo mv -v /tmp/www.conf /opt/bitnami/nginx/conf/vhosts/;
|
315
|
+
sudo mv -v /tmp/_.conf /opt/bitnami/nginx/conf/vhosts/;
|
316
|
+
HEREDOC
|
317
|
+
shell_exec(command)
|
318
|
+
|
319
|
+
Meroku::App.all.each do |app|
|
320
|
+
port = (3000 + app.id).to_s
|
321
|
+
domains = "#{app.name}.meroku.com"
|
322
|
+
domains = "#{app.name}.meroku.com"
|
323
|
+
domains += " #{app.domains.pluck(:domain).join(" ")}" if app.domains.size > 0
|
324
|
+
cert = nil
|
325
|
+
cert = app.name if app.server_crt
|
326
|
+
IO.write("/tmp/#{app.name}.conf", generate_nginx_config(domains, port, cert) )
|
327
|
+
shell_exec("sudo mv -v /tmp/#{app.name}.conf /opt/bitnami/nginx/conf/vhosts/")
|
328
|
+
if app.server_crt
|
329
|
+
IO.write("/tmp/#{app.name}.crt", app.server_crt )
|
330
|
+
IO.write("/tmp/#{app.name}.key", app.server_key )
|
331
|
+
shell_exec "set -ex; sudo mv -v /tmp/#{app.name}.crt /opt/bitnami/nginx/keys/cli\
|
332
|
+
ents/"
|
333
|
+
shell_exec "set -ex; sudo mv -v /tmp/#{app.name}.key /opt/bitnami/nginx/keys/cli\
|
334
|
+
ents/"
|
335
|
+
end
|
336
|
+
end
|
337
|
+
command = <<-'HEREDOC'
|
338
|
+
set -ex;
|
339
|
+
sudo /opt/bitnami/nginx/sbin/nginx -s reload;
|
340
|
+
ls -la /opt/bitnami/nginx/conf/vhosts/;
|
341
|
+
HEREDOC
|
342
|
+
shell_exec(command)
|
343
|
+
IO.write("/home/bitnami/meroku/rails_app/log/nginx_rebuild.log", "ngin_rebuild() ended\n", mode: 'a')
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
def self.generate_nginx_config(domains, port, cert)
|
348
|
+
if cert
|
349
|
+
server_crt = "/opt/bitnami/nginx/keys/clients/#{cert}.crt"
|
350
|
+
server_key = "/opt/bitnami/nginx/keys/clients/#{cert}.key"
|
351
|
+
else
|
352
|
+
server_crt = "/opt/bitnami/nginx/keys/meroku_site_fullchain.pem"
|
353
|
+
server_key = "/opt/bitnami/nginx/keys/meroku_site_privkey.pem"
|
354
|
+
end
|
355
|
+
|
356
|
+
template = nginx_template
|
357
|
+
template.gsub!('REPLACEMEDOMAINS', domains)
|
358
|
+
template.gsub!('REPLACEMEPORT', port)
|
359
|
+
template.gsub!('REPLACEMESERVERCERT', server_crt)
|
360
|
+
template.gsub!('REPLACEMESERVERKEY', server_key)
|
361
|
+
template
|
362
|
+
end
|
363
|
+
|
364
|
+
def self.nginx_template
|
365
|
+
<<-'HEREDOC'
|
366
|
+
server {
|
367
|
+
listen 80;
|
368
|
+
server_name REPLACEMEDOMAINS;
|
369
|
+
listen 443 ssl;
|
370
|
+
ssl_certificate REPLACEMESERVERCERT;
|
371
|
+
ssl_certificate_key REPLACEMESERVERKEY;
|
372
|
+
|
373
|
+
root /home/u1/onebody/public;
|
374
|
+
|
375
|
+
location ~ ^/assets/ {
|
376
|
+
expires 1y;
|
377
|
+
add_header Cache-Control public;
|
378
|
+
|
379
|
+
add_header ETag "";
|
380
|
+
break;
|
381
|
+
}
|
382
|
+
|
383
|
+
ssl_session_timeout 5m;
|
384
|
+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
385
|
+
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
|
386
|
+
ssl_prefer_server_ciphers on;
|
387
|
+
|
388
|
+
location / {
|
389
|
+
proxy_pass http://127.0.0.1:REPLACEMEPORT;
|
390
|
+
# got from https://github.com/mperham/sidekiq/issues/2560
|
391
|
+
proxy_set_header Host $http_host;
|
392
|
+
proxy_set_header X-Real-IP $proxy_protocol_addr;
|
393
|
+
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
|
394
|
+
proxy_set_header X-Forwarded-Proto https;
|
395
|
+
|
396
|
+
}
|
397
|
+
}
|
398
|
+
HEREDOC
|
399
|
+
end
|
400
|
+
|
401
|
+
def self.nginx_fallback_vhost
|
402
|
+
<<-'HEREDOC'
|
403
|
+
# _.conf
|
404
|
+
# Default server for clients who do not send correct Host header.
|
405
|
+
# The underline in the file name makes sure that this file comes first in the dir.
|
406
|
+
server {
|
407
|
+
server_name _;
|
408
|
+
listen *:80 default_server deferred;
|
409
|
+
return 404;
|
410
|
+
}
|
411
|
+
HEREDOC
|
412
|
+
end
|
413
|
+
|
414
|
+
|
415
|
+
end
|
416
|
+
end
|
data/lib/meroku.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require "meroku/version"
|
2
|
+
require "meroku/util"
|
3
|
+
require "meroku/sanitychecks"
|
4
|
+
require "meroku/cli"
|
5
|
+
require "meroku/cli/server"
|
6
|
+
require "meroku/cli/keys"
|
7
|
+
require "meroku/cli/domains"
|
8
|
+
require "meroku/cli/remote"
|
9
|
+
require "meroku/cli/certs"
|
10
|
+
require "meroku/cli/config"
|
11
|
+
require "meroku/cli/cli"
|
12
|
+
|
13
|
+
require "meroku/error"
|
14
|
+
require "meroku/core_ext"
|
15
|
+
require 'aws-sdk'
|
16
|
+
|
17
|
+
module Meroku
|
18
|
+
|
19
|
+
PRODUCTION_IP = "34.239.241.218"
|
20
|
+
|
5
21
|
end
|
metadata
CHANGED
@@ -1,57 +1,182 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meroku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Meroku System
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
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
|
-
|
11
|
+
date: 2017-06-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.6.8
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.6.8
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-sdk
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: dotenv
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rest-client
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.6.8
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.6.8
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: activesupport
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: actionview
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 4.1.1
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 4.1.1
|
139
|
+
description:
|
140
|
+
email:
|
141
|
+
- meroku.system@gmail.com
|
142
|
+
executables:
|
143
|
+
- meroku
|
48
144
|
extensions: []
|
49
145
|
extra_rdoc_files: []
|
50
146
|
files:
|
147
|
+
- bin/console
|
148
|
+
- bin/setup
|
149
|
+
- exe/meroku
|
51
150
|
- lib/meroku.rb
|
52
|
-
|
53
|
-
|
54
|
-
-
|
151
|
+
- lib/meroku/app.rb
|
152
|
+
- lib/meroku/app/collaborator.rb
|
153
|
+
- lib/meroku/application_record.rb
|
154
|
+
- lib/meroku/apps_controller.rb
|
155
|
+
- lib/meroku/cli.rb
|
156
|
+
- lib/meroku/cli/certs.rb
|
157
|
+
- lib/meroku/cli/certs.rb~
|
158
|
+
- lib/meroku/cli/cli.rb
|
159
|
+
- lib/meroku/cli/config.rb
|
160
|
+
- lib/meroku/cli/domains.rb
|
161
|
+
- lib/meroku/cli/keys.rb
|
162
|
+
- lib/meroku/cli/remote.rb
|
163
|
+
- lib/meroku/cli/remote.rb~
|
164
|
+
- lib/meroku/cli/server.rb
|
165
|
+
- lib/meroku/cli/server.rb~
|
166
|
+
- lib/meroku/config.rb
|
167
|
+
- lib/meroku/configs_controller.rb
|
168
|
+
- lib/meroku/core_ext.rb
|
169
|
+
- lib/meroku/domain.rb
|
170
|
+
- lib/meroku/domains_controller.rb
|
171
|
+
- lib/meroku/error.rb
|
172
|
+
- lib/meroku/key.rb
|
173
|
+
- lib/meroku/keys_controller.rb
|
174
|
+
- lib/meroku/sanitychecks.rb
|
175
|
+
- lib/meroku/user.rb
|
176
|
+
- lib/meroku/util.rb
|
177
|
+
- lib/meroku/version.rb
|
178
|
+
homepage: http://example.net
|
179
|
+
licenses: []
|
55
180
|
metadata: {}
|
56
181
|
post_install_message:
|
57
182
|
rdoc_options: []
|
@@ -69,9 +194,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
194
|
version: '0'
|
70
195
|
requirements: []
|
71
196
|
rubyforge_project:
|
72
|
-
rubygems_version: 2.
|
197
|
+
rubygems_version: 2.6.12
|
73
198
|
signing_key:
|
74
199
|
specification_version: 4
|
75
|
-
summary:
|
200
|
+
summary: The command line tool for meroku.com
|
76
201
|
test_files: []
|
77
|
-
has_rdoc:
|