lib/omnibus/config.rb in omnibus-3.1.1 vs lib/omnibus/config.rb in omnibus-3.2.0.rc.1

- old
+ new

@@ -12,305 +12,466 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # -require 'mixlib/config' +require 'singleton' module Omnibus - # Global configuration object for Omnibus runs. - # - # @todo Write a {http://yardoc.org/guides/extending-yard/writing-handlers.html - # Yard handler} for Mixlib::Config-style DSL methods. I'd like - # the default value to show up in the docs without having to type - # it out twice, which I'm doing now for benefit of viewers of the Yard docs. class Config - extend Mixlib::Config - extend Util + include Cleanroom + include NullArgumentable + include Singleton + include Util + class << self + # + # @param [String] filepath + # the path to the config definition to load from disk + # + # @return [Config] + # + def load(filepath) + evaluate_file(instance, filepath) + end + + # + # @macro default + # @method $1(value = NULL) + # + # @param [Symbol] key + # the name of the configuration value to create + # @param [Object] default + # the default value + # @param [Proc] block + # a block to be called for the default value. If the block is provided, + # the +default+ attribute is ignored + # + def default(key, default = NullArgumentable::NULL, &block) + # This is a class method, which delegates to the instance method + define_singleton_method(key) do |value = NullArgumentable::NULL| + instance.send(key, value) + end + + # This is an instance method, but this is a singleton object ;) + define_method(key) do |value = NullArgumentable::NULL| + set_or_return(key, value, default, &block) + end + + # All config options should be avaiable as DSL methods + expose(key) + end + + # + # Check if the configuration includes the given key. + # + # @param [Symbol] key + # + # @return [true, false] + # + def key?(key) + public_method_defined?(key.to_sym) + end + alias_method :has_key?, :key? + + # + # Get a value from the config object. + # + # @deprecated Use direct method instead + # + # @param [Symbol] key + # the key to fetch + # + # @return [Object] + # + def fetch(key) + Omnibus.logger.deprecated('Config') do + "fetch ([]). Please use `Config.#{key}' instead." + end + + public_method_defined?(key.to_sym) && instance.send(key.to_sym) + end + alias_method :[], :fetch + + # + # Reset the current configuration values. This method will unset any + # "stored" or memorized configuration values. + # + # @return [true] + # + def reset! + instance.instance_variables.each do |instance_variable| + instance.send(:remove_instance_variable, instance_variable) + end + + true + end + end + + # # @!group Directory Configuration Parameters + # -------------------------------------------------- - # @!attribute [rw] base_dir - # The "base" directory where Omnibus will store it's data. Other paths are - # dynamically constructed from this value. + # The "base" directory where Omnibus will store it's data. Other paths are + # dynamically computed from this value. # - # Defaults to `"C:\omnibus-ruby"` on Windows - # Defaults to `"/var/cache/omnibus"` on other platforms + # - Defaults to +C:\omnibus-ruby+ on Windows + # - Defaults to +/var/cache/omnibus+ on other platforms # - # @return [String] + # @return [String] default(:base_dir) do - if Ohai.platform == 'windows' + if Ohai['platform'] == 'windows' 'C:\\omnibus-ruby' else '/var/cache/omnibus' end end - # @!attribute [rw] cache_dir - # The absolute path to the directory on the virtual machine where - # code will be cached. + # The absolute path to the directory on the virtual machine where + # code will be cached. # - # Defaults to `"/var/cache/omnibus/cache"`. - # - # @return [String] + # @return [String] default(:cache_dir) { windows_safe_path(base_dir, 'cache') } - # @!attribute [rw] install_path_cache_dir - # The absolute path to the directory on the virtual machine where - # install paths will be progressively cached. + # The absolute path to the directory on the virtual machine where + # git caching will occur and software's will be progressively cached. # - # Defaults to `"/var/cache/omnibus/cache/install_path"`. + # @return [String] + default(:git_cache_dir) do + if defined?(@install_path_cache_dir) + @install_path_cache_dir + else + windows_safe_path(base_dir, 'cache', 'git_cache') + end + end + + # @deprecated Use {#git_cache_dir} instead. # - # @return [String] - default(:install_path_cache_dir) { windows_safe_path(base_dir, 'cache', 'install_path') } + # @return [String] + default(:install_path_cache_dir) do + Omnibus.logger.deprecated('Config') do + 'Config.install_path_cache_dir. Plase use Config.git_cache_dir instead.' + end - # @!attribute [rw] source_dir - # The absolute path to the directory on the virtual machine where - # source code will be downloaded. + git_cache_dir + end + + # The absolute path to the directory on the virtual machine where + # source code will be downloaded. # - # Defaults to `"/var/cache/omnibus/src"`. - # - # @return [String] + # @return [String] default(:source_dir) { windows_safe_path(base_dir, 'src') } - # @!attribute [rw] build_dir - # The absolute path to the directory on the virtual machine where - # software will be built. + # The absolute path to the directory on the virtual machine where + # software will be built. # - # Defaults to `"/var/cache/omnibus/build"`. - # - # @return [String] + # @return [String] default(:build_dir) { windows_safe_path(base_dir, 'build') } - # @!attribute [rw] package_dir - # The absolute path to the directory on the virtual machine where - # packages will be constructed. + # The absolute path to the directory on the virtual machine where + # packages will be constructed. # - # Defaults to `"/var/cache/omnibus/pkg"`. - # - # @return [String] + # @return [String] default(:package_dir) { windows_safe_path(base_dir, 'pkg') } - # @!attribute [rw] package_tmp - # The absolute path to the directory on the virtual machine where - # packagers will store intermediate packaging products. Some packaging - # methods (notably fpm) handle this internally so not all packagers will - # use this setting. + # The absolute path to the directory on the virtual machine where + # packagers will store intermediate packaging products. Some packaging + # methods (notably fpm) handle this internally so not all packagers will + # use this setting. # - # Defaults to `"/var/cache/omnibus/pkg-tmp"`. - # - # @return [String] + # @return [String] default(:package_tmp) { windows_safe_path(base_dir, 'pkg-tmp') } - # @!attribute [rw] project_dir - # The relative path of the directory containing {Omnibus::Project} - # DSL files. This is relative to {#project_root}. + # The relative path of the directory containing {Omnibus::Project} + # DSL files. This is relative to {#project_root}. # - # Defaults to `"config/projects"`. + # @return [String] + default(:project_dir, 'config/projects') + + # The relative path of the directory containing {Omnibus::Software} + # DSL files. This is relative {#project_root}. # - # @return [String] - default :project_dir, 'config/projects' + # @return [String] + default(:software_dir, 'config/software') - # @!attribute [rw] software_dir - # The relative path of the directory containing {Omnibus::Software} - # DSL files. This is relative {#project_root}. + # The root directory in which to look for {Omnibus::Project} and + # {Omnibus::Software} DSL files. # - # Defaults to `"config/software"`. + # @return [String] + default(:project_root) { Dir.pwd } + + # -------------------------------------------------- + # @!endgroup # - # @return [String] - default :software_dir, 'config/software' - # @!attribute [rw] project_root - # The root directory in which to look for {Omnibus::Project} and - # {Omnibus::Software} DSL files. # - # Defaults to the current working directory. + # @!group DMG / PKG configuration options + # -------------------------------------------------- + + # Package OSX pkg files inside a DMG # - # @return [String] - default(:project_root) { Dir.pwd } + # @return [true, false] + default(:build_dmg, true) - # @!attribute [rw] install_dir - # Installation directory + # The starting x,y and ending x,y positions for the created DMG window. # - # Defaults to `"/opt/chef"`. + # @return [String] + default(:dmg_window_bounds, '100, 100, 750, 600') + + # The starting x,y position where the .pkg file should live in the DMG + # window. # - # @todo This appears to be unused, and actually conflated with - # {Omnibus::Project#install_path} + # @return [String] + default(:dmg_pkg_position, '535, 50') + + # Sign the pkg package. # - # @return [String] - default :install_dir, '/opt/chef' + # @return [true, false] + default(:sign_pkg, false) + # The identity to sign the pkg with. + # + # @return [String] + default(:signing_identity, nil) + + # -------------------------------------------------- # @!endgroup + # - # @!group DMG / PKG configuration options + # + # @!group S3 Caching Configuration Parameters + # -------------------------------------------------- - # @!attribute [rw] build_dmg - # Package OSX pkg files inside a DMG + # Indicate if you wish to cache software artifacts in S3 for + # quicker build times. Requires {#s3_bucket}, {#s3_access_key}, + # and {#s3_secret_key} to be set if this is set to +true+. # - # @return [Boolean] - default :build_dmg, true + # @return [true, false] + default(:use_s3_caching, false) - # @!attribute [rw] dmg_window_bounds - # Indicate the starting x,y and ending x,y positions for the created DMG - # window. + # The name of the S3 bucket you want to cache software artifacts in. # # @return [String] - default :dmg_window_bounds, '100, 100, 750, 600' + default(:s3_bucket) do + raise MissingConfigOption.new(:s3_bucket, "'my_bucket'") + end - # @!attribute [rw] dmg_pkg_position - # Indicate the starting x,y position where the .pkg file should live in - # the DMG window. + # The S3 access key to use with S3 caching. # # @return [String] - default :dmg_pkg_position, '535, 50' + default(:s3_access_key) do + raise MissingConfigOption.new(:s3_access_key, "'ABCD1234'") + end - # @!attribute [rw] sign_pkg - # Sign the pkg package. + # The S3 secret key to use with S3 caching. # - # Default is false. + # @return [String] + default(:s3_secret_key) do + raise MissingConfigOption.new(:s3_secret_key, "'EFGH5678'") + end + + # -------------------------------------------------- + # @!endgroup # - # @return [Boolean] - default :sign_pkg, false - # @!attribute [rw] signing_identity - # The identity to sign the pkg with. # - # Default is nil. Required if sign_pkg is set. + # @!group Artifactory Publisher + # -------------------------------------------------- + + # The full URL where the artifactory instance is accessible. # - # @return [String] - default :signing_identity, nil + # @return [String] + default(:artifactory_endpoint) do + raise MissingConfigOption.new(:artifactory_endpoint, "'https://...'") + end - # @!endgroup + # The username of the artifactory user to authenticate with. + # + # @return [String] + default(:artifactory_username) do + raise MissingConfigOption.new(:artifactory_username, "'admin'") + end - # @!group S3 Caching Configuration Parameters + # The password of the artifactory user to authenticate with. + # + # @return [String] + default(:artifactory_password) do + raise MissingConfigOption.new(:artifactory_password, "'password'") + end - # @!attribute [rw] use_s3_caching - # Indicate if you wish to cache software artifacts in S3 for - # quicker build times. Requires {#s3_bucket}, {#s3_access_key}, - # and {#s3_secret_key} to be set if this is set to `true`. + # The path on disk to an SSL pem file to sign requests with. # - # Defaults to `false`. + # @return [String, nil] + default(:artifactory_ssl_pem_file, nil) + + # Whether to perform SSL verification when connecting to artifactory. # - # @return [Boolean] - default :use_s3_caching, false + # @return [true, false] + default(:artifactory_ssl_verify, true) - # @!attribute [rw] s3_bucket - # The name of the S3 bucket you want to cache software artifacts in. + # The username to use when connecting to artifactory via a proxy. # - # Defaults to `nil`. Must be set if {#use_s3_caching} is `true`. + # @return [String] + default(:artifactory_proxy_username, nil) + + # The password to use when connecting to artifactory via a proxy. # - # @return [String, nil] - default :s3_bucket, nil + # @return [String] + default(:artifactory_proxy_password, nil) - # @!attribute [rw] s3_access_key - # The S3 access key to use with S3 caching. + # The address to use when connecting to artifactory via a proxy. # - # Defaults to `nil`. Must be set if {#use_s3_caching} is `true`. - # - # @return [String, nil] - default :s3_access_key, nil + # @return [String] + default(:artifactory_proxy_address, nil) - # @!attribute [rw] s3_secret_key - # The S3 secret key to use with S3 caching. + # The port to use when connecting to artifactory via a proxy. # - # Defaults to `nil`. Must be set if {#use_s3_caching} is `true.` - # - # @return [String, nil] - default :s3_secret_key, nil + # @return [String] + default(:artifactory_proxy_port, nil) + # -------------------------------------------------- # @!endgroup + # - # @!group S3 Release Parameters + # + # @!group S3 Publisher + # -------------------------------------------------- - # @!attribute [rw] release_s3_bucket - # The name of the S3 bucket you want to release artifacts to. + # The S3 access key to use for S3 artifact release. # - # Defaults to `nil`. Must be set to use `release package` command. + # @return [String] + default(:publish_s3_access_key) do + raise MissingConfigOption.new(:publish_s3_access_key, "'ABCD1234'") + end + + # The S3 secret key to use for S3 artifact release # - # @return [String, nil] - default :release_s3_bucket, nil + # @return [String] + default(:publish_s3_secret_key) do + raise MissingConfigOption.new(:publish_s3_secret_key, "'EFGH5678'") + end - # @!attribute [rw] release_s3_access_key - # The S3 access key to use for S3 artifact release. + # -------------------------------------------------- + # @!endgroup # - # Defaults to `nil`. Must be set to use `release package` command. + # - # @return [String, nil] - default :release_s3_access_key, nil + # @!group Miscellaneous Configuration Parameters + # -------------------------------------------------- - # @!attribute [rw] release_s3_secret_key - # The S3 secret key to use for S3 artifact release + # @deprecated The is no replacement for this configuration item # - # Defaults to `nil`. Must be set to use `release package` command. - # - # @return [String, nil] - default :release_s3_secret_key, nil + # @return [true, false] + default(:override_file) do + Omnibus.logger.deprecated('Config') do + 'Config.override_file. Using an override file is deprecated.' + end - # @!endgroup + nil + end - # @!group Miscellaneous Configuration Parameters + # An array of local disk paths that include software definitions to load + # from disk. The software definitions in these paths are pulled + # **in order**, so if multiple paths have the same software definition, the + # one that appears **first** in the list here is chosen. + # + # - These paths take precedence over those defined in {#software_gems}. + # - These paths are preceeded by local project vendored softwares. + # + # For these paths, it is assumed that the folder structure is: + # + # /PATH/config/software/* + # + # @return [Array<String>] + default(:local_software_dirs) { [] } - # @!attribute [rw] override_file + # @deprecated Use {#software_gems} instead # - # @return [Boolean] - default :override_file, nil + # @return [String] + default(:software_gem) do + Omnibus.logger.deprecated('Config') do + 'Config.software_gem. Plase use Config.software_gems (plural) and ' \ + 'specify an array of software gems instead.' + end - # @!attribute [rw] software_gem + software_gems + end + + # The list of gems to pull software definitions from. The software + # definitions from these gems are pulled **in order**, so if multiple gems + # have the same software definition, the one that appears **first** in the + # list here is chosen. # - # The gem to pull software definitions from. This is just the name of the gem, which is used - # to find the path to your software definitions, and you must also specify this gem in the - # Gemfile of your project repo in order to include the gem in your bundle. + # - These paths are preceeded by those defined in {#local_software_dirs}. + # - These paths are preceeded by local project vendored softwares. # - # Defaults to "omnibus-software". + # For these gems, it is assumed that the folder structure is: # - # @return [String, nil] - default :software_gem, 'omnibus-software' + # /GEM_ROOT/config/software/* + # + # @return [Array<String>] + default(:software_gems) do + if defined?(@software_gem) + Array(@software_gem) + else + ['omnibus-software'] + end + end - # @!attribute [rw] solaris_compiler + # The solaris compiler to use # - # @return [String, nil] - default :solaris_compiler, nil + # @return [String, nil] + default(:solaris_compiler, nil) + # -------------------------------------------------- # @!endgroup + # - # @!group Build Version Parameters + # + # @!group Build Parameters + # -------------------------------------------------- - # @!attribute [rw] append_timestamp - # Append the current timestamp to the version identifier. + # Append the current timestamp to the version identifier. # - # @return [Boolean] - default :append_timestamp, true + # @return [true, false] + default(:append_timestamp, true) - # # @!endgroup + # The number of times to retry the build before failing. + # + # @return [Integer] + default(:build_retries, 3) - # @!group Build Control Parameters + # Use the incremental build caching implemented via git. This will + # drastically improve build times, but may result in hidden and + # unexpected bugs. + # + # @return [true, false] + default(:use_git_caching, true) - # @! attribute [rw] build_retries - # The number of times to retry the build before failing. + # -------------------------------------------------- + # @!endgroup # - # @return [Integer, nil] - default :build_retries, 3 - # @!group Validation Methods + private - # Asserts that the Config object is in a valid state. If invalid - # for any reason, an exception will be thrown. # - # @raise [RuntimeError] - # @return [void] - def self.validate - valid_s3_config? - # add other validation methods as needed - end + # + # + def set_or_return(key, value = NULL, default = NULL, &block) + instance_variable = :"@#{key}" - # @raise [InvalidS3Configuration] - def self.valid_s3_config? - if use_s3_caching - unless s3_bucket - raise InvalidS3Configuration.new(s3_bucket, s3_access_key, s3_secret_key) + if null?(value) + if instance_variable_defined?(instance_variable) + instance_variable_get(instance_variable) + else + if block + instance_eval(&block) + else + null?(default) ? nil : default + end end + else + instance_variable_set(instance_variable, value) end end - - # @!endgroup - end # Config -end # Omnibus + end +end