meroku 0.0.0 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
@@ -0,0 +1,3 @@
1
+ module Meroku
2
+ VERSION = "0.1.28"
3
+ end
data/lib/meroku.rb CHANGED
@@ -1,5 +1,21 @@
1
- class Meroku
2
- def self.present?
3
- "Meroku has been successfully distributed as a gem"
4
- end
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.0.0
4
+ version: 0.1.28
5
5
  platform: ruby
6
6
  authors:
7
- - Grayson Wright
7
+ - Meroku System
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2014-08-19 00:00:00.000000000 Z
12
- dependencies: []
13
- description: |
14
- # Meroku
15
-
16
- ## Under Development
17
-
18
- A self-hosted git-powered simple deployment option. No more messing with
19
- headache-inducing NginX configuration files or paying $30 a month for hosted
20
- services.
21
-
22
- ## Prerequisites:
23
-
24
- - Git
25
- - A web application (v0.1.0 will only support Rack)
26
- - Your own server (v0.1.0 will only support Debian 7)
27
- - A DNS provider with a public API (v0.1.0 will only support DNSimple)
28
-
29
- Future versions will hopefully support more application languages & frameworks,
30
- DNS providers, and server operating systems.
31
-
32
- ## Usage
33
-
34
- In the directory that contains your Rack application:
35
-
36
- ```bash
37
- gem install meroku
38
- meroku setup # This will guide you through setting up meroku to talk to your server
39
- meroku new subdomain.yourdomain.com
40
- git push meroku master # Watch your application start up, and visit it online!
41
- ```
42
-
43
- ## License
44
-
45
- Meroku is released under the [MIT License](http://www.opensource.org/licenses/MIT).
46
- email: wright.grayson@gmail.com
47
- executables: []
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
- homepage: https://github.com/graysonwright/meroku
53
- licenses:
54
- - MIT
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.2.2
197
+ rubygems_version: 2.6.12
73
198
  signing_key:
74
199
  specification_version: 4
75
- summary: A self-hosted git-powered simple deployment option
200
+ summary: The command line tool for meroku.com
76
201
  test_files: []
77
- has_rdoc: