관리-도구
편집 파일: config_options_list.rb
# Phusion Passenger - https://www.phusionpassenger.com/ # Copyright (c) 2015-2018 Phusion Holding B.V. # # "Passenger", "Phusion Passenger" and "Union Station" are registered # trademarks of Phusion Holding B.V. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. PhusionPassenger.require_passenger_lib 'constants' PhusionPassenger.require_passenger_lib 'platform_info/ruby' # This file contains a specification of all supported Passenger Standalone # configuration options. The specifications are spread over multiple constants, # one for each category. The command line parser for `passenger start` is # automatically generated from these specifications. The configuration file # parser and the environment variable parser also use these specifications. # # A specification is an array of hashes. The following keys are supported: # # - :name # The name of the configuration option. If you omit this option, while # simultaneously setting the `:cli` option, then it means this configuration # option is available as a command line option only. # # - :type # (default: :string) # The value type. Supported types are: :string, :integer, :boolean, :path, # :array, :map, :hostname. # This is used for determining a default parser and for checking the value. # # - :type_desc # (default: automatically inferred) # A description of the value type, to be used in command line option help # messages. For example, the `:address` option should have the type desc # `HOST` so that the help message `--address HOST` is generated. Boolean # options have a `type_desc` of nil. # # - :cli # (default: automatically inferred) # The name of the corresponding command line option. If not specified, then # a default one will be automatically generated form the configuration option # name. For example, `:ssl_certificate_path` becomes `--ssl-certificate-path`. # If set to nil, then it means there is no corresponding command line option. # # - :cli_parser # (default: automatically inferred) # Command line options are parsed based on the configuration option type. # If you want to parse it differently, then you can set this option to a # lambda to specify a custom parser. # # - :short_cli # The name of the corresponding short command line option, if any. For # example, the `:address` option should have `short_cli` set to `-a`. # # - :desc # A description to be displayed in command line options help message. # # - :default # The default value. # # - :min # If :type is :integer, then this specifies the minimum accepted value. # Has no meaing if :type is not :integer. # This value is used by the default CLI parser to check whether the # passed argument is acceptable. module PhusionPassenger module Standalone # Server configuration options SERVER_CONFIG_SPEC = [ { :name => :address, :type => :hostname, :type_desc => 'HOST', :short_cli => '-a', :default => '0.0.0.0', :desc => "Bind to the given address.\n" \ "Default: %DEFAULT%" }, { :name => :port, :type => :integer, :short_cli => '-p', :default => 3000, :desc => 'Use the given port number. Default: %DEFAULT%' }, { :name => :socket_file, :type => :path, :type_desc => 'FILE', :cli => '--socket', :short_cli => '-S', :desc => "Bind to Unix domain socket instead of TCP\n" \ 'socket' }, { :name => :socket_backlog, :type => :integer, :cli => '--socket-backlog', :desc => "Override size of the socket backlog.\n" \ "Default: #{DEFAULT_SOCKET_BACKLOG}" }, { :name => :ssl, :type => :boolean, :desc => "Enable SSL support (Nginx\n" \ 'engine only)' }, { :name => :ssl_certificate, :type => :path, :desc => "Specify the SSL certificate path\n" \ '(Nginx engine only)' }, { :name => :ssl_certificate_key, :type => :path, :desc => "Specify the SSL key path (Nginx\n" \ 'engine only)' }, { :name => :ssl_port, :type => :integer, :type_desc => 'PORT', :desc => "Listen for SSL on this port, while\n" \ "listening for HTTP on the normal port\n" \ '(Nginx engine only)' }, { :name => :daemonize, :type => :boolean, :short_cli => '-d', :desc => 'Daemonize into the background' }, { :name => :user, :type_desc => 'USERNAME', :desc => "User to run as. Ignored unless\n" \ 'running as root' }, { :name => :log_file, :type => :path, :desc => "Where to write log messages. Default:\n" \ 'console, or /dev/null when daemonized' }, { :name => :pid_file, :type => :path, :desc => 'Where to store the PID file' }, { :name => :instance_registry_dir, :type => :path, :desc => 'Use the given instance registry directory' }, { :name => :data_buffer_dir, :type => :path, :desc => 'Use the given data buffer directory' }, { :name => :core_file_descriptor_ulimit, :type => :integer, :desc => "Set custom file descriptor ulimit for the\n" \ "#{SHORT_PROGRAM_NAME} core" } ] # Application loading configuration options APPLICATION_LOADING_CONFIG_SPECS = [ { :name => :environment, :type_desc => 'NAME', :short_cli => '-e', :default => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || ENV['NODE_ENV'] || ENV['PASSENGER_APP_ENV'] || 'development', :desc => "Web framework environment. Default:\n" \ "%DEFAULT%" }, { :name => :ruby, :type_desc => 'FILENAME', :desc => "Executable to use for Ruby apps.\n" \ "Default: #{PlatformInfo.ruby_command}\n" \ "(current context)" }, { :name => :python, :type_desc => 'FILENAME', :desc => 'Executable to use for Python apps' }, { :name => :nodejs, :type_desc => 'FILENAME', :desc => 'Executable to use for Node.js apps' }, { :name => :meteor_app_settings, :type => :path, :type_desc => 'FILENAME', :desc => "Settings file to use for (development mode)\n" \ 'Meteor apps' }, { :type => :path, :type_desc => 'FILENAME', :cli => '--rackup', :short_cli => '-R', :cli_parser => lambda do |options, value| options[:app_type] = 'rack' options[:startup_file] = File.absolute_logical_path(value, Dir.logical_pwd) end, :desc => "Consider application a Ruby app, and use\n" \ 'the given rackup file' }, { :name => :app_type, :type_desc => 'NAME', :desc => 'Force app to be detected as the given type' }, { :name => :startup_file, :type => :path, :type_desc => 'FILENAME', :desc => 'Force given startup file to be used' }, { :name => :app_start_command, :type_desc => 'COMMAND', :desc => 'Force the app to be started through this command' }, { :name => :app_support_kuria_protocol, :type => :boolean, :desc => 'Force the app to be recognized as a Kuria app', }, { :name => :spawn_method, :type_desc => 'NAME', :default => PlatformInfo.ruby_supports_fork? ? DEFAULT_SPAWN_METHOD : 'direct', :desc => 'The spawn method to use. Default: see docs' }, { :name => :direct_instance_request_address, :type => :hostname, :type_desc => 'HOST', :default => '127.0.0.1', :desc => "The address that Passenger binds to in order to allow sending HTTP requests to individual application processes.\nDefault: %DEFAULT%" }, { :name => :static_files_dir, :type => :path, :desc => "Specify the static files dir (Nginx engine\n" \ 'only)' }, { :name => :restart_dir, :type => :path, :desc => 'Specify the restart dir' }, { :name => :friendly_error_pages, :type => :boolean, :desc => 'Turn on friendly error pages' }, { :name => :custom_error_page, :type => :path, :desc => 'Path to html file to use for Passenger generated error pages' }, { :type => :boolean, :cli => '--no-friendly-error-pages', :cli_parser => lambda do |options, value| options[:friendly_error_pages] = false end, :desc => 'Turn off friendly error pages' }, { :name => :load_shell_envvars, :type => :boolean, # The Standalone mode is primarily used for serving a single app (except # when in mass deployment mode), so load_shell_envvars is disabled by # default. However, it's enabled by default in the Core, so we need to # explicitly set it to disabled here. :default => false, :desc => "Load shell startup files before loading\n" \ 'application' }, { :name => :preload_bundler, :type => :boolean, :default => false, :desc => "Tell Ruby to load the bundler gem before loading the application" }, { :name => :app_file_descriptor_ulimit, :type => :integer, :desc => "Set custom file descriptor ulimit for the\n" \ "application" }, { :name => :debugger, :type => :boolean, :desc => 'Enable debugger support' }, { :name => :envvars, :type => :map, :type_desc => 'NAME=VALUE', :default => {}, :cli => '--envvar', :cli_parser => lambda do |options, value| if value !~ /=.+/ abort "*** ERROR: invalid --envvar format: #{value}" end key, real_value = value.split('=', 2) options[:envvars] ||= {} options[:envvars][key] = real_value end, :desc => 'Pass environment variable to application' } ] # Process management configuration options PROCESS_MANAGEMENT_CONFIG_SPECS = [ { :name => :max_pool_size, :type => :integer, :min => 1, :desc => "Maximum number of application processes.\n" \ "Default: #{DEFAULT_MAX_POOL_SIZE}" }, { :name => :min_instances, :type => :integer, :min => 0, :desc => "Minimum number of processes per\n" \ 'application. Default: 1' }, { :name => :pool_idle_time, :type => :integer, :type_desc => 'SECONDS', :desc => "Maximum time that processes may be idle.\n" \ "Default: #{DEFAULT_POOL_IDLE_TIME}" }, { :name => :max_preloader_idle_time, :type => :integer, :type_desc => 'SECONDS', :desc => "Maximum time that preloader processes may\n" \ "be idle. A value of 0 means that preloader\n" \ "processes never timeout. Default: #{DEFAULT_MAX_PRELOADER_IDLE_TIME}" }, { :name => :force_max_concurrent_requests_per_process, :type => :integer, :desc => "Force #{SHORT_PROGRAM_NAME} to believe that an\n" \ "application process can handle the given\n" \ "number of concurrent requests per process" }, { :name => :start_timeout, :type => :integer, :type_desc => 'SECONDS', :desc => "The maximum time an application process may\n" \ "take to start up, after which it will be killed\n" \ "with SIGKILL, and logged with an error.\nDefault: #{DEFAULT_START_TIMEOUT / 1000}" }, { :name => :concurrency_model, :type_desc => 'NAME', :desc => "The concurrency model to use, either\n" \ "'process' or 'thread' (Enterprise only).\n" \ "Default: #{DEFAULT_CONCURRENCY_MODEL}" }, { :name => :thread_count, :type => :integer, :desc => "The number of threads to use when using\n" \ "the 'thread' concurrency model (Enterprise\n" \ "only). Default: #{DEFAULT_APP_THREAD_COUNT}" }, { :name => :memory_limit, :type => :integer, :type_desc => 'MB', :desc => "Restart application processes that go over\n" \ "the given memory limit (Enterprise only)" }, { :name => :rolling_restarts, :type => :boolean, :desc => "Enable rolling restarts (Enterprise only)" }, { :name => :resist_deployment_errors, :type => :boolean, :desc => "Enable deployment error resistance\n" \ '(Enterprise only)' } ] # Request handling configuration options REQUEST_HANDLING_CONFIG_SPECS = [ { :name => :max_requests, :type => :integer, :min => 0, :desc => "Restart application processes that have handled\n" \ "the specified maximum number of requests" }, { :name => :max_request_time, :type => :integer, :type_desc => 'SECONDS', :min => 0, :desc => "Abort requests that take too much time\n" \ '(Enterprise only)' }, { :name => :max_request_queue_size, :type => :integer, :min => 0, :desc => "Specify request queue size. Default: #{DEFAULT_MAX_REQUEST_QUEUE_SIZE}" }, { :name => :sticky_sessions, :type => :boolean, :desc => 'Enable sticky sessions' }, { :name => :sticky_sessions_cookie_name, :type_desc => 'NAME', :desc => "Cookie name to use for sticky sessions.\n" \ "Default: #{DEFAULT_STICKY_SESSIONS_COOKIE_NAME}" }, { :name => :sticky_sessions_cookie_attributes, :type_desc => "'NAME1=VALUE1; NAME2'", :desc => "The attributes to use for the sticky session cookie.\n" \ "Default: #{DEFAULT_STICKY_SESSIONS_COOKIE_ATTRIBUTES}" }, { :name => :vary_turbocache_by_cookie, :type_desc => 'NAME', :desc => "Vary the turbocache by the cookie of the\n" \ 'given name' }, { :name => :turbocaching, :type => :boolean, :cli => nil }, { :type => :boolean, :cli => '--disable-turbocaching', :desc => 'Disable turbocaching', :cli_parser => lambda do |options, value| options[:turbocaching] = false end }, { :name => :unlimited_concurrency_paths, :type => :array, :type_desc => 'URI-PATH', :cli => '--unlimited-concurrency-path', :desc => "Specify URI path which supports unlimited\n" \ "concurrency. Specify multiple times for\n" \ "multiple paths", :default => [], :cli_parser => lambda do |options, value| options[:unlimited_concurrency_paths] ||= [] options[:unlimited_concurrency_paths] << value end }, { :name => :abort_websockets_on_process_shutdown, :type => :boolean, :cli => nil }, { :type => :boolean, :cli => '--no-abort-websockets-on-process-shutdown', :desc => "Do not abort WebSocket connections on\n" \ 'process restart', :cli_parser => lambda do |options, value| options[:abort_websockets_on_process_shutdown] = false end } ] # Nginx engine configuration options NGINX_ENGINE_CONFIG_SPECS = [ { :name => :nginx_bin, :type => :path, :type_desc => 'FILENAME', :desc => 'Nginx binary to use as core' }, { :name => :nginx_version, :type_desc => 'VERSION', :default => PREFERRED_NGINX_VERSION, :desc => "Nginx version to use as core.\n" \ "Default: #{PREFERRED_NGINX_VERSION}" }, { :name => :nginx_tarball, :type => :path, :type_desc => 'FILENAME', :desc => "If Nginx needs to be installed, then the\n" \ "given tarball will be used instead of\n" \ "downloading from the Internet" }, { :name => :nginx_config_template, :type => :path, :type_desc => 'FILENAME', :desc => "The template to use for generating the\n" \ 'Nginx config file' }, { :name => :debug_nginx_config, :type => :boolean, :desc => 'Print Nginx config template and exit' } ] # Advanced configuration options ADVANCED_CONFIG_SPECS = [ { :name => :disable_security_update_check, :type => :boolean, :desc => "Disable check for security updates" }, { :name => :security_update_check_proxy, :type_desc => 'NAME', :desc => "Use HTTP/SOCKS proxy for the security update check" }, { :name => :disable_anonymous_telemetry, :type => :boolean, :desc => "Disable anonymous telemetry collection" }, { :name => :anonymous_telemetry_proxy, :type_desc => 'NAME', :desc => "Use HTTP/SOCKS proxy for anonymous telemetry collection" }, { :name => :engine, :type_desc => 'NAME', :default => 'nginx', :desc => "Underlying HTTP engine to use. Available\n" \ "options: nginx (default), builtin" }, { :name => :log_level, :type => :integer, :default => DEFAULT_LOG_LEVEL, :desc => "Log level to use. Default: #{DEFAULT_LOG_LEVEL}" }, { :name => :disable_log_prefix, :type => :boolean, :desc => "Disable prefixing log statements with PID and channel." }, { :name => :admin_panel_url, :type => :string, :desc => 'Connect to an admin panel at the given connector URL' }, { :name => :admin_panel_auth_type, :type => :string, :desc => 'Authentication type to use when connecting to the admin panel' }, { :name => :admin_panel_username, :type => :string, :desc => 'Username to use when authenticating with the admin panel' }, { :name => :admin_panel_password, :type => :string, :desc => 'Password to use when authenticating with the admin panel' }, { :name => :auto, :type => :boolean, :default => !STDIN.tty? || !STDOUT.tty?, :desc => "Run in non-interactive mode. Default when\n" \ 'stdin or stdout is not a TTY' }, { :name => :ctls, :type => :array, :type_desc => 'NAME=VALUE', :default => [], :cli_parser => lambda do |options, value| if value !~ /=.+/ abort "*** ERROR: invalid --ctl format: #{value}" end options[:ctls] ||= [] options[:ctls] << value end }, { :name => :binaries_url_root, :type_desc => 'URL', :desc => "If Nginx needs to be installed, then the\n" \ "specified URL will be checked for binaries\n" \ 'prior to a local build' }, { :name => :runtime_check_only, :type => :boolean, :desc => "Quit after checking whether the\n" \ "#{PROGRAM_NAME} Standalone runtime files\n" \ 'are installed' }, { :name => :dont_install_runtime, :type => :boolean, :cli => '--no-install-runtime', :desc => 'Abort if runtime must be installed' }, { :name => :dont_compile_runtime, :type => :boolean, :cli => '--no-compile-runtime', :desc => 'Abort if runtime must be compiled' } ] CONFIG_SPECS = [ SERVER_CONFIG_SPEC, APPLICATION_LOADING_CONFIG_SPECS, PROCESS_MANAGEMENT_CONFIG_SPECS, REQUEST_HANDLING_CONFIG_SPECS, NGINX_ENGINE_CONFIG_SPECS, ADVANCED_CONFIG_SPECS ] # Maps configuration options to their default value. Automatically # set by code later in this file. # # To inspect the value of this array, run: # # ./dev/runner -r standalone/config_options_list -r pp \ # 'pp Standalone::CONFIG_DEFAULTS; nil' CONFIG_DEFAULTS = {} # Indexes all configuration specification items by name. # # To inspect the value of this array, run: # # ./dev/runner -r standalone/config_options_list -r pp \ # 'pp Standalone::CONFIG_NAME_INDEX; nil' CONFIG_NAME_INDEX = {} ############ # Apply transformations on the specification constants, e.g. set default values. make_default_type_desc_value = lambda do |spec_item| case spec_item[:type] when :string 'STRING' when :integer 'NUMBER' when :path 'PATH' when :array 'ARRAY' when :map 'MAP' when :hostname 'HOSTNAME' else nil end end make_default_cli_value = lambda do |spec_item| '--' + spec_item[:name].to_s.gsub('_', '-') end CONFIG_SPECS.each do |spec| spec.each do |spec_item| spec_item[:type] ||= :string spec_item[:type_desc] ||= make_default_type_desc_value.call(spec_item) if spec_item[:name] if !spec_item.key?(:cli) spec_item[:cli] = make_default_cli_value.call(spec_item) end if spec_item.key?(:default) CONFIG_DEFAULTS[spec_item[:name]] = spec_item[:default] end CONFIG_NAME_INDEX[spec_item[:name]] = spec_item end end end end end