관리-도구
편집 파일: Config.h
/* * Phusion Passenger - https://www.phusionpassenger.com/ * Copyright (c) 2011-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. */ #ifndef _PASSENGER_SPAWNING_KIT_CONFIG_H_ #define _PASSENGER_SPAWNING_KIT_CONFIG_H_ #include <oxt/macros.hpp> #include <boost/shared_array.hpp> #include <vector> #include <cstddef> #include <jsoncpp/json.h> #include <Constants.h> #include <StaticString.h> #include <DataStructures/StringKeyTable.h> namespace Passenger { namespace SpawningKit { using namespace std; // The following hints are available: // // @require_non_empty // @pass_during_handshake // @non_confidential // @only_meaningful_if // @only_pass_during_handshake_if // // - begin hinted parseable class - class Config { private: boost::shared_array<char> storage; Json::Value tableToJson(const StringKeyTable<StaticString> &table) const { Json::Value doc(Json::objectValue); StringKeyTable<StaticString>::ConstIterator it(table); while (*it != NULL) { doc[it.getKey().toString()] = it.getValue().toString(); it.next(); } return doc; } public: /** * The app group name that the spawned process shall belong to. SpawningKit does * not use this information directly: it is passed to LoggingKit when logging * app output. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString appGroupName; /** * The root directory of the application to spawn. For example, for Ruby apps, this * is the directory containing config.ru. The startCommand will be invoked from * this directory. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString appRoot; /** * The log level to use. * * @hinted_parseable * @pass_during_handshake * @non_confidential */ int logLevel; /** * Whether the app to be spawned is generic or not. Generic * apps do not have special support for Passenger built in, * nor do we have a wrapper for loading the app. * * For example, Rack and Node.js apps are not considered * generic because we have wrappers for them. Go apps without * special Passenger support built in are considered generic. * * @hinted_parseable * @pass_during_handshake * @non_confidential */ bool genericApp: 1; /** * If the app is not generic (`!genericApp`), then this specifies * whether the app is loaded through a wrapper (true), or whether * the app has special support for Passenger built in and is * started directly (false). The only use for this in SpawningKit * is to better format error messages. * * @hinted_parseable * @only_meaningful_if !config.genericApp * @pass_during_handshake * @non_confidential */ bool startsUsingWrapper: 1; /** * When a wrapper is used to load the application, this field * specifies whether the wrapper is supplied by Phusion or by * a third party. The only use for this in SpawningKit is to better * format error messages. * * @hinted_parseable * @only_meaningful_if !config.genericApp && config.startsUsingWrapper * @pass_during_handshake * @non_confidential */ bool wrapperSuppliedByThirdParty: 1; /** * If the app is not generic (`!genericApp`), then this specifies * whether SpawningKit should find a free port to pass to the app * so that it can listen on that port. * This is always done if the app is generic, but *can* be done * for non-generic apps as well. * * @hinted_parseable * @only_meaningful_if !config.genericApp */ bool findFreePort: 1; /** * Whether Passenger should tell Ruby to preload bundler, * this is to help deal with multiple versions of gems * being installed, which is due to updates of default gems. * * @hinted_parseable * @pass_during_handshake * @only_meaningful_if config.appType == "ruby" * @non_confidential */ bool preloadBundler: 1; /** * Whether to load environment variables set in shell startup * files (e.g. ~/.bashrc) during spawning. * * @hinted_parseable * @pass_during_handshake * @non_confidential */ bool loadShellEnvvars: 1; /** * Set to true if you do not want SpawningKit to remove the * work directory after a spawning operation, which is useful * for debugging. Defaults to false. * * @hinted_parseable */ bool debugWorkDir: 1; /** * The command to run in order to start the app. * * If `genericApp` is true, then the command string must contain '$PORT'. * The command string is expected to start the app on the given port. * SpawningKit will take care of passing an appropriate $PORT value to * the app. * * If `genericApp` is false, then the command string is expected do * either one of these things: * - If there is a wrapper available for the app, then the command string * is to invoke the wrapper (and `startsUsingWrapper` should be true). * - Otherwise, the command string is to start the app directly, in * Passenger mode (and `startsUsingWrapper` should be false). * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString startCommand; /** * The application's entry point file. If a relative path is given, then it * is relative to the app root. Only meaningful if app is to be loaded through * a wrapper. * * @hinted_parseable * @only_meaningful_if !config.genericApp && config.startsUsingWrapper * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString startupFile; /** * A process title to set when spawning the application. * * @hinted_parseable * @pass_during_handshake * @non_confidential * @only_pass_during_handshake_if !config.processTitle.empty() */ StaticString processTitle; /** * An application type name, e.g. "ruby" or "nodejs". The only use for this * in SpawningKit is to better format error messages. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString appType; /** * The value to set PASSENGER_APP_ENV/RAILS_ENV/etc to. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString appEnv; /** * The spawn method used for spawning the app, i.e. "smart" or "direct". * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString spawnMethod; /** * The address that Passenger binds to in order to allow sending HTTP * requests to individual application processes. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString bindAddress; /** * The base URI on which the app runs. If the app is running on the * root URI, then this value must be "/". * * @hinted_parseable * @require_non_empty * @pass_during_handshake base_uri * @non_confidential */ StaticString baseURI; /** * The user to start run the app as. Only has effect if the current process * is running with root privileges. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString user; /** * The group to start run the app as. Only has effect if the current process * is running with root privileges. * * @hinted_parseable * @require_non_empty * @pass_during_handshake * @non_confidential */ StaticString group; /** * Any environment variables to pass to the application. These will be set * after the OS shell has already done its work, but before the application * is started. * * @hinted_parseable * @pass_during_handshake */ StringKeyTable<StaticString> environmentVariables; /** * Specifies that the app's stdout/stderr output should be written * to the given log file. * * @hinted_parseable * @non_confidential * @pass_during_handshake */ StaticString logFile; /** * The API key of the pool group that the spawned process is to belong to. * * @hinted_parseable * @pass_during_handshake * @only_pass_during_handshake_if !config.apiKey.empty() */ StaticString apiKey; /** * A UUID that's generated on Group initialization, and changes every time * the Group receives a restart command. Allows Union Station to track app * restarts. * * @hinted_parseable * @pass_during_handshake * @only_pass_during_handshake_if !config.groupUuid.empty() */ StaticString groupUuid; /** * Minimum user ID starting from which entering LVE and CageFS is allowed. * * @hinted_parseable */ unsigned int lveMinUid; /** * The file descriptor ulimit that the app should have. * A value of 0 means that the ulimit should not be changed. * * @hinted_parseable * @pass_during_handshake * @non_confidential * @only_pass_during_handshake_if config.fileDescriptorUlimit > 0 */ unsigned int fileDescriptorUlimit; /** * The maximum amount of time, in milliseconds, that may be spent * on spawning the process or the preloader. * * @hinted_parseable * @require config.startTimeoutMsec > 0 */ unsigned int startTimeoutMsec; /*********************/ /*********************/ Config() : logLevel(DEFAULT_LOG_LEVEL), genericApp(false), startsUsingWrapper(false), wrapperSuppliedByThirdParty(false), findFreePort(false), preloadBundler(false), loadShellEnvvars(false), debugWorkDir(false), appEnv(P_STATIC_STRING(DEFAULT_APP_ENV)), baseURI(P_STATIC_STRING("/")), lveMinUid(DEFAULT_LVE_MIN_UID), fileDescriptorUlimit(0), startTimeoutMsec(DEFAULT_START_TIMEOUT) /*********************/ { } void internStrings(); bool validate(vector<StaticString> &errors) const; Json::Value getConfidentialFieldsToPassToApp() const; Json::Value getNonConfidentialFieldsToPassToApp() const; }; // - end hinted parseable class - #include <Core/SpawningKit/Config/AutoGeneratedCode.h> } // namespace SpawningKit } // namespace Passenger #endif /* _PASSENGER_SPAWNING_KIT_CONFIG_H_ */