nginx_stage 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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +3 -0
  4. data/CHANGELOG.md +199 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +19 -0
  8. data/Rakefile +36 -0
  9. data/bin/node +15 -0
  10. data/bin/ood_ruby +38 -0
  11. data/bin/python +15 -0
  12. data/bin/ruby +15 -0
  13. data/lib/nginx_stage/application.rb +125 -0
  14. data/lib/nginx_stage/configuration.rb +418 -0
  15. data/lib/nginx_stage/errors.rb +46 -0
  16. data/lib/nginx_stage/generator.rb +139 -0
  17. data/lib/nginx_stage/generator_helpers.rb +68 -0
  18. data/lib/nginx_stage/generators/app_clean_generator.rb +38 -0
  19. data/lib/nginx_stage/generators/app_config_generator.rb +101 -0
  20. data/lib/nginx_stage/generators/app_list_generator.rb +24 -0
  21. data/lib/nginx_stage/generators/app_reset_generator.rb +54 -0
  22. data/lib/nginx_stage/generators/nginx_clean_generator.rb +61 -0
  23. data/lib/nginx_stage/generators/nginx_list_generator.rb +22 -0
  24. data/lib/nginx_stage/generators/nginx_process_generator.rb +47 -0
  25. data/lib/nginx_stage/generators/nginx_show_generator.rb +48 -0
  26. data/lib/nginx_stage/generators/pun_config_generator.rb +102 -0
  27. data/lib/nginx_stage/pid_file.rb +37 -0
  28. data/lib/nginx_stage/socket_file.rb +51 -0
  29. data/lib/nginx_stage/user.rb +75 -0
  30. data/lib/nginx_stage/version.rb +4 -0
  31. data/lib/nginx_stage/views/app_config_view.rb +42 -0
  32. data/lib/nginx_stage/views/pun_config_view.rb +144 -0
  33. data/lib/nginx_stage.rb +133 -0
  34. data/nginx_stage.gemspec +24 -0
  35. data/sbin/nginx_stage +7 -0
  36. data/share/nginx_stage_example.yml +166 -0
  37. data/templates/app.conf.erb +14 -0
  38. data/templates/pun.conf.erb +79 -0
  39. data/test/minitest_helper.rb +4 -0
  40. data/test/test_nginx_stage.rb +11 -0
  41. metadata +132 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fa24a601f96e88b6ce80144643c1050d40610662
