vhost_generator 0.2.2 → 0.3.0

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.
@@ -94,8 +94,11 @@ class ForemanExportApplication
94
94
  '# Default: web (must have entry of that name in Procfile)',
95
95
  lambda { |value| config.process_type = value }],
96
96
  ['-G', '--generator=GENERATOR',
97
- '# Default: nginx (only supported for now)',
97
+ '# Default: "nginx" (try "apache" too)',
98
98
  lambda { |value| config.generator = value }],
99
+ ['-O', '--generator-options=OPTIONS',
100
+ '# Comma-separated list of key=value',
101
+ lambda { |value| config.generator_options = value }],
99
102
  ['-N', '--dry-run', lambda { |value| config.dry_run = true }],
100
103
  ['-R', '--stop-start-service',
101
104
  '# Starts and stops APP service (may not work everywhere)',
@@ -174,9 +177,14 @@ class ForemanExportApplication
174
177
  Array(Shellwords.escape("#{target}/#{app}") + "-*.conf")
175
178
  commands << %w(sudo bundle exec foreman export) +
176
179
  escape(argv + foreman_flags)
177
- commands << %w(sudo service) + escape(app) + %w(start)
178
- commands << ['echo',
179
- '"Finished, now open your browser and see if all works."']
180
+ message = 'Finished, now '
181
+ if config.service
182
+ commands << %w(sudo service) + escape(app) + %w(start)
183
+ else
184
+ message = "start the #{escape(app)} service, "
185
+ end
186
+ message << "open your browser and see if everything works."
187
+ commands << ['echo', '"' + message + '"']
180
188
  self
181
189
  end
182
190
 
@@ -185,12 +193,14 @@ class ForemanExportApplication
185
193
  attr_reader :config, :argv, :commands
186
194
 
187
195
  def generator_flags(flags=Array.new)
196
+ flags << '-a' << config.app if config.app
188
197
  flags << '-f' << config.static_folder if config.static_folder
189
198
  flags << '-l' << config.server_ports if config.server_ports
190
199
  flags << '-s' << config.server_names if config.server_names
191
200
  flags << '-p' << config.instance_ports if config.instance_ports
192
201
  flags << '-g' << config.generator if config.generator
193
- flags << '-o' << "upstream=#{app}" if config.generator == 'nginx' && app
202
+ flags << '-o' << config.generator_options if config.generator_options
203
+ flags
194
204
  end
195
205
 
196
206
  def foreman_flags(flags=Array.new)
@@ -203,6 +213,7 @@ class ForemanExportApplication
203
213
  flags << '-c' << config.concurrency if config.concurrency
204
214
  flags << '-f' << config.procfile if config.procfile
205
215
  flags << '-d' << config.root if config.root
216
+ flags
206
217
  end
207
218
 
208
219
  def app
@@ -217,8 +228,18 @@ class ForemanExportApplication
217
228
  argv[1] # eg. /etc/init
218
229
  end
219
230
 
231
+ def vhost_dir
232
+ if config.generator == 'nginx'
233
+ '/etc/nginx/sites-enabled'
234
+ elsif config.generator == 'apache'
235
+ '/etc/apache2/sites-enabled'
236
+ else
237
+ raise RuntimeError, "Can't guess vhost_dir for generator=#{config.generator}"
238
+ end
239
+ end
240
+
220
241
  def vhost_config
221
- "/etc/#{service}/sites-enabled/rails-#{app}.conf"
242
+ "#{vhost_dir}/vhost-#{app}.conf"
222
243
  end
223
244
 
224
245
  def escape(args)
@@ -26,7 +26,8 @@ Feature: Wrap "foreman export"
26
26
  -L, --server-ports=PORTS # Default: 80
27
27
  -S, --server-names=NAMES # Default: localhost
28
28
  -K, --foreman-process-type=TYPE # Default: web (must have entry of that name in Procfile)
29
- -G, --generator=GENERATOR # Default: nginx (only supported for now)
29
+ -G, --generator=GENERATOR # Default: "nginx" (try "apache" too)
30
+ -O, --generator-options=OPTIONS # Comma-separated list of key=value
30
31
  -N, --dry-run
31
32
  -R, --stop-start-service # Starts and stops APP service (may not work everywhere)
32
33
 
@@ -39,10 +40,10 @@ Feature: Wrap "foreman export"
39
40
  clock: ....
40
41
  web: bundle exec webserver -p $PORT
41
42
  """
42
- When I run `bundle exec foreman-export-vhost upstart /etc/init -a MYAPP -u MYUSER -p 6000 -c clock=1,web=2 -L 80,81 -S localhost,myapp.com -K web -G nginx -N -R`
43
+ When I run `bundle exec foreman-export-vhost upstart /etc/init -f Procfile -a MYAPP -u MYUSER -p 6000 -c clock=1,web=2 -L 80,81 -S localhost,myapp.com -K web -G nginx -O assets_expire_in=15d -N -R`
43
44
  Then the output should match:
44
45
  """
45
- bundle exec foreman run vhost-generator -f /.*/public -l 80,81 -s localhost,myapp.com -p 6100,6101 -g nginx -o upstream=MYAPP | sudo tee /etc/nginx/sites-enabled/rails-MYAPP.conf
46
+ bundle exec foreman run vhost-generator -a MYAPP -f /.*/public -l 80,81 -s localhost,myapp.com -p 6100,6101 -g nginx -o assets_expire_in\\=15d \| sudo tee /etc/nginx/sites-enabled/vhost-MYAPP.conf
46
47
  """
47
48
  And the output should contain:
48
49
  """
@@ -57,6 +58,6 @@ Feature: Wrap "foreman export"
57
58
  And the output should contain:
58
59
  """
59
60
  sudo service MYAPP start
60
- echo "Finished, now open your browser and see if all works."
61
+ echo "Finished, now open your browser and see if everything works."
61
62
  # Now, try to run this script again without the --dry-run switch!
62
63
  """
@@ -5,11 +5,11 @@ Feature: Output nginx configuration file
5
5
  I want to output a nginx virtualhost configuration.
6
6
 
7
7
  Scenario: using command-line options
8
- When I run `bundle exec vhost-generator -g nginx -o upstream=myupstream -f html -l 80,81 -s localhost,my.server -p 5000,5001,5002 -r /myapp`
8
+ When I run `bundle exec vhost-generator -g nginx -o assets_expire_in=15d -a testapp -f html -l 80,81 -s localhost,my.server -p 5000,5001,5002 -r /myapp`
9
9
  Then the output should match /FILE GENERATED BY.*EDIT AT YOUR OWN RISK/
10
10
  And the output should contain:
11
11
  """
12
- upstream myupstream {
12
+ upstream testapp {
13
13
  server localhost:5000 fail_timeout=0;
14
14
  server localhost:5001 fail_timeout=0;
15
15
  server localhost:5002 fail_timeout=0;
@@ -34,14 +34,14 @@ Feature: Output nginx configuration file
34
34
  proxy_set_header X-Forwarded-Proto $scheme;
35
35
  proxy_set_header Host $http_host;
36
36
  proxy_redirect off;
37
- proxy_pass http://myupstream;
37
+ proxy_pass http://testapp;
38
38
  }
39
39
  """
40
40
  And the output should contain:
41
41
  """
42
42
  location /myapp/assets {
43
43
  gzip_static on; # to serve pre-gzipped version
44
- expires 60d;
44
+ expires 15d;
45
45
  add_header Cache-Control public;
46
46
  }
47
47
  """
@@ -55,7 +55,8 @@ Feature: Output nginx configuration file
55
55
 
56
56
  Scenario: using environment variables
57
57
  When I set env variable "GENERATOR" to "nginx"
58
- And I set env variable "GENERATOR_OPTIONS" to "upstream=myupstream"
58
+ And I set env variable "GENERATOR_OPTIONS" to "assets_expire_in=15d"
59
+ And I set env variable "APPLICATION" to "testapp"
59
60
  And I set env variable "STATIC_FOLDER" to "html"
60
61
  And I set env variable "SERVER_PORTS" to "80,81"
61
62
  And I set env variable "SERVER_NAMES" to "localhost,my.server"
@@ -65,7 +66,7 @@ Feature: Output nginx configuration file
65
66
  Then the output should match /FILE GENERATED BY.*EDIT AT YOUR OWN RISK/
66
67
  And the output should contain:
67
68
  """
68
- upstream myupstream {
69
+ upstream testapp {
69
70
  server localhost:5000 fail_timeout=0;
70
71
  server localhost:5001 fail_timeout=0;
71
72
  server localhost:5002 fail_timeout=0;
@@ -90,14 +91,14 @@ Feature: Output nginx configuration file
90
91
  proxy_set_header X-Forwarded-Proto $scheme;
91
92
  proxy_set_header Host $http_host;
92
93
  proxy_redirect off;
93
- proxy_pass http://myupstream;
94
+ proxy_pass http://testapp;
94
95
  }
95
96
  """
96
97
  And the output should contain:
97
98
  """
98
99
  location /myapp/assets {
99
100
  gzip_static on; # to serve pre-gzipped version
100
- expires 60d;
101
+ expires 15d;
101
102
  add_header Cache-Control public;
102
103
  }
103
104
  """
@@ -8,5 +8,5 @@ Feature: Output program version
8
8
  When I run `bundle exec vhost-generator --version`
9
9
  Then it should pass with:
10
10
  """
11
- vhost-generator, version 0.2.2
11
+ vhost-generator, version 0.3.0
12
12
  """
@@ -33,6 +33,9 @@ module VhostGenerator
33
33
  end
34
34
 
35
35
  def handle_env(env)
36
+ if app = env['APPLICATION']
37
+ config.application = app
38
+ end
36
39
  if path = env['STATIC_FOLDER']
37
40
  config.static_folder = path
38
41
  end
@@ -90,6 +93,9 @@ module VhostGenerator
90
93
 
91
94
  def application_options
92
95
  [
96
+ ['-a', '--application APPLICATION',
97
+ %q{Unique name of your application (e.g. myapp)},
98
+ lambda { |value| config.application = value }],
93
99
  ['-f', '--static-folder STATIC_FOLDER',
94
100
  %q{Path of your application's static folder (e.g. public/)},
95
101
  lambda { |value| config.static_folder = value }],
@@ -0,0 +1,64 @@
1
+ require 'shellwords'
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ namespace :vhost do
5
+ _cset(:vhost_port) { 5000 }
6
+ _cset(:vhost_env) { nil }
7
+ _cset(:vhost_concurrency) { nil }
8
+ _cset(:vhost_procfile) { 'Procfile' }
9
+ _cset(:vhost_server_ports) { '80' }
10
+ _cset(:vhost_server_names) { 'localhost' }
11
+ _cset(:vhost_process) { abort "Please specify the foreman process type, set :vhost_process, 'web' (if you have 'web' in your Procfile)" }
12
+ _cset(:vhost_generator) { abort "Please specify the target web server, set :vhost_generator, 'nginx' (or 'apache')" }
13
+ _cset(:vhost_generator_options) { nil }
14
+
15
+ desc <<-DESC
16
+ Runs the "foreman-export-vhost" command to manage a foreman-enabled \
17
+ application using upstart and generate nginx or apache virtualhost configuration \
18
+ file to serve it to web clients.
19
+
20
+ You can override any of these defaults by setting the variables shown below.
21
+
22
+ set :vhost_port, #{vhost_port.inspect}
23
+ set :vhost_env, #{vhost_env.inspect}
24
+ set :vhost_concurrency, #{vhost_concurrency.inspect}
25
+ set :vhost_procfile, #{vhost_procfile.inspect}
26
+ set :vhost_server_ports, #{vhost_server_ports.inspect}
27
+ set :vhost_server_names, #{vhost_server_names.inspect}
28
+ set :vhost_generator,
29
+ set :vhost_generator_options, #{vhost_generator_options.inspect}
30
+ set :vhost_process
31
+ DESC
32
+ task :export do
33
+ cmdline = "foreman-export-vhost upstart /etc/init -u $USER"
34
+ cmdline << " -a #{application.shellescape}"
35
+ cmdline << " -p #{String(vhost_port).shellescape}"
36
+ cmdline << " -e #{vhost_env.shellescape}" if vhost_env
37
+ cmdline << " -f #{vhost_procfile.shellescape}" if vhost_procfile
38
+ cmdline << " -c #{vhost_concurrency.shellescape}" if vhost_concurrency
39
+ cmdline << " -K #{vhost_process.shellescape}"
40
+ cmdline << " -L #{vhost_server_ports.shellescape}" if vhost_server_ports
41
+ cmdline << " -S #{vhost_server_names.shellescape}" if vhost_server_names
42
+ cmdline << " -G #{vhost_generator.shellescape}" if vhost_generator
43
+ cmdline << " -O #{vhost_generator_options.shellescape}" if vhost_generator_options
44
+ run "cd #{release_path} && #{sudo} RAILS_ENV=#{rails_env} bundle exec #{cmdline}"
45
+ end
46
+
47
+ before 'deploy:create_symlink', 'vhost:export'
48
+ end
49
+
50
+ # Each application is turned into an upstart service by 'foreman export'.
51
+ namespace :deploy do
52
+ task :start do
53
+ run "#{sudo} service #{application.shellescape} start"
54
+ end
55
+
56
+ task :stop do
57
+ run "#{sudo} service #{application.shellescape} stop"
58
+ end
59
+
60
+ task :restart, :roles => :app, :except => { :no_release => true } do
61
+ run "#{sudo} service #{application.shellescape} restart"
62
+ end
63
+ end
64
+ end
@@ -34,7 +34,7 @@ module VhostGenerator
34
34
  args << '-s' << @config.server_names.join(',')
35
35
  args << '-p' << @config.instance_ports.join(',')
36
36
  args << '-r' << @config.relative_root
37
- args << '-g' << 'nginx' # FIXME use @config.generator when real registry
37
+ args << '-g' << @config.generator
38
38
  options = @config.generator_options.collect {|k,v| "#{k}=#{v}" }
39
39
  args << '-o' << options.join(',')
40
40
  args
@@ -9,7 +9,9 @@ module VhostGenerator
9
9
  attr_reader :cfg, :options
10
10
  def initialize(cfg, options={})
11
11
  @cfg = cfg
12
- @options = OpenStruct.new(default_options.merge(options)).freeze
12
+ @options = OpenStruct.new(default_options.merge(options))
13
+ @options.upstream ||= cfg.application
14
+ @options.freeze
13
15
  end
14
16
 
15
17
  def render
@@ -20,7 +22,7 @@ module VhostGenerator
20
22
 
21
23
  def default_options
22
24
  Hash[ 'client_max_body_size' => '4G', 'keepalive_timeout' => '10',
23
- 'assets_expire_in' => '60d', 'upstream' => 'appservers' ].freeze
25
+ 'assets_expire_in' => '60d' ].freeze
24
26
  end
25
27
 
26
28
  private
@@ -1,3 +1,3 @@
1
1
  module VhostGenerator
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -8,14 +8,16 @@ module VhostGenerator
8
8
  # +env+ or +cmdline+ needed to render the configuration template.
9
9
  #
10
10
  class VhostConfiguration
11
- attr_reader :static_folder, :server_ports, :server_names,
11
+ attr_reader :application, :static_folder, :server_ports, :server_names,
12
12
  :instance_ports, :relative_root,
13
13
  :generator, :generator_options
14
14
  attr_accessor :cmdline
15
15
 
16
- def initialize(static_folder='public', server_ports='80',
17
- server_names='localhost', instance_ports='', relative_root='/',
18
- generator='nginx', generator_options='', cmdline=nil)
16
+ def initialize(application='myapp', static_folder='public',
17
+ server_ports='80', server_names='localhost', instance_ports='',
18
+ relative_root='/', generator='nginx', generator_options='',
19
+ cmdline=nil)
20
+ self.application = application
19
21
  self.static_folder = static_folder
20
22
  self.server_ports = server_ports
21
23
  self.server_names = server_names
@@ -26,6 +28,12 @@ module VhostGenerator
26
28
  self.generator_options = generator_options
27
29
  end
28
30
 
31
+ def application=(app)
32
+ app = String(app).strip.gsub(/\s+/, '_') # avoid blanks in app name.
33
+ raise ArgumentError, "application is required" unless app && !app.empty?
34
+ @application = app
35
+ end
36
+
29
37
  def static_folder=(folder)
30
38
  @static_folder = File.expand_path(folder)
31
39
  end
@@ -47,7 +55,8 @@ module VhostGenerator
47
55
  end
48
56
 
49
57
  def generator=(name)
50
- @generator = generator_for(name)
58
+ generator_for(name) # ensure generator exists
59
+ @generator = name
51
60
  end
52
61
 
53
62
  def generator_options=(options)
@@ -59,7 +68,7 @@ module VhostGenerator
59
68
  end
60
69
 
61
70
  def output
62
- self.generator.new(self, self.generator_options).render
71
+ generator_for(self.generator).new(self, self.generator_options).render
63
72
  end
64
73
 
65
74
  protected
@@ -7,6 +7,7 @@ describe VhostGenerator::Application do
7
7
  before { subject.config = config }
8
8
 
9
9
  options = Hash[
10
+ 'application' => 'APPLICATION',
10
11
  'static_folder' => 'STATIC_FOLDER',
11
12
  'server_ports' => 'SERVER_PORTS',
12
13
  'server_names' => 'SERVER_NAMES',
@@ -7,6 +7,7 @@ describe VhostGenerator::Application do
7
7
  before { subject.config = config }
8
8
 
9
9
  options = Hash[
10
+ 'application' => %w(-a --application),
10
11
  'static_folder' => %w(-f --static-folder),
11
12
  'server_ports' => %w(-l --listen),
12
13
  'server_names' => %w(-s --server-name),
@@ -1,6 +1,24 @@
1
1
  require 'vhost_generator/vhost_configuration'
2
2
 
3
3
  describe VhostGenerator::VhostConfiguration do
4
+ describe "#application" do
5
+ it "is 'myapp' by default" do
6
+ expect(subject.application).to eql('myapp')
7
+ end
8
+
9
+ it "is normalized on the fly" do
10
+ expect {
11
+ subject.application = ' my sanitized app '
12
+ }.to change(subject, :application).to('my_sanitized_app')
13
+ end
14
+
15
+ it "is required" do
16
+ expect {
17
+ subject.application = ''
18
+ }.to raise_error(ArgumentError, /required/)
19
+ end
20
+ end
21
+
4
22
  describe "#static_folder" do
5
23
  it "is 'public/' by default" do
6
24
  expect(subject.static_folder).to eql(File.expand_path('public'))
@@ -84,12 +102,12 @@ describe VhostGenerator::VhostConfiguration do
84
102
  expect(subject.generator).to be
85
103
  end
86
104
 
87
- it "is resolved into a generator plugin" do
105
+ it "is set when a generator plugin exists" do
88
106
  generator = double('generator')
89
107
  subject.send(:registry).merge!('test' => generator)
90
108
  expect {
91
109
  subject.generator = 'test'
92
- }.to change(subject, :generator).to generator
110
+ }.to change(subject, :generator).to 'test'
93
111
  end
94
112
 
95
113
  it "complains when trying to set invalid values" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vhost_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-02 00:00:00.000000000 Z
12
+ date: 2012-10-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -100,6 +100,7 @@ files:
100
100
  - features/version.feature
101
101
  - lib/vhost_generator.rb
102
102
  - lib/vhost_generator/application.rb
103
+ - lib/vhost_generator/capistrano.rb
103
104
  - lib/vhost_generator/cmdline_builder.rb
104
105
  - lib/vhost_generator/nginx_generator.rb
105
106
  - lib/vhost_generator/version.rb
@@ -126,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
127
  version: '0'
127
128
  segments:
128
129
  - 0
129
- hash: 138630257
130
+ hash: 1022995219
130
131
  required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  none: false
132
133
  requirements:
@@ -135,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  version: '0'
136
137
  segments:
137
138
  - 0
138
- hash: 138630257
139
+ hash: 1022995219
139
140
  requirements: []
140
141
  rubyforge_project:
141
142
  rubygems_version: 1.8.23