pushapp 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a90bcaeac4b94c006852afa1b39a6a6e47fac27f
4
- data.tar.gz: 8c252eb2cf6063b113b125194e918b43d096ec88
3
+ metadata.gz: 6087f97376d51ff71653aa1e8bae7d43fad3996f
4
+ data.tar.gz: 3bf44bdfe73b940d6aa433a3fc38f623c61e83d4
5
5
  SHA512:
6
- metadata.gz: fc6c2a10d4e21936629acc2ac1d3077d1a189040d5dd88e6050196c3f9ce784ac705251cba3c1076fa56ee9cc2aa12eb144f1fc8d80d0f1c2b191b82d542183b
7
- data.tar.gz: 717c1c269b6153a34d652565871d1e31e575918de16e0222ffc0886f3fbc60317c482b94dfb123c87c25d237a20e463063a22253515327ad34dc01c771d5126d
6
+ metadata.gz: dc18dcdb79729f45675bee73c64242ed9de16a614a5d4b99a9c18d06636d1bd8b56968d38c7c56f31f8a222875c1fecbad345d1d4d3c250a99c421bb4b0ae635
7
+ data.tar.gz: d51bbec53b29f95e312ea6eaa44c0f42e48a98552bf6862956a23d9db481736a06668e5b296b38658ffc4716433f0f533d68700edfd8fc97744e0b3101bdd465
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
  require 'pushapp/commands'
3
+ require 'pushapp/generators'
3
4
 
4
5
  module Pushapp
5
6
  class CLI < Thor
@@ -66,5 +67,8 @@ module Pushapp
66
67
  def ssh(remote=nil)
67
68
  Pushapp::Commands.run(:ssh, remote: remote, options: options)
68
69
  end
70
+
71
+ desc "generate MODULE REMOTE", "bootstrapp app with varios optimizaed configs"
72
+ subcommand "generate", Generators
69
73
  end
70
74
  end
