meroku 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +2 -0
  3. data/Guardfile +7 -18
  4. data/README.md +78 -4
  5. data/bin/meroku +1 -1
  6. data/frontend/.gitignore +23 -0
  7. data/frontend/.ruby-version +2 -0
  8. data/frontend/Gemfile +58 -0
  9. data/frontend/Gemfile.lock +233 -0
  10. data/frontend/README.md +24 -0
  11. data/frontend/Rakefile +6 -0
  12. data/frontend/app/assets/config/manifest.js +3 -0
  13. data/frontend/app/assets/images/.keep +0 -0
  14. data/frontend/app/assets/javascripts/application.js +15 -0
  15. data/frontend/app/assets/javascripts/apps.coffee +3 -0
  16. data/frontend/app/assets/javascripts/cable.js +13 -0
  17. data/frontend/app/assets/javascripts/channels/.keep +0 -0
  18. data/frontend/app/assets/javascripts/pages.coffee +3 -0
  19. data/frontend/app/assets/javascripts/publickeys.coffee +3 -0
  20. data/frontend/app/assets/stylesheets/application.css +15 -0
  21. data/frontend/app/assets/stylesheets/apps.scss +3 -0
  22. data/frontend/app/assets/stylesheets/pages.scss +3 -0
  23. data/frontend/app/assets/stylesheets/publickeys.scss +3 -0
  24. data/frontend/app/assets/stylesheets/scaffolds.scss +84 -0
  25. data/frontend/app/channels/application_cable/channel.rb +4 -0
  26. data/frontend/app/channels/application_cable/connection.rb +4 -0
  27. data/frontend/app/controllers/application_controller.rb +3 -0
  28. data/frontend/app/controllers/apps_controller.rb +85 -0
  29. data/frontend/app/controllers/concerns/.keep +0 -0
  30. data/frontend/app/controllers/pages_controller.rb +4 -0
  31. data/frontend/app/controllers/publickeys_controller.rb +76 -0
  32. data/frontend/app/controllers/users/confirmations_controller.rb +28 -0
  33. data/frontend/app/controllers/users/omniauth_callbacks_controller.rb +28 -0
  34. data/frontend/app/controllers/users/passwords_controller.rb +32 -0
  35. data/frontend/app/controllers/users/registrations_controller.rb +89 -0
  36. data/frontend/app/controllers/users/sessions_controller.rb +25 -0
  37. data/frontend/app/controllers/users/unlocks_controller.rb +28 -0
  38. data/frontend/app/helpers/application_helper.rb +2 -0
  39. data/frontend/app/helpers/apps_helper.rb +2 -0
  40. data/frontend/app/helpers/pages_helper.rb +2 -0
  41. data/frontend/app/helpers/publickeys_helper.rb +2 -0
  42. data/frontend/app/jobs/application_job.rb +2 -0
  43. data/frontend/app/mailers/application_mailer.rb +4 -0
  44. data/frontend/app/models/app.rb +3 -0
  45. data/frontend/app/models/application_record.rb +3 -0
  46. data/frontend/app/models/concerns/.keep +0 -0
  47. data/frontend/app/models/publickey.rb +3 -0
  48. data/frontend/app/models/user.rb +12 -0
  49. data/frontend/app/serializable/serializable_app.rb +6 -0
  50. data/frontend/app/serializable/serializable_publickey.rb +7 -0
  51. data/frontend/app/serializable/serializable_user.rb +7 -0
  52. data/frontend/app/serializers/app_serializer.rb +3 -0
  53. data/frontend/app/serializers/publickey_serializer.rb +4 -0
  54. data/frontend/app/views/apps/_app.json.jbuilder +2 -0
  55. data/frontend/app/views/apps/_form.html.erb +22 -0
  56. data/frontend/app/views/apps/edit.html.erb +6 -0
  57. data/frontend/app/views/apps/index.html.erb +27 -0
  58. data/frontend/app/views/apps/index.json.jbuilder +1 -0
  59. data/frontend/app/views/apps/new.html.erb +5 -0
  60. data/frontend/app/views/apps/show.html.erb +9 -0
  61. data/frontend/app/views/apps/show.json.jbuilder +1 -0
  62. data/frontend/app/views/devise/confirmations/new.html.erb +16 -0
  63. data/frontend/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  64. data/frontend/app/views/devise/mailer/email_changed.html.erb +7 -0
  65. data/frontend/app/views/devise/mailer/password_change.html.erb +3 -0
  66. data/frontend/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  67. data/frontend/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  68. data/frontend/app/views/devise/passwords/edit.html.erb +25 -0
  69. data/frontend/app/views/devise/passwords/new.html.erb +16 -0
  70. data/frontend/app/views/devise/registrations/edit.html.erb +43 -0
  71. data/frontend/app/views/devise/registrations/new.html.erb +29 -0
  72. data/frontend/app/views/devise/sessions/new.html.erb +26 -0
  73. data/frontend/app/views/devise/shared/_links.html.erb +25 -0
  74. data/frontend/app/views/devise/unlocks/new.html.erb +16 -0
  75. data/frontend/app/views/layouts/application.html.erb +16 -0
  76. data/frontend/app/views/layouts/mailer.html.erb +13 -0
  77. data/frontend/app/views/layouts/mailer.text.erb +1 -0
  78. data/frontend/app/views/pages/landing.html.erb +2 -0
  79. data/frontend/app/views/publickeys/_form.html.erb +32 -0
  80. data/frontend/app/views/publickeys/_publickey.json.jbuilder +2 -0
  81. data/frontend/app/views/publickeys/edit.html.erb +6 -0
  82. data/frontend/app/views/publickeys/index.html.erb +31 -0
  83. data/frontend/app/views/publickeys/index.json.jbuilder +1 -0
  84. data/frontend/app/views/publickeys/new.html.erb +5 -0
  85. data/frontend/app/views/publickeys/show.html.erb +19 -0
  86. data/frontend/app/views/publickeys/show.json.jbuilder +1 -0
  87. data/frontend/bin/bundle +3 -0
  88. data/frontend/bin/rails +9 -0
  89. data/frontend/bin/rake +9 -0
  90. data/frontend/bin/setup +38 -0
  91. data/frontend/bin/spring +17 -0
  92. data/frontend/bin/update +29 -0
  93. data/frontend/bin/yarn +11 -0
  94. data/frontend/config.ru +5 -0
  95. data/frontend/config/application.rb +18 -0
  96. data/frontend/config/boot.rb +3 -0
  97. data/frontend/config/cable.yml +10 -0
  98. data/frontend/config/database.yml +25 -0
  99. data/frontend/config/environment.rb +5 -0
  100. data/frontend/config/environments/development.rb +56 -0
  101. data/frontend/config/environments/production.rb +97 -0
  102. data/frontend/config/environments/test.rb +42 -0
  103. data/frontend/config/initializers/ams.rb +3 -0
  104. data/frontend/config/initializers/application_controller_renderer.rb +8 -0
  105. data/frontend/config/initializers/assets.rb +14 -0
  106. data/frontend/config/initializers/backtrace_silencers.rb +7 -0
  107. data/frontend/config/initializers/cookies_serializer.rb +5 -0
  108. data/frontend/config/initializers/devise.rb +277 -0
  109. data/frontend/config/initializers/filter_parameter_logging.rb +4 -0
  110. data/frontend/config/initializers/inflections.rb +16 -0
  111. data/frontend/config/initializers/mime_types.rb +4 -0
  112. data/frontend/config/initializers/wrap_parameters.rb +14 -0
  113. data/frontend/config/locales/devise.en.yml +64 -0
  114. data/frontend/config/locales/en.yml +33 -0
  115. data/frontend/config/puma.rb +66 -0
  116. data/frontend/config/routes.rb +19 -0
  117. data/frontend/config/secrets.yml +32 -0
  118. data/frontend/config/spring.rb +6 -0
  119. data/frontend/db/migrate/20171023223732_devise_create_users.rb +42 -0
  120. data/frontend/db/migrate/20171025193627_add_token_to_users.rb +5 -0
  121. data/frontend/db/migrate/20171025203706_create_apps.rb +9 -0
  122. data/frontend/db/migrate/20171025223804_add_user_to_apps.rb +5 -0
  123. data/frontend/db/migrate/20171026071440_create_publickeys.rb +11 -0
  124. data/frontend/db/schema.rb +32 -0
  125. data/frontend/db/seeds.rb +7 -0
  126. data/frontend/etc_nginx_sites-available_default +29 -0
  127. data/frontend/lib/assets/.keep +0 -0
  128. data/frontend/lib/tasks/.keep +0 -0
  129. data/frontend/log/.keep +0 -0
  130. data/frontend/package.json +5 -0
  131. data/frontend/public/404.html +67 -0
  132. data/frontend/public/422.html +67 -0
  133. data/frontend/public/500.html +66 -0
  134. data/frontend/public/apple-touch-icon-precomposed.png +0 -0
  135. data/frontend/public/apple-touch-icon.png +0 -0
  136. data/frontend/public/favicon.ico +0 -0
  137. data/frontend/public/robots.txt +1 -0
  138. data/frontend/test/application_system_test_case.rb +5 -0
  139. data/frontend/test/controllers/.keep +0 -0
  140. data/frontend/test/controllers/apps_controller_test.rb +48 -0
  141. data/frontend/test/controllers/pages_controller_test.rb +9 -0
  142. data/frontend/test/controllers/publickeys_controller_test.rb +48 -0
  143. data/frontend/test/fixtures/.keep +0 -0
  144. data/frontend/test/fixtures/apps.yml +7 -0
  145. data/frontend/test/fixtures/files/.keep +0 -0
  146. data/frontend/test/fixtures/publickeys.yml +11 -0
  147. data/frontend/test/fixtures/users.yml +11 -0
  148. data/frontend/test/helpers/.keep +0 -0
  149. data/frontend/test/integration/.keep +0 -0
  150. data/frontend/test/mailers/.keep +0 -0
  151. data/frontend/test/models/.keep +0 -0
  152. data/frontend/test/models/app_test.rb +7 -0
  153. data/frontend/test/models/publickey_test.rb +7 -0
  154. data/frontend/test/models/user_test.rb +7 -0
  155. data/frontend/test/system/.keep +0 -0
  156. data/frontend/test/system/apps_test.rb +9 -0
  157. data/frontend/test/system/publickeys_test.rb +9 -0
  158. data/frontend/test/test_helper.rb +9 -0
  159. data/frontend/tmp/.keep +0 -0
  160. data/frontend/vendor/.keep +0 -0
  161. data/lib/meroku.rb +11 -24
  162. data/lib/meroku/aws.rb +32 -0
  163. data/lib/meroku/cli.rb +131 -0
  164. data/lib/meroku/infrastructure.rb +10 -17
  165. data/lib/meroku/infrastructure/node.rb +68 -0
  166. data/lib/meroku/tunnel.rb +50 -0
  167. data/lib/meroku/version.rb +1 -1
  168. data/meroku.gemspec +7 -3
  169. data/modified-cedar-14.sh +175 -0
  170. metadata +222 -19
