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.
- data/bin/foreman-export-vhost +27 -6
- data/features/foreman-export-vhost.feature +5 -4
- data/features/output-nginx.feature +9 -8
- data/features/version.feature +1 -1
- data/lib/vhost_generator/application.rb +6 -0
- data/lib/vhost_generator/capistrano.rb +64 -0
- data/lib/vhost_generator/cmdline_builder.rb +1 -1
- data/lib/vhost_generator/nginx_generator.rb +4 -2
- data/lib/vhost_generator/version.rb +1 -1
- data/lib/vhost_generator/vhost_configuration.rb +15 -6
- data/spec/application_env_spec.rb +1 -0
- data/spec/application_options_spec.rb +1 -0
- data/spec/vhost_configuration_spec.rb +20 -2
- metadata +5 -4
data/bin/foreman-export-vhost
CHANGED
@@ -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 (
|
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
|
-
|
178
|
-
|
179
|
-
|
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' <<
|
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
|
-
"
|
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 (
|
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
|
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
|
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
|
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
|
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://
|
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
|
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 "
|
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
|
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://
|
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
|
101
|
+
expires 15d;
|
101
102
|
add_header Cache-Control public;
|
102
103
|
}
|
103
104
|
"""
|
data/features/version.feature
CHANGED
@@ -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' <<
|
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))
|
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'
|
25
|
+
'assets_expire_in' => '60d' ].freeze
|
24
26
|
end
|
25
27
|
|
26
28
|
private
|
@@ -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(
|
17
|
-
|
18
|
-
generator='nginx', generator_options='',
|
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
|
-
|
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
|
@@ -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
|
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
|
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.
|
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-
|
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:
|
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:
|
139
|
+
hash: 1022995219
|
139
140
|
requirements: []
|
140
141
|
rubyforge_project:
|
141
142
|
rubygems_version: 1.8.23
|