@@ -0,0 +1,258 @@
1
+ require 'thor'
2
+ require 'awesome_print'
3
+ require 'json'
4
+
5
+ module Pushapp
6
+ class Generators < Thor
7
+ include Thor::Actions
8
+
9
+ source_root Pushapp::TEMPLATE_ROOT
10
+
11
+ class_option :file, default: Pushapp::DEFAULT_CONFIG_LOCATION,
12
+ type: :string, aliases: '-f', banner: 'Specify a pushapp configuration file'
13
+
14
+ desc 'unicorn-nginx REMOTE', 'generates nginx config for unicorn'
15
+ method_option :host, desc: 'Nginx host, will use remote host as default.'
16
+ method_option :env, desc: "unicorn env, will use remote RAILS_ENV as default."
17
+ method_option :listen, default: '80', desc: "Nginx port to listen. Default: 80"
18
+
19
+ def unicorn_nginx(remote)
20
+ options[:remote] = remote
21
+ template 'unicorn_nginx.conf.erb', "config/deploys/#{app_name}.nginx.conf"
22
+ end
23
+
24
+ desc "unicorn-upstart", "generates unicorn binary for upstart/foreman"
25
+ def unicorn_upstart
26
+ template 'unicorn_upstart.erb', 'bin/unicorn_upstart'
27
+ chmod 'bin/unicorn_upstart', 'a+x'
28
+ end
29
+
30
+ desc "unicorn REMOTE", "generates unicorn config"
31
+ def unicorn(remote)
32
+ options[:remote] = remote
33
+ template 'unicorn.rb.erb', 'config/unicorn.rb'
34
+ end
35
+
36
+ desc "chef-solor REMOTE", "generates chef-solor with knife-solo configs"
37
+ method_option :database,
38
+ type: :string,
39
+ default: 'postgresql',
40
+ desc: 'mysql or postgresql',
41
+ aliases: '-d'
42
+
43
+ method_option :ssh_pub_key,
44
+ type: :string,
45
+ default: "#{ENV['HOME']}/.ssh/id_rsa.pub"
46
+
47
+ method_option :vagrant_box,
48
+ type: :string,
49
+ default: "opscode_ubuntu-12.04-i386_chef-11.4.4"
50
+
51
+ method_option :vagrant_box_url,
52
+ type: :string,
53
+ default: "https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04-i386_chef-11.4.4.box"
54
+
55
+ method_option :db_password,
56
+ type: :string,
57
+ default: 'password1'
58
+
59
+ method_option :ruby,
60
+ type: :string,
61
+ default: '2.0.0-p0'
62
+
63
+ def chef_solo(remote)
64
+ options[:remote] = remote
65
+
66
+ template 'Cheffile.erb', 'config/deploys/chef/Cheffile'
67
+ template 'Vagrantfile.erb', 'config/deploys/chef/Vagrantfile'
68
+ template 'node.json.erb', "config/deploys/chef/nodes/#{app_host}.json"
69
+ template 'user.json.erb', "config/deploys/chef/data_bags/users/#{app_user}.json"
70
+
71
+ template 'chef.gitignore', 'config/deploys/chef/.gitignore'
72
+ end
73
+
74
+ private
75
+
76
+ def app_name
77
+ remote.path.split('/').last
78
+ end
79
+
80
+ def app_user
81
+ remote.user
82
+ end
83
+
84
+ def app_host
85
+ options[:host] || remote.host || '127.0.0.1'
86
+ end
87
+
88
+ def app_path
89
+ remote.path
90
+ end
91
+
92
+ def app_env
93
+ remote.env['RACK_ENV'] || remote.env['RAILS_ENV'] || 'production'
94
+ end
95
+
96
+ def remote
97
+ @remote ||= config.remotes_named_by(options[:remote]).first
98
+ end
99
+
100
+ def config
101
+ @config ||= Pushapp::Config.parse(options[:file])
102
+ end
103
+
104
+ def mysql?
105
+ options[:database] == 'mysql'
106
+ end
107
+
108
+ def postgresql?
109
+ options[:database] == 'postgresql'
110
+ end
111
+
112
+ def postgresql_config
113
+ {
114
+ config: {
115
+ listen_addresses: "*",
116
+ port: "5432"
117
+ },
118
+ pg_hba: [
119
+ {
120
+ type: "local",
121
+ db: "postgres",
122
+ user: "postgres",
123
+ addr: nil,
124
+ method: "trust"
125
+ },
126
+ {
127
+ type: "host",
128
+ db: "all",
129
+ user: "all",
130
+ addr: "0.0.0.0/0",
131
+ method: "md5"
132
+ },
133
+ {
134
+ type: "host",
135
+ db: "all",
136
+ user: "all",
137
+ addr: "::1/0",
138
+ method: "md5"
139
+ }
140
+ ],
141
+ password: {
142
+ postgres: options[:db_password]
143
+ }
144
+ }
145
+ end
146
+
147
+ def mysql_config
148
+ {
149
+ :server_root_password => options[:db_password],
150
+ :server_repl_password => options[:db_password],
151
+ :server_debian_password => options[:db_password],
152
+ :service_name => "mysql",
153
+ :basedir => "/usr",
154
+ :data_dir => "/var/lib/mysql",
155
+ :root_group => "root",
156
+ :mysqladmin_bin => "/usr/bin/mysqladmin",
157
+ :mysql_bin => "/usr/bin/mysql",
158
+ :conf_dir => "/etc/mysql",
159
+ :confd_dir => "/etc/mysql/conf.d",
160
+ :socket => "/var/run/mysqld/mysqld.sock",
161
+ :pid_file => "/var/run/mysqld/mysqld.pid",
162
+ :grants_path => "/etc/mysql/grants.sql"
163
+ }
164
+ end
165
+
166
+ def authorization_config
167
+ {
168
+ sudo: {
169
+ users: [app_user],
170
+ passwordless: true
171
+ }
172
+ }
173
+ end
174
+
175
+ def common_config
176
+ cfg = {
177
+ nginx: {
178
+ dir: "/etc/nginx",
179
+ log_dir: "/var/log/nginx",
180
+ binary: "/usr/sbin/nginx",
181
+ user: "www-data",
182
+ pid: "/var/run/nginx.pid",
183
+ worker_connections: "1024"
184
+ },
185
+ git: {
186
+ prefix: "/usr/local"
187
+ },
188
+ }
189
+ cfg[:mysql] = mysql_config if mysql?
190
+ cfg[:postgresql] = postgresql_config if postgresql?
191
+ cfg
192
+ end
193
+
194
+ def chef_config
195
+ common_config.merge({
196
+ authorization: authorization_config,
197
+ rbenv: rbenv_config(app_user)
198
+ })
199
+ end
200
+
201
+ def config_json
202
+ chef_config.merge({
203
+ run_list: run_list
204
+ })
205
+ end
206
+
207
+ def vagrant_config
208
+ # common_config.merge({
209
+ # rbenv: rbenv_config('vagrant')
210
+ # })
211
+ chef_config
212
+ end
213
+
214
+ def run_list
215
+ [
216
+ "apt",
217
+ "chef-solo-search",
218
+ "locale",
219
+ "users::sysadmins",
220
+ "sudo",
221
+ "runit",
222
+ mysql? ? "mysql::server" : nil,
223
+ postgresql? ? "postgresql::server" : nil,
224
+ "imagemagick",
225
+ "ruby_build",
226
+ "rbenv::user",
227
+ "nginx::repo",
228
+ "nginx",
229
+ "git"
230
+ ].compact
231
+ end
232
+
233
+ def user_json
234
+ {
235
+ id: app_user,
236
+ comment: "Application User",
237
+ ssh_keys: [File.read(options[:ssh_pub_key])],
238
+ groups: ["sysadmin", "sudo", "staff"],
239
+ shell: "/bin/bash"
240
+ }
241
+ end
242
+
243
+
244
+ def rbenv_config(user)
245
+ {
246
+ user_installs: [{
247
+ user: user,
248
+ rubies: [ options[:ruby] ],
249
+ global: options[:ruby],
250
+ environment: { CFLAGS: "-march=native -O2 -pipe" },
251
+ gems: {
252
+ options[:ruby] => [{name: "bundler", version: "1.3.5"}]
253
+ }
254
+ }]
255
+ }
256
+ end
257
+ end
258
+ end
@@ -1,3 +1,3 @@
1
1
  module Pushapp