File without changes
File without changes
data/lib/meroku.rb CHANGED
@@ -1,30 +1,17 @@
1
+ require "active_support/core_ext/object/try"
2
+ require "net/ssh"
3
+ require 'net/http'
4
+ require "escape"
5
+ require "aws-sdk-ec2"
6
+ require "dotenv"
7
+ require "byebug"
8
+ require 'rest-client'
1
9
  require "meroku/version"
10
+ require "meroku/tunnel"
11
+ require "meroku/cli"
12
+ require "meroku/aws"
2
13
  require "meroku/infrastructure"
3
- require 'aws-sdk-ec2'
4
- require 'dotenv/load'
5
14
 
6
15
  module Meroku
7
16
 
8
- def self.cli_start(*args)
9
- case args.join(" ")
10
- when "infrastructure spawn"
11
- Meroku::Infrastructure.spawn
12
- when "infrastructure despawn"
13
- Meroku::Infrastructure.despawn
14
- else
15
- print_help
16
- end
17
- end
18
-
19
- def self.print_help
20
- puts <<~HEREDOC
21
- Usage: meroku command subcommand
22
-
23
- Examples
24
-
25
- meroku infrastrucuture spawn # Spawns server
26
-
27
- HEREDOC
28
- end
29
-
30
17
  end
data/lib/meroku/aws.rb ADDED
@@ -0,0 +1,32 @@
1
+ module Meroku
2
+ module Aws
3
+
4
+ EC2_PARAMS = {
5
+ image_id: 'ami-841f46ff', #was xenial 'ami-cd0f5cb6',
6
+ min_count: 1,
7
+ max_count: 1,
8
+ key_name: 'meroku.id_rsa',
9
+ instance_type: 't2.micro',
10
+ tag_specifications: [
11
+ {
12
+ resource_type: "instance",
13
+ tags: [
14
+ {
15
+ key: "Name",
16
+ value: "node",
17
+ },
18
+ ],
19
+ },
20
+ ]
21
+ }
22
+
23
+ def credentials
24
+ ::Aws::Credentials.new(ENV['AWS_ACCESS_KEY'], ENV['AWS_SECRET'])
25
+ end
26
+
27
+ def ec2_client
28
+ ::Aws::EC2::Client.new(region: 'us-east-1', credentials: credentials)
29
+ end
30
+
31
+ end
32
+ end
data/lib/meroku/cli.rb ADDED
@@ -0,0 +1,131 @@
1
+ module Meroku
2
+ module CLI
3
+
4
+ HELP = <<~HEREDOC
5
+ Usage: meroku command subcommand
6
+
7
+ Examples
8
+
9
+ meroku signup # if you havent done already
10
+
11
+ meroku create
12
+
13
+ meroku keys:add
14
+
15
+ meroku infrastrucuture spawn # Spawns server
16
+
17
+ HEREDOC
18
+
19
+ def self.start(*args)
20
+ case args.join(" ")
21
+ when "infrastructure spawn"
22
+ load_secrets || exit
23
+ node = Meroku::Infrastructure::Node.new.associate_address.install_packages.install_frontend_app
24
+ puts "spawned #{node.instance.try(:instance_id)}"
25
+ when "infrastructure despawn"
26
+ load_secrets || exit
27
+ Meroku::Infrastructure.despawn
28
+ when "signup"
29
+ signup
30
+ when "keys:add"
31
+ token_check || exit
32
+ keys_add
33
+ when "create"
34
+ token_check || exit
35
+ create
36
+ else
37
+ puts HELP
38
+ end
39
+ end
40
+
41
+ def self.signup
42
+ print "Email: "
43
+ email = STDIN.gets
44
+ print "Password: "
45
+ password = STDIN.noecho(&:gets).chomp
46
+ print "\n"
47
+ url = "https://www.meroku.com/users.json"
48
+ #url = "http://localhost:3000/users.json"
49
+ response_json = RestClient.post url, {:user=>{:email => email, :password => password, :password_confirmation => password}}.to_json, timeout: 1, :content_type => :json, :accept => :json
50
+ if JSON.parse(response_json)["errors"] && JSON.parse(response_json)["errors"].size > 0
51
+ puts JSON.parse(response_json)["errors"].map{|x| x["detail"]}.join(".")
52
+ else
53
+ email = JSON.parse(response_json)["data"]["attributes"]["email"]
54
+ token = JSON.parse(response_json)["data"]["attributes"]["token"]
55
+ puts "Signed up #{email}"
56
+ save_token(token)
57
+ end
58
+ end
59
+
60
+ def self.create
61
+ url = "https://www.meroku.com/apps.json"
62
+ token = `cat ~/.meroku/.token`.chomp
63
+ response_json = RestClient.post url, {:app=>{:name => "unnamed"}, :token=>token}.to_json, timeout: 1, :content_type => :json, :accept => :json
64
+
65
+ if JSON.parse(response_json)["errors"] && JSON.parse(response_json)["errors"].size > 0
66
+ puts JSON.parse(response_json)["errors"].map{|x| x["detail"]}.join(".")
67
+ else
68
+ name = JSON.parse(response_json)["data"]["attributes"]["name"]
69
+ puts "Created #{name}, adding git remote"
70
+ puts "git remote remove meroku"
71
+ `git remote remove meroku`
72
+ puts "git remote add meroku git@www.meroku.com:#{name}.git"
73
+ `git remote add meroku git@www.meroku.com:#{name}.git`
74
+ end
75
+ end
76
+
77
+ def self.token_check
78
+ if !File.exist? "#{Dir.home}/.meroku/.token"
79
+ puts "error: Have you logged in yet?"
80
+ return nil
81
+ end
82
+ true
83
+ end
84
+
85
+ def self.load_secrets
86
+ if !File.exist? "#{Dir.home}/.meroku/.secret"
87
+ puts "error: File #{Dir.home}/.meroku/.secret not found"
88
+ return nil
89
+ end
90
+ env_file = Dir.home+'/.meroku/meroku.env'
91
+ if !File.exist? env_file
92
+ secret=`cat ~/.meroku/.secret`.chomp
93
+ remote_env_file = "http://www.sam-we.com/dropbox/meroku-#{secret}/meroku.env"
94
+ File.write(env_file, Net::HTTP.get(URI.parse(remote_env_file)))
95
+ end
96
+ Dotenv.load(env_file)
97
+ end
98
+
99
+ def self.save_token(token)
100
+ dirname = File.dirname("#{Dir.home}/.meroku")
101
+ unless File.directory?(dirname)
102
+ FileUtils.mkdir(dirname)
103
+ end
104
+ File.open("#{Dir.home}/.meroku/.token", 'w') { |file| file.write(token) }
105
+ end
106
+
107
+ def self.keys_add
108
+ if !File.exist? "#{Dir.home}/.ssh/id_rsa.pub"
109
+ puts "error: File #{Dir.home}/.ssh/id_rsa.pub not found"
110
+ puts "You can use this command to generate a key:"
111
+ puts " ssh-keygen -t rsa"
112
+ return nil
113
+ end
114
+ name = "id_rsa.pub"
115
+ data = `cat ~/.ssh/id_rsa.pub`.chomp
116
+ url = "https://www.meroku.com/publickeys.json"
117
+ token = `cat ~/.meroku/.token`.chomp
118
+ response_json = RestClient.post url, {:publickey=>{:name => nam, :data=>data}, :token=>token}.to_json, timeout: 1, :content_type => :json, :accept => :json
119
+
120
+ if JSON.parse(response_json)["errors"] && JSON.parse(response_json)["errors"].size > 0
121
+ puts JSON.parse(response_json)["errors"].map{|x| x["detail"]}.join(".")
122
+ else
123
+ name = JSON.parse(response_json)["data"]["attributes"]["name"]
124
+ puts "Added #{name}"
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+
131
+ end
@@ -1,24 +1,17 @@
1
+ require "meroku/infrastructure/node"
2
+
1
3
  module Meroku