4
+ data.tar.gz: c57cffe3cdd786e2871920b6867e0707e7a25864
5
+ SHA512:
6
+ metadata.gz: e139fd36c641d1a715afab850616b5aeb69d5a4241c06eb095317ee6007da4b5b2ed823a7637c2117b629be2ce7b7c007543b577813881e26931f5ff32bcf017
7
+ data.tar.gz: 9e102f6f33a6b43bfb5bb5d5b354061e415cae2074472ae375fa78ec2e2dbd9ca9a9a57fb2d3a43fec6a6028df729c6428d789b7d51282a633703cb0cfc56cdb
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,199 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.3.0] - 2017-10-30
10
+ ### Added
11
+ - Added a confirmation page when attempting to restart PUN due to discovery of
12
+ uninitialized app. [#20](https://github.com/OSC/nginx_stage/issues/20)
13
+ - Added configuration option to modify regular expression used to validate user
14
+ name. [#19](https://github.com/OSC/nginx_stage/issues/19)
15
+ - Added support to specify custom NGINX environment under `/etc/ood/profile`.
16
+ [#24](https://github.com/OSC/nginx_stage/pull/24)
17
+
18
+ ### Changed
19
+ - Default regex for validating username now includes common email symbols.
20
+ [#19](https://github.com/OSC/nginx_stage/issues/19)
21
+ - Moved configuration location to `/etc/ood/config/nginx_stage.yml`.
22
+ [#23](https://github.com/OSC/nginx_stage/pull/23)
23
+ - Modified the `CHANGELOG.md` formatting.
24
+
25
+ ### Deprecated
26
+ - Deprecating the old configuration location located underneath the app's
27
+ installation directory.
28
+
29
+ ### Fixed
30
+ - Fixed link to documentation in `README.md`.
31
+ - Updated the `LICENSE.txt` with correct information.
32
+
33
+ ## [0.2.1] - 2017-03-02
34
+ ### Removed
35
+ - Removed `%{env}` from config for better readability.
36
+
37
+ ## [0.2.0] - 2017-01-30
38
+ ### Changed
39
+ - Provide better default ruby wrapper that doesn't require modifications.
40
+
41
+ ### Removed
42
+ - Removed client-side analytics (now handled server-side).
43
+
44
+ ### Fixed
45
+ - Don't crash when config file has invalid option.
46
+
47
+ ## [0.1.0] - 2016-10-27
48
+ ### Added
49
+ - Implement nginx sendfile feature for optimal static file downloads.
50
+
51
+ ### Changed
52
+ - Made git 1.9+ a requirement for the dashboard app.
53
+
54
+ ### Fixed
55
+ - Fix for app checks under restrictive NFS permissions as `root`.
56
+ - Forgot to copy over example ruby wrapper.
57
+
58
+ ## [0.0.13] - 2016-10-11
59
+ ### Added
60
+ - Add query parameter that forces file to be downloaded by browser.
61
+
62
+ ## [0.0.12] - 2016-10-11
63
+ ### Added
64
+ - Added a download uri that serves files directly off of the filesystem.
65
+
66
+ ## [0.0.11] - 2016-09-22
67
+ ### Fixed
68
+ - Fixes/simplifications to default yaml configuration file.
69
+ - Display help msg by default if CLI called with no arguments.
70
+ - Added back javascript dependency for GA due to caching issues.
71
+
72
+ ## [0.0.10] - 2016-09-14
73
+ ### Removed
74
+ - Removed javascript dependency when setting GA dimensions.
75
+
76
+ ## [0.0.9] - 2016-08-30
77
+ ### Added
78
+ - Added timestamp (hit scope) dimension in Google Analytics.
79
+ - Added user id (user scope) dimension in Google Analytics.
80
+
81
+ ## [0.0.8] - 2016-08-09
82
+ ### Added
83
+ - Added session id tracking in Google Analytics
84
+
85
+ ### Changed
86
+ - Use wrappers for Passenger binaries (ruby/node/python), allows apps to
87
+ override system-installed binary
88
+
89
+ ### Fixed
90
+ - Moved GA to end of `<head>` tag from `<body>`.
91
+
92
+ ## [0.0.7] - 2016-06-17
93
+ ### Fixed
94
+ - Updated Google Analytics account number used in metrics reporting.
95
+
96
+ ## [0.0.6] - 2016-06-03
97
+ ### Added
98
+ - Added Python as a configuration option.
99
+ - Added Google analytics (metrics reporting required by project).
100
+ - Added `nginx_show` command (lists details of currently running PUN).
101
+ - Added `nginx_list` command (lists all users with running PUNs).
102
+ - Added `nginx_clean` command (stops all running PUNs w/ no active
103
+ connections).
104
+ - Added `app_reset` command (resets all app configs using current template).
105
+ - Added `app_list` command (lists all staged app configs).
106
+ - Added `app_clean` command (deletes all stale app configs).
107
+ - Check if user has disabled shell when starting PUN with `pun` command.
108
+
109
+ ### Changed
110
+ - Set Node.js and Python binary paths as optional.
111
+ - Uses a full URL now in PUN config for redirection when app doesn't exist.
112
+ - Changed default location for dev apps.
113
+ - Set Nginx tmp root back to local disk.
114
+ - Use local disk paths for staging location of user shared apps.
115
+ - Can create `User` object from any string-like object.
116
+
117
+ ### Fixed
118
+ - Fixed string concatenation bug.
119
+
120
+ ## [0.0.5] - 2016-04-15
121
+ ### Changed
122
+ - Refactored Configuration module to reduce duplication.
123
+ - Move config file parsing from binary to library.
124
+ - Separated paths where pun and app configs are stored for easier config
125
+ cleanup.
126
+ - Directly spawn Rails apps to keep all apps under parent process.
127
+ - Introduced/renamed possible app environments to: `dev`, `usr`, and `sys`.
128
+ - Regenerates default config file if doesn't exist or nothing set in it.
129
+ - `rake install` doesn't depend on `git` anymore.
130
+
131
+ ### Removed
132
+ - Removed unix group whitelists as this should be responsibility of apps and
133
+ file permissions (provides greater flexibility).
134
+
135
+ ### Fixed
136
+ - Set Nginx tmp root to user's home directory to allow for larger file uploads.
137
+ - Fixed crash when config file was empty.
138
+
139
+ ## [0.0.4] - 2016-04-04
140
+ ### Added
141
+ - Display user name in process information.
142
+ - Sys admins can now define configuration options in `config/nginx_stage.yml`.
143
+ - Sys admins can now define PUN environment in `bin/ood_ruby` wrapper script.
144
+
145
+ ### Changed
146
+ - Set maximum upload file size to 10 GB in nginx config.
147
+ - Uses unix group whitelists for consumers and publishers of apps.
148
+ - Use "restart" (stop + start) instead of "reload" after generating app config
149
+ (takes advantage of `Open3` for executing nginx binary).
150
+
151
+ ### Fixed
152
+ - Uses URL escaped strings for CLI arguments (security fix).
153
+ - App requests with periods in the app name now work.
154
+ - Fixed code typo in `User` class.
155
+ - `rake install` now only installs git version checked out (fixes strange
156
+ behavior with older versions).
157
+
158
+ ## [0.0.3] - 2016-02-04
159
+ ### Added
160
+ - Added `rake install` for simpler installation.
161
+ - User can now get individualized help messages corresponding to a command.
162
+
163
+ ### Changed
164
+ - Options for a command are now specified in the corresponding generator.
165
+
166
+ ### Fixed
167
+ - The `exec` call is made more secure.
168
+
169
+ ## [0.0.2] - 2016-01-20
170
+ ### Added
171
+ - Add app initialization redirect URI option `pun -app-init-uri` if app not
172
+ found by nginx.
173
+ - Added `nginx` subcommand for easier control of nginx process.
174
+
175
+ ### Changed
176
+ - Sanitize user input from command line.
177
+ - Refactoring, cleanup internal configuration code making it more readable.
178
+
179
+ ## 0.0.1 - 2016-01-14
180
+ ### Added
181
+ - Initial release
182
+
183
+ [Unreleased]: https://github.com/OSC/nginx_stage/compare/v0.3.0...HEAD
184
+ [0.3.0]: https://github.com/OSC/nginx_stage/compare/v0.2.1...v0.3.0
185
+ [0.2.1]: https://github.com/OSC/nginx_stage/compare/v0.2.0...v0.2.1
186
+ [0.2.0]: https://github.com/OSC/nginx_stage/compare/v0.1.0...v0.2.0
187
+ [0.1.0]: https://github.com/OSC/nginx_stage/compare/v0.0.13...v0.1.0
188
+ [0.0.13]: https://github.com/OSC/nginx_stage/compare/v0.0.12...v0.0.13
189
+ [0.0.12]: https://github.com/OSC/nginx_stage/compare/v0.0.11...v0.0.12
190
+ [0.0.11]: https://github.com/OSC/nginx_stage/compare/v0.0.10...v0.0.11
191
+ [0.0.10]: https://github.com/OSC/nginx_stage/compare/v0.0.9...v0.0.10
192
+ [0.0.9]: https://github.com/OSC/nginx_stage/compare/v0.0.8...v0.0.9
193
+ [0.0.8]: https://github.com/OSC/nginx_stage/compare/v0.0.7...v0.0.8
194
+ [0.0.7]: https://github.com/OSC/nginx_stage/compare/v0.0.6...v0.0.7
195
+ [0.0.6]: https://github.com/OSC/nginx_stage/compare/v0.0.5...v0.0.6
196
+ [0.0.5]: https://github.com/OSC/nginx_stage/compare/v0.0.4...v0.0.5
197
+ [0.0.4]: https://github.com/OSC/nginx_stage/compare/v0.0.3...v0.0.4
198
+ [0.0.3]: https://github.com/OSC/nginx_stage/compare/v0.0.2...v0.0.3
199
+ [0.0.2]: https://github.com/OSC/nginx_stage/compare/v0.0.1...v0.0.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nginx_stage.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016-2017 Ohio Supercomputer Center
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # nginx_stage
2
+
3
+ ![GitHub Release](https://img.shields.io/github/release/osc/nginx_stage.svg)
4
+ ![GitHub License](https://img.shields.io/github/license/osc/nginx_stage.svg)
5
+
6
+ Stages and launches the per-user NGINX (PUN) processes for individual users. It
7
+ is also responsible for staging, listing, and cleaning up web application NGINX
8
+ configuration files, as well as listing and stopping running PUNs.
9
+
10
+ For more information please visit the
11
+ [Documentation](https://osc.github.io/ood-documentation/master/infrastructure/nginx-stage.html).
12
+
13
+ ## Contributing
14
+
15
+ 1. Fork it ( https://github.com/OSC/nginx_stage/fork )
16
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
17
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
18
+ 4. Push to the branch (`git push origin my-new-feature`)
19
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require "rake/testtask"
2
+ require "yaml"
3
+
4
+ #
5
+ # Define tasks for `rake test`
6
+ #
7
+
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << "test"
10
+ end
11
+
12
+ # Set default rake task to `test`
13
+ task :default => :test
14
+
15
+ #
16
+ # Define tasks needed for `rake install`
17
+ #
18
+
19
+ PREFIX = ENV['PREFIX'] || '/opt/ood/nginx_stage'
20
+
21
+ desc <<-DESC
22
+ Install nginx_stage into env var PREFIX
23
+ Default: PREFIX=/opt/ood/nginx_stage
24
+ DESC
25
+ task :install => [:required_files] do
26
+ end
27
+
28
+ # Dynamically generate tasks for copying required files
29
+ FileList['sbin/nginx_stage', 'bin/*', 'share/*', 'templates/*.erb', 'lib/**/*.rb'].each do |source|
30
+ target = "#{PREFIX}/#{source}"
31
+ file target => [source] do
32
+ mkdir_p File.dirname(target) unless File.directory? File.dirname(target)
33
+ cp source, target
34
+ end
35
+ task :required_files => target
36
+ end
data/bin/node ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/env bash
2
+
3
+ #
4
+ # Passenger `node` wrapper script
5
+ #
6
+ # Tries to run the developer specified version of node for the requested app
7
+ # before running system default binary (specified in the `bin/ood_ruby` wrapper
8
+ # that stages the PUN)
9
+ #
10
+
11
+ if [[ -x "${PWD}/bin/node" ]]; then
12
+ exec "${PWD}/bin/node" "$@"
13
+ else
14
+ exec node "$@"
15
+ fi
data/bin/ood_ruby ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Open OnDemand Ruby wrapper script
4
+ #
5
+ # The purpose of this script is to wrap up the necessary environment for the
6
+ # per-user NGINX (PUN) processes to run under. The PUN requires the following
7
+ # software in its environment:
8
+ #
9
+ # - nginx 1.6
10
+ # - passenger 4.0
11
+ # - ruby 2.2
12
+ # - node.js 0.10
13
+ # - git 1.9
14
+ #
15
+
16
+ # Allow admin to override the environment the PUN runs in
17
+ #
18
+ NGINX_PROFILE=${NGINX_PROFILE:-/etc/ood/profile}
19
+ if [[ -f "${NGINX_PROFILE}" ]]; then
20
+ # Source in the custom environment
21
+ source "${NGINX_PROFILE}"
22
+ else
23
+ # For Software Collections 2.0
24
+ #
25
+ # 1. Read in environment variable SCL_PKGS which may be set in `sudo` call
26
+ # otherwise fallback to default software collection packages.
27
+ #
28
+ # 2. Check if Software Collections is installed, then source the defined
29
+ # package scripts.
30
+ #
31
+ SCL_PKGS=${SCL_PKGS:-"nginx16 rh-passenger40 rh-ruby22 nodejs010 git19"}
32
+ SCL_SOURCE="$(command -v scl_source)"
33
+ [[ ${SCL_SOURCE} ]] && source "${SCL_SOURCE}" enable ${SCL_PKGS}
34
+ fi
35
+
36
+ # Environment is set, so call Ruby now
37
+ #
38
+ exec /usr/bin/env ruby "$@"
data/bin/python ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/env bash
2
+
3
+ #
4
+ # Passenger `python` wrapper script
5
+ #
6
+ # Tries to run the developer specified version of python for the requested app
7
+ # before running system default binary (specified in the `bin/ood_ruby` wrapper
8
+ # that stages the PUN)
9
+ #
10
+
11
+ if [[ -x "${PWD}/bin/python" ]]; then
12
+ exec "${PWD}/bin/python" "$@"
13
+ else
14
+ exec python "$@"
15
+ fi
data/bin/ruby ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/env bash
2
+
3
+ #
4
+ # Passenger `ruby` wrapper script
5
+ #
6
+ # Tries to run the developer specified version of ruby for the requested app
7
+ # before running system default binary (specified in the `bin/ood_ruby` wrapper
8
+ # that stages the PUN)
9
+ #
10
+
11
+ if [[ -x "${PWD}/bin/ruby" ]]; then
12
+ exec "${PWD}/bin/ruby" "$@"
13
+ else
14
+ exec ruby "$@"
15
+ fi
@@ -0,0 +1,125 @@
1
+ require 'optparse'
2
+ require 'cgi'
3
+
4
+ module NginxStage
5
+ # The command line interface for NginxStage
6
+ module Application
7
+ # Options parsed from CLI
8
+ # @return [Hash] hash of options and their values
9
+ def self.options
10
+ @options ||= {}
11
+ end
12
+
13
+ # Available commands for the CLI
14
+ # @return [Hash] hash of commands and their attributes
15
+ def self.commands
16
+ {
17
+ 'pun' => NginxStage::PunConfigGenerator,
18
+ 'app' => NginxStage::AppConfigGenerator,
19
+ 'app_reset' => NginxStage::AppResetGenerator,
20
+ 'app_list' => NginxStage::AppListGenerator,
21
+ 'app_clean' => NginxStage::AppCleanGenerator,
22
+ 'nginx' => NginxStage::NginxProcessGenerator,
23
+ 'nginx_show' => NginxStage::NginxShowGenerator,
24
+ 'nginx_list' => NginxStage::NginxListGenerator,
25
+ 'nginx_clean' => NginxStage::NginxCleanGenerator,
26
+ }
27
+ end
28
+
29
+ # Starts the NginxStage workflow
30
+ # @return [void]
31
+ def self.start
32
+ ARGV << "--help" if ARGV.empty?
33
+ command = ARGV.first[0] != '-' ? ARGV.shift : nil
34
+
35
+ generator = commands.fetch(command) do
36
+ command ? raise(InvalidCommand, "invalid command: #{command}") : nil
37
+ end
38
+
39
+ parser = generator ? cmd_parser(command, generator) : default_parser
40
+ parser.parse!( ARGV )
41
+ generator.new(options).invoke if generator
42
+ rescue
43
+ $stderr.puts "#{$!.to_s}"
44
+ $stderr.puts "Run 'nginx_stage --help' to see a full list of available command line options."
45
+ exit(false)
46
+ end
47
+
48
+ # Parses user-supplied arguments
49
+ # @return [OptionParser] the option parser object
50
+ def self.default_parser
51
+ OptionParser.new do |opts|
52
+ opts.banner = "Usage: nginx_stage COMMAND [OPTIONS]"
53
+
54
+ opts.separator ""
55
+ opts.separator "Commands:"
56
+ commands.each do |cmd, klass|
57
+ opts.separator sprintf(" %-20s# %s", cmd, klass.desc)
58
+ end
59
+
60
+ opts.separator ""
61
+ opts.separator "General options:"
62
+ opts.on("-h", "--help", "# Show this help message") do
63
+ puts opts
64
+ exit
65
+ end
66
+ opts.on("-v", "--version", "# Show version") do
67
+ puts "nginx_stage, version #{VERSION}"
68
+ exit
69
+ end
70
+
71
+ opts.separator ""
72
+ opts.separator "All commands can be run with -h (or --help) for more information."
73
+ opts.separator ""
74
+ end
75
+ end
76
+
77
+ # Parses user-supplied arguments for a given command
78
+ # @param command [String] the name of the given command
79
+ # @param generator [Generator] a generator class for a given command
80
+ # @return [OptionParser] the option parser object
81
+ def self.cmd_parser(command, generator)
82
+ OptionParser.new do |opts|
83
+ opts.banner = "Usage: nginx_stage #{command} [OPTIONS]"
84
+
85
+ opts.separator ""
86
+ opts.separator "Required options:"
87
+ generator.options.select {|k,v| v[:required]}.each do |k, v|
88
+ opts.on(*v[:opt_args]) do |input|
89
+ options[k] = unescape(input)
90
+ end
91
+ end
92
+
93
+ opts.separator ""
94
+ opts.separator "General options:"
95
+ generator.options.select {|k,v| !v[:required]}.each do |k, v|
96
+ opts.on(*v[:opt_args]) do |input|
97
+ options[k] = unescape(input)
98
+ end
99
+ end
100
+
101
+ opts.separator ""
102
+ opts.separator "Common options:"
103
+ opts.on("-h", "--help", "# Show this help message") do
104
+ puts opts
105
+ exit
106
+ end
107
+ opts.on("-v", "--version", "# Show version") do
108
+ puts "nginx_stage, version #{VERSION}"
109
+ exit
110
+ end
111
+
112
+ opts.separator ""
113
+ opts.separator generator.footer
114
+ opts.separator ""
115
+ end
116
+ end
117
+
118
+
119
+ private
120
+ # Unescape string
121
+ def self.unescape(value)
122
+ value.respond_to?(:gsub) ? CGI::unescape(value) : value
123
+ end
124
+ end
125
+ end