2
- VERSION = '0.0.6'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'thor'
22
+ spec.add_dependency 'awesome_print'
22
23
 
23
24
  spec.add_development_dependency 'bundler', '~> 1.3'
24
25
  spec.add_development_dependency 'rake'
@@ -0,0 +1,17 @@
1
+ site 'http://community.opscode.com/api/v1'
2
+
3
+ cookbook "apt"
4
+ <% if options[:database] == 'mysql' %>
5
+ cookbook "mysql", {}
6
+ <% elsif options[:database] == 'postgresql' %>
7
+ cookbook "postgresql", {}
8
+ <% end %>
9
+ cookbook "sudo", {:gihub => "patcon/chef-sudo"}
10
+ cookbook "locale", {:github => "yury/hw-chef-locale"}
11
+ cookbook "imagemagick"
12
+ cookbook "chef-solo-search", {:github => "edelight/chef-solo-search"}
13
+ cookbook "users"
14
+ cookbook "ruby_build", {:github=>"fnichol/chef-ruby_build", :ref=>"v0.7.2"}
15
+ cookbook "rbenv", {:github=>"fnichol/chef-rbenv"}
16
+ cookbook "nginx", {:github=> "opscode-cookbooks/nginx"}
17
+ cookbook "git", {}
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ # -*- mode: ruby -*-
4
+ # vi: set ft=ruby :
5
+
6
+ Vagrant::Config.run do |config|
7
+
8
+ config.vm.box = "<%= options[:vagrant_box] %>"
9
+ config.vm.box_url = "<%= options[:vagrant_box_url] %>"
10
+ # config.ssh.forward_agent = true
11
+
12
+ config.vm.provision :chef_solo do |chef|
13
+ chef.cookbooks_path = ["cookbooks"]
14
+ chef.data_bags_path = "data_bags"
15
+ <% run_list.each do |recipe| -%>
16
+ chef.add_recipe '<%= recipe %>'
17
+ <% end -%>
18
+ chef.json = <%= AwesomePrint::Inspector.new(plain: true, index: false, indent: -2).awesome(vagrant_config).gsub("\n", "\n ") %>
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ .vagrant
2
+ tmp
3
+ cookbooks
@@ -0,0 +1 @@
1
+ <%= JSON.pretty_generate(config_json) %>
@@ -0,0 +1,70 @@
1
+ # Sample configuration file for Unicorn (not Rack)
2
+ #
3
+ # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
4
+ # documentation.
5
+ env ||= ENV["RACK_ENV"] || "development"
6
+ root = File.expand_path('../..', __FILE__)
7
+ # Use at least one worker per core if you're on a dedicated server,
8
+ # more will usually help for _short_ waits on databases/caches.
9
+ worker_processes 4
10
+
11
+ # Help ensure your application will always spawn in the symlinked
12
+ # "current" directory that Capistrano sets up.
13
+ working_directory root # available in 0.94.0+
14
+
15
+ # listen on both a Unix domain socket and a TCP port,
16
+ # we use a shorter backlog for quicker failover when busy
17
+ listen "/tmp/unicorn.<%= app_name %>.#{app_env}.sock", :backlog => 64
18
+
19
+ # nuke workers after 60 seconds (the default)
20
+ timeout 60
21
+
22
+ # feel free to point this anywhere accessible on the filesystem
23
+ pid "#{root}/tmp/pids/unicorn.pid"
24
+
25
+ # some applications/frameworks log to stderr or stdout, so prevent
26
+ # them from going to /dev/null when daemonized here:
27
+ stderr_path "#{root}/log/unicorn.stderr.log"
28
+ stdout_path "#{root}/log/unicorn.stdout.log"
29
+
30
+ # combine REE with "preload_app true" for memory savings
31
+ # http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
32
+ preload_app true
33
+ GC.respond_to?(:copy_on_write_friendly=) and
34
+ GC.copy_on_write_friendly = true
35
+
36
+ before_fork do |server, worker|
37
+ Kernel.rand
38
+ # the following is highly recomended for Rails + "preload_app true"
39
+ # as there's no need for the master process to hold a connection
40
+ defined?(ActiveRecord::Base) and
41
+ ActiveRecord::Base.connection.disconnect!
42
+
43
+ # The following is only recommended for memory/DB-constrained
44
+ # installations. It is not needed if your system can house
45
+ # twice as many worker_processes as you have configured.
46
+ #
47
+ # # This allows a new master process to incrementally
48
+ # # phase out the old master process with SIGTTOU to avoid a
49
+ # # thundering herd (especially in the "preload_app false" case)
50
+ # # when doing a transparent upgrade. The last worker spawned
51
+ # # will then kill off the old master process with a SIGQUIT.
52
+ old_pid = "#{server.config[:pid]}.oldbin"
53
+ if old_pid != server.pid
54
+ begin
55
+ sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
56
+ Process.kill(sig, File.read(old_pid).to_i)
57
+ rescue Errno::ENOENT, Errno::ESRCH
58
+ end
59
+ end
60
+ #
61
+ # # *optionally* throttle the master from forking too quickly by sleeping
62
+ sleep 1
63
+ end
64
+
65
+ after_fork do |server, worker|
66
+ Kernel.rand
67
+ # the following is *required* for Rails + "preload_app true",
68
+ defined?(ActiveRecord::Base) and
69
+ ActiveRecord::Base.establish_connection
70
+ end
@@ -0,0 +1,40 @@
1
+ upstream <%= app_name %>-unicorn {
2
+ server unix:/tmp/unicorn.<%= app_name %>.<%= app_env %>.sock fail_timeout=0;
3
+ }
4
+
5
+ server {
6
+ listen <%= options[:listen] %>;
7
+ server_name www.<%= app_host %>;
8
+ rewrite ^(.*) http://<%= app_host %>$1 permanent;
9
+ }
10
+
11
+ server {
12
+ listen <%= options[:listen] %>;
13
+ server_name <%= app_host %>;
14
+
15
+ root <%=app_path%>/public;
16
+
17
+ location /assets {
18
+ location ~ \.(js|css|otf|ttf|eot|woff|svg)$ {
19
+ gzip_static on; # to serve pre-gzipped version
20
+ }
21
+
22
+ expires max;
23
+ add_header Cache-Control public;
24
+ }
25
+
26
+ try_files $uri/index.html $uri.html $uri @app;
27
+
28
+ location @app {
29
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
30
+ proxy_set_header Host $http_host;
31
+ add_header X-UA-Compatible IE=Edge,chrome=1;
32
+ add_header imagetoolbar no;
33
+ proxy_redirect off;
34
+ proxy_pass http://<%= app_name %>-unicorn;
35
+ }
36
+
37
+ error_page 500 502 503 504 /500.html;
38
+ client_max_body_size 4G;
39
+ keepalive_timeout 10;
40
+ }
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+
3
+ if [ -f tmp/pids/unicorn.pid ]; then
4
+ unicorn_pid_file=tmp/pids/unicorn.pid
5
+ # Someone restarted the master; wait for the new master to exit.
6
+ PID=`cat $unicorn_pid_file`
7
+
8
+ while kill -0 $PID; do
9
+ sleep 2
10
+ PID=`cat $unicorn_pid_file`
11
+ done
12
+
13
+ # If we get here, the master has exited, either because someone restarted
14
+ # it again (in which case there's already a new master running), or
15
+ # it died for real (in which case we'll need to start a new process).
16
+ # The sleep above is a tradeoff between polling load and mimizing the
17
+ # restart delay when the master dies for real (which should hopefully be
18
+ # rare).
19
+ rm $unicorn_pid_file
20
+ else
21
+ # Run the unicorn master process (this won't return until it exits).
22
+ bundle exec unicorn -E $RAILS_ENV -c config/unicorn.rb
23
+ fi
@@ -0,0 +1 @@
1
+ <%= JSON.pretty_generate(user_json) %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pushapp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yury Korolev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-02 00:00:00.000000000 Z
11
+ date: 2013-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: awesome_print
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +99,7 @@ files:
85
99
  - lib/pushapp/cli.rb
86
100
  - lib/pushapp/commands.rb
87
101
  - lib/pushapp/config.rb
102
+ - lib/pushapp/generators.rb
88
103
  - lib/pushapp/git.rb
89
104
  - lib/pushapp/hook.rb
90
105
  - lib/pushapp/logger.rb
@@ -99,12 +114,20 @@ files:
99
114
  - lib/pushapp/tasks/upstart.rb
100
115
  - lib/pushapp/version.rb
101
116
  - pushapp.gemspec
117
+ - templates/Cheffile.erb
118
+ - templates/Vagrantfile.erb
119
+ - templates/chef.gitignore
102
120
  - templates/config.rb.erb
103
121
  - templates/hook/base.erb
104
122
  - templates/hook/bundler.erb
105
123
  - templates/hook/git-reset.erb
106
124
  - templates/hook/setup.erb
107
125
  - templates/hook/tasks.erb
126
+ - templates/node.json.erb
127
+ - templates/unicorn.rb.erb
128
+ - templates/unicorn_nginx.conf.erb
129
+ - templates/unicorn_upstart.erb
130
+ - templates/user.json.erb
108
131
  - test/fixtures/empty_config.rb
109
132
  - test/pushapp/cli_test.rb
110
133
  - test/pushapp/config_test.rb