2
4
  module Infrastructure
3
- def self.spawn
4
- credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY'], ENV['AWS_SECRET'])
5
- ec2_client = Aws::EC2::Client.new(region: 'us-east-1', credentials: credentials)
6
- ec2_client.run_instances(
7
- image_id: 'ami-cd0f5cb6',
8
- min_count: 1,
9
- max_count: 1,
10
- key_name: 'meroku.id_rsa',
11
- instance_type: 't2.micro',
12
- ).instances.first
13
- end
5
+
6
+ extend Meroku::Aws
14
7
 
15
8
  def self.despawn
16
- resp = nil
17
- credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY'], ENV['AWS_SECRET'])
18
- ec2 = Aws::EC2::Resource.new(region: 'us-east-1', credentials: credentials)
19
- running_instance = ec2.instances.detect { |i| i.exists? && i.state.code!=48 }
20
- resp = running_instance.terminate if running_instance
21
- resp
9
+ instances = ec2_client.describe_instances(filters:[{ name: "tag:Name", values: ['node'] }, { name: 'instance-state-name', values: ['running','pending'] }]).reservations.map { |xx| xx.instances.first.instance_id }
10
+ puts "will despawn #{instances.inspect}"
11
+ ec2_client.terminate_instances({
12
+ instance_ids: instances
13
+ }) if instances.size > 0
22
14
  end
23
15
  end
16
+
24
17
  end
@@ -0,0 +1,68 @@
1
+
2
+ module Meroku
3
+ module Infrastructure
4
+ class Node
5
+ include Meroku::Aws
6
+ attr_accessor :instance, :tunnel
7
+
8
+ def initialize
9
+ result = ec2_client.try(:run_instances,Meroku::Aws::EC2_PARAMS)
10
+ @instance = result.instances.first if result
11
+ @tunnel = Meroku::Tunnel.new(
12
+ ip: "34.239.241.218",
13
+ username: "ubuntu",
14
+ keys: "~/crypto/meroku/meroku.id_rsa",
15
+ verify_host_key: false,
16
+ verbose: false
17
+ )
18
+ self
19
+ end
20
+
21
+ def associate_address
22
+ retries ||= 0
23
+ return self if !ec2_client
24
+ ec2_client.associate_address(
25
+ allocation_id: "eipalloc-139f7823",
26
+ instance_id: @instance.try(:instance_id)
27
+ )
28
+ self
29
+ rescue ::Aws::EC2::Errors::InvalidInstanceID => e
30
+ print STDERR.print "."
31
+ sleep 2
32
+ retry if (retries += 1) < 15
33
+ end
34
+
35
+ def install_packages
36
+ @tunnel.run "sudo apt-add-repository ppa:brightbox/ruby-ng\;"
37
+ @tunnel.run "curl -s -o /tmp/modified-cedar-14.sh https://raw.githubusercontent.com/oystersauce8/meroku/master/modified-cedar-14.sh"
38
+ @tunnel.run "sudo chmod 755 /tmp/modified-cedar-14.sh"
39
+ @tunnel.run "/bin/bash -lc 'sudo /tmp/modified-cedar-14.sh'"
40
+ #@tunnel.run "sudo apt-get update\;"
41
+ @tunnel.run "sudo apt-get install -y ruby2.4 ruby2.4-dev"
42
+ @tunnel.run "sudo apt-get install -y nginx libsqlite3-dev nodejs"
43
+ self
44
+ end
45
+
46
+ def install_frontend_app
47
+ @tunnel.run 'mkdir /home/ubuntu/.meroku'
48
+ @tunnel.run "cd ~\; git clone https://github.com/oystersauce8/meroku\;"
49
+ @tunnel.run "sudo cp ~/meroku/frontend/etc_nginx_sites-available_default /etc/nginx/sites-available/default"
50
+
51
+ @tunnel.run "curl -o /home/ubuntu/.meroku/letsencrypt_fullchain.pem http://www.sam-we.com/dropbox/meroku-#{ENV['SECRET']}/letsencrypt_fullchain.pem"
52
+ @tunnel.run "curl -o /home/ubuntu/.meroku/letsencrypt_privkey.pem http://www.sam-we.com/dropbox/meroku-#{ENV['SECRET']}/letsencrypt_privkey.pem"
53
+
54
+ @tunnel.run "cd ~/.meroku/\; curl -O http://www.sam-we.com/dropbox/meroku-#{ENV['SECRET']}/ssh_host_keys.tgz"
55
+ #@tunnel.run "cd ~/.meroku/\; sudo tar xf ssh_host_keys.tgz -C /etc/ssh/ --overwrite"
56
+ @tunnel.run "cd ~/meroku/frontend/\; sudo gem install bundler\; bundle\;"
57
+ @tunnel.run "(cd ~/meroku/frontend && RAILS_ENV=production bundle exec rails assets:precompile)"
58
+
59
+ @tunnel.run "(cd ~/meroku/frontend && RAILS_ENV=production bundle exec rake db:migrate)"
60
+ @tunnel.run "cd ~/meroku/frontend/\; bundle exec puma -d"
61
+ @tunnel.run "sudo service nginx restart"
62
+ @tunnel.run "sudo service ssh restart"
63
+ self
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,50 @@
1
+ module Meroku
2
+ class Tunnel
3
+
4
+ attr_accessor :ip, :username, :keys, :verify_host_key, :verbose
5
+
6
+ def initialize(ip:,username:,keys:,verify_host_key:,verbose:)
7
+ @ip = ip
8
+ @username = username
9
+ @keys = keys
10
+ @verify_host_key = verify_host_key
11
+ @verbose = verbose
12
+ end
13
+
14
+ def run(cmd)
15
+ @verbose=true
16
+ retries ||= 0
17
+ Net::SSH.start(@ip,
18
+ @username,
19
+ password: 'password',
20
+ keys: @keys,
21
+ verify_host_key: @verify_host_key,
22
+ timeout: 90) do |ssh|
23
+ channel = ssh.open_channel do |ch|
24
+ STDERR.print cmd
25
+ ch.exec cmd do |ch, success|
26
+ raise "could not execute command" unless success
27
+ ch.on_data do |c, data|
28
+ if @verbose
29
+ $stdout.print data
30
+ else
31
+ $stdout.print "."
32
+ end
33
+ end
34
+ ch.on_extended_data do |c, type, data|
35
+ if @verbose
36
+ $stderr.print data
37
+ else
38
+ $stderr.print "."
39
+ end
40
+ end
41
+ ch.on_close { print "\n" }
42
+ end
43
+ end
44
+ channel.wait
45
+ end
46
+ rescue Errno::ECONNREFUSED => e
47
+ retry if (retries += 1) < 10
48
+ end
49
+ end
50
+ end
@@ -1,3 +1,3 @@
1
1
  module Meroku
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
data/meroku.gemspec CHANGED
@@ -21,16 +21,20 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_runtime_dependency "aws-sdk", "~> 3"
25
- spec.add_runtime_dependency "dotenv", "~> 2.2.1"
24
+ spec.add_dependency 'escape', '~> 0.0.4'
25
+ spec.add_dependency 'rest-client'
26
26
 
27
+ spec.add_runtime_dependency "activesupport", "~> 5.1.4"
28
+ spec.add_runtime_dependency "aws-sdk-ec2", "~> 1"
29
+ spec.add_runtime_dependency "dotenv", "~> 2.2.1"
30
+ spec.add_runtime_dependency "net-ssh", "~> 4.2.0"
31
+
27
32
  spec.add_development_dependency "bundler", "~> 1.15"
28
33
  spec.add_development_dependency "rake", "~> 10.0"
29
34
  spec.add_development_dependency "minitest", "~> 5.0"
30
35
 
31
36
  spec.add_development_dependency "guard", "~>2.14.1"
32
37
  spec.add_development_dependency "guard-minitest", "~>2.4.6"
33
- spec.add_development_dependency "guard-shell", "~>0.7.1"
34
38
  spec.add_development_dependency "byebug", "~> 9.1.0"
35
39
  spec.add_development_dependency "simplecov", "~> 0.14.1"
36
40
  spec.add_development_dependency "coveralls", "~> 0.8.21"
@@ -0,0 +1,175 @@
1
+ #!/bin/bash
2
+
3
+ exec 2>&1
4
+ set -e
5
+ set -x
6
+
7
+ cat > /etc/apt/sources.list <<EOF
8
+ deb http://archive.ubuntu.com/ubuntu/ trusty main universe
9
+ deb http://archive.ubuntu.com/ubuntu/ trusty-security main universe
10
+ deb http://archive.ubuntu.com/ubuntu/ trusty-updates main universe
11
+
12
+ deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main
13
+ EOF
14
+
15
+ apt-key add - <<'PGDG_ACCC4CF8'
16
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
17
+ Version: GnuPG v1
18
+
19
+ mQINBE6XR8IBEACVdDKT2HEH1IyHzXkb4nIWAY7echjRxo7MTcj4vbXAyBKOfjja
20
+ UrBEJWHN6fjKJXOYWXHLIYg0hOGeW9qcSiaa1/rYIbOzjfGfhE4x0Y+NJHS1db0V
21
+ G6GUj3qXaeyqIJGS2z7m0Thy4Lgr/LpZlZ78Nf1fliSzBlMo1sV7PpP/7zUO+aA4
22
+ bKa8Rio3weMXQOZgclzgeSdqtwKnyKTQdXY5MkH1QXyFIk1nTfWwyqpJjHlgtwMi
23
+ c2cxjqG5nnV9rIYlTTjYG6RBglq0SmzF/raBnF4Lwjxq4qRqvRllBXdFu5+2pMfC
24
+ IZ10HPRdqDCTN60DUix+BTzBUT30NzaLhZbOMT5RvQtvTVgWpeIn20i2NrPWNCUh
25
+ hj490dKDLpK/v+A5/i8zPvN4c6MkDHi1FZfaoz3863dylUBR3Ip26oM0hHXf4/2U
26
+ A/oA4pCl2W0hc4aNtozjKHkVjRx5Q8/hVYu+39csFWxo6YSB/KgIEw+0W8DiTII3
27
+ RQj/OlD68ZDmGLyQPiJvaEtY9fDrcSpI0Esm0i4sjkNbuuh0Cvwwwqo5EF1zfkVj
28
+ Tqz2REYQGMJGc5LUbIpk5sMHo1HWV038TWxlDRwtOdzw08zQA6BeWe9FOokRPeR2
29
+ AqhyaJJwOZJodKZ76S+LDwFkTLzEKnYPCzkoRwLrEdNt1M7wQBThnC5z6wARAQAB
30
+ tBxQb3N0Z3JlU1FMIERlYmlhbiBSZXBvc2l0b3J5iQI9BBMBCAAnAhsDBQsJCAcD
31
+ BRUKCQgLBRYCAwEAAh4BAheABQJS6RUZBQkOhCctAAoJEH/MfUaszEz4zmQP/2ad
32
+ HtuaXL5Xu3C3NGLha/aQb9iSJC8z5vN55HMCpsWlmslCBuEr+qR+oZvPkvwh0Io/
33
+ 8hQl/qN54DMNifRwVL2n2eG52yNERie9BrAMK2kNFZZCH4OxlMN0876BmDuNq2U6
34
+ 7vUtCv+pxT+g9R1LvlPgLCTjS3m+qMqUICJ310BMT2cpYlJx3YqXouFkdWBVurI0
35
+ pGU/+QtydcJALz5eZbzlbYSPWbOm2ZSS2cLrCsVNFDOAbYLtUn955yXB5s4rIscE
36
+ vTzBxPgID1iBknnPzdu2tCpk07yJleiupxI1yXstCtvhGCbiAbGFDaKzhgcAxSIX
37
+ 0ZPahpaYLdCkcoLlfgD+ar4K8veSK2LazrhO99O0onRG0p7zuXszXphO4E/WdbTO
38
+ yDD35qCqYeAX6TaB+2l4kIdVqPgoXT/doWVLUK2NjZtd3JpMWI0OGYDFn2DAvgwP
39
+ xqKEoGTOYuoWKssnwLlA/ZMETegak27gFAKfoQlmHjeA/PLC2KRYd6Wg2DSifhn+
40
+ 2MouoE4XFfeekVBQx98rOQ5NLwy/TYlsHXm1n0RW86ETN3chj/PPWjsi80t5oepx
41
+ 82azRoVu95LJUkHpPLYyqwfueoVzp2+B2hJU2Rg7w+cJq64TfeJG8hrc93MnSKIb
42
+ zTvXfdPtvYdHhhA2LYu4+5mh5ASlAMJXD7zIOZt2iEYEEBEIAAYFAk6XSO4ACgkQ
43
+ xa93SlhRC1qmjwCg9U7U+XN7Gc/dhY/eymJqmzUGT/gAn0guvoX75Y+BsZlI6dWn
44
+ qaFU6N8HiQIcBBABCAAGBQJOl0kLAAoJEExaa6sS0qeuBfEP/3AnLrcKx+dFKERX
45
+ o4NBCGWr+i1CnowupKS3rm2xLbmiB969szG5TxnOIvnjECqPz6skK3HkV3jTZaju
46
+ v3sR6M2ItpnrncWuiLnYcCSDp9TEMpCWzTEgtrBlKdVuTNTeRGILeIcvqoZX5w+u
47
+ i0eBvvbeRbHEyUsvOEnYjrqoAjqUJj5FUZtR1+V9fnZp8zDgpOSxx0LomnFdKnhj
48
+ uyXAQlRCA6/roVNR9ruRjxTR5ubteZ9ubTsVYr2/eMYOjQ46LhAgR+3Alblu/WHB
49
+ MR/9F9//RuOa43R5Sjx9TiFCYol+Ozk8XRt3QGweEH51YkSYY3oRbHBb2Fkql6N6
50
+ YFqlLBL7/aiWnNmRDEs/cdpo9HpFsbjOv4RlsSXQfvvfOayHpT5nO1UQFzoyMVpJ
51
+ 615zwmQDJT5Qy7uvr2eQYRV9AXt8t/H+xjQsRZCc5YVmeAo91qIzI/tA2gtXik49
52
+ 6yeziZbfUvcZzuzjjxFExss4DSAwMgorvBeIbiz2k2qXukbqcTjB2XqAlZasd6Ll
53
+ nLXpQdqDV3McYkP/MvttWh3w+J/woiBcA7yEI5e3YJk97uS6+ssbqLEd0CcdT+qz
54
+ +Waw0z/ZIU99Lfh2Qm77OT6vr//Zulw5ovjZVO2boRIcve7S97gQ4KC+G/+QaRS+
55
+ VPZ67j5UMxqtT/Y4+NHcQGgwF/1iiQI9BBMBCAAnAhsDBQsJCAcDBRUKCQgLBRYC
56
+ AwEAAh4BAheABQJQeSssBQkDwxbfAAoJEH/MfUaszEz4bgkP/0AI0UgDgkNNqplA
57
+ IpE/pkwem2jgGpJGKurh2xDu6j2ZL+BPzPhzyCeMHZwTXkkI373TXGQQP8dIa+RD
58
+ HAZ3iijw4+ISdKWpziEUJjUk04UMPTlN+dYJt2EHLQDD0VLtX0yQC/wLmVEH/REp
59
+ oclbVjZR/+ehwX2IxOIlXmkZJDSycl975FnSUjMAvyzty8P9DN0fIrQ7Ju+BfMOM
60
+ TnUkOdp0kRUYez7pxbURJfkM0NxAP1geACI91aISBpFg3zxQs1d3MmUIhJ4wHvYB
61
+ uaR7Fx1FkLAxWddre/OCYJBsjucE9uqc04rgKVjN5P/VfqNxyUoB+YZ+8Lk4t03p
62
+ RBcD9XzcyOYlFLWXbcWxTn1jJ2QMqRIWi5lzZIOMw5B+OK9LLPX0dAwIFGr9WtuV
63
+ J2zp+D4CBEMtn4Byh8EaQsttHeqAkpZoMlrEeNBDz2L7RquPQNmiuom15nb7xU/k
64
+ 7PGfqtkpBaaGBV9tJkdp7BdH27dZXx+uT+uHbpMXkRrXliHjWpAw+NGwADh/Pjmq
65
+ ExlQSdgAiXy1TTOdzxKH7WrwMFGDK0fddKr8GH3f+Oq4eOoNRa6/UhTCmBPbryCS
66
+ IA7EAd0Aae9YaLlOB+eTORg/F1EWLPm34kKSRtae3gfHuY2cdUmoDVnOF8C9hc0P
67
+ bL65G4NWPt+fW7lIj+0+kF19s2PviQI9BBMBCAAnAhsDBQsJCAcDBRUKCQgLBRYC
68
+ AwEAAh4BAheABQJRKm2VBQkINsBBAAoJEH/MfUaszEz4RTEP/1sQHyjHaUiAPaCA
69
+ v8jw/3SaWP/g8qLjpY6ROjLnDMvwKwRAoxUwcIv4/TWDOMpwJN+CJIbjXsXNYvf9
70
+ OX+UTOvq4iwi4ADrAAw2xw+Jomc6EsYla+hkN2FzGzhpXfZFfUsuphjY3FKL+4hX
71
+ H+R8ucNwIz3yrkfc17MMn8yFNWFzm4omU9/JeeaafwUoLxlULL2zY7H3+QmxCl0u
72
+ 6t8VvlszdEFhemLHzVYRY0Ro/ISrR78CnANNsMIy3i11U5uvdeWVCoWV1BXNLzOD
73
+ 4+BIDbMB/Do8PQCWiliSGZi8lvmj/sKbumMFQonMQWOfQswTtqTyQ3yhUM1LaxK5
74
+ PYq13rggi3rA8oq8SYb/KNCQL5pzACji4TRVK0kNpvtxJxe84X8+9IB1vhBvF/Ji
75
+ /xDd/3VDNPY+k1a47cON0S8Qc8DA3mq4hRfcgvuWy7ZxoMY7AfSJOhleb9+PzRBB
76
+ n9agYgMxZg1RUWZazQ5KuoJqbxpwOYVFja/stItNS4xsmi0lh2I4MNlBEDqnFLUx
77
+ SvTDc22c3uJlWhzBM/f2jH19uUeqm4jaggob3iJvJmK+Q7Ns3WcfhuWwCnc1+58d
78
+ iFAMRUCRBPeFS0qd56QGk1r97B6+3UfLUslCfaaA8IMOFvQSHJwDO87xWGyxeRTY
79
+ IIP9up4xwgje9LB7fMxsSkCDTHOk
80
+ =s3DI
81
+ -----END PGP PUBLIC KEY BLOCK-----
82
+ PGDG_ACCC4CF8
83
+
84
+ apt-get update
85
+ apt-get upgrade -y --force-yes
86
+ apt-get install -y --force-yes \
87
+ autoconf \
88
+ bind9-host \
89
+ bison \
90
+ build-essential \
91
+ coreutils \
92
+ curl \
93
+ daemontools \
94
+ dnsutils \
95
+ ed \
96
+ git \
97
+ imagemagick \
98
+ iputils-tracepath \
99
+ language-pack-en \
100
+ libbz2-dev \
101
+ libcurl4-openssl-dev \
102
+ libev-dev \
103
+ libevent-dev \
104
+ libglib2.0-dev \
105
+ libjpeg-dev \
106
+ libmagickwand-dev \
107
+ libmysqlclient-dev \
108
+ libncurses5-dev \
109
+ libpq-dev \
110
+ libpq5 \
111
+ librdkafka-dev \
112
+ libreadline6-dev \
113
+ libssl-dev \
114
+ libuv-dev \
115
+ libxml2-dev \
116
+ libxslt-dev \
117
+ netcat-openbsd \
118
+ openjdk-7-jdk \
119
+ openjdk-7-jre-headless \
120
+ openssh-client \
121
+ openssh-server \
122
+ postgresql-client-9.6 \
123
+ postgresql-server-dev-9.6 \
124
+ python \
125
+ python-dev \
126
+ socat \
127
+ stunnel \
128
+ syslinux \
129
+ tar \
130
+ telnet \
131
+ zip \
132
+ zlib1g-dev \
133
+ #
134
+
135
+ ## locales
136
+ #apt-cache search language-pack \
137
+ # | cut -d ' ' -f 1 \
138
+ # | grep -v '^language\-pack\-\(gnome\|kde\)\-' \
139
+ # | grep -v '\-base$' \
140
+ # | xargs apt-get install -y --force-yes --no-install-recommends
141
+
142
+ cd /
143
+ rm -rf /var/cache/apt/archives/*.deb
144
+ rm -rf /root/*
145
+ rm -rf /tmp/*
146
+
147
+ ## remove SUID and SGID flags from all binaries
148
+ #function pruned_find() {
149
+ # find / -type d \( -name dev -o -name proc \) -prune -o $@ -print
150
+ #}
151
+ #
152
+ #pruned_find -perm /u+s | xargs -r chmod u-s
153
+ #pruned_find -perm /g+s | xargs -r chmod g-s
154
+ #
155
+ ## remove non-root ownership of files
156
+ #chown root:root /var/lib/libuuid
157
+ #
158
+ ## display build summary
159
+ #set +x
160
+ #echo -e "\nRemaining suspicious security bits:"
161
+ #(
162
+ # pruned_find ! -user root
163
+ # pruned_find -perm /u+s
164
+ # pruned_find -perm /g+s
165
+ # pruned_find -perm /+t
166
+ #) | sed -u "s/^/ /"
167
+
168
+ echo -e "\nInstalled versions:"
169
+ (
170
+ git --version
171
+ python -V
172
+ ) 2>&1 | sed -u "s/^/ /"
173
+
174
+ echo -e "\nSuccess!"
175
+ exit 0