diff --git a/lib/puppet/util/platform.rb b/lib/puppet/util/platform.rb index da2484710a..f9de4aa71f 100644 --- a/lib/puppet/util/platform.rb +++ b/lib/puppet/util/platform.rb @@ -21,6 +21,11 @@ def solaris? end module_function :solaris? + def linux? + RUBY_PLATFORM.include?('linux') + end + module_function :linux? + def default_paths return [] if windows? diff --git a/lib/puppet/util/run_mode.rb b/lib/puppet/util/run_mode.rb index cf331e4532..c9db4374c4 100644 --- a/lib/puppet/util/run_mode.rb +++ b/lib/puppet/util/run_mode.rb @@ -15,6 +15,8 @@ def self.[](name) @run_modes ||= {} if Puppet::Util::Platform.windows? @run_modes[name] ||= WindowsRunMode.new(name) + elsif Puppet::Util::Platform.linux? + @run_modes[name] ||= LinuxRunMode.new(name) else @run_modes[name] ||= UnixRunMode.new(name) end @@ -160,5 +162,85 @@ def windows_common_base(*extra) [ENV.fetch('ALLUSERSPROFILE', nil), "PuppetLabs"] + extra end end + + # A Linux runmode, using systemd, FHS and XDG standards + # + # This first attempts systemd environment variables. If those don't exist + # it falls back to using hardcoded directories for root and XDG directories + # for non-root users. XDG describes various environment variables with + # recommended fallbacks. + # + # @see https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory= + # @see https://specifications.freedesktop.org/basedir-spec/latest/ + class LinuxRunMode < RunMode + def conf_dir + ENV.fetch('CONFIGURATION_DIRECTORY') do + config_home = which_dir("/etc", ENV.fetch("XDG_CONFIG_HOME", "~/.config")) + File.join(config_home, packaging_name) + end + end + + def code_dir + File.join(conf_dir, 'code') + end + + def var_dir + ENV.fetch('STATE_DIRECTORY') do + data_home = which_dir("/var/lib", ENV.fetch("XDG_DATA_HOME", "~/.local/share")) + File.join(data_home, packaging_name) + end + end + + def cache_directory + ENV.fetch('CACHE_DIRECTORY') do + cache_home = which_dir("/var/cache", ENV.fetch("XDG_CACHE_HOME", "~/.cache")) + File.join(cache_home, packaging_name) + end + end + + def public_dir + File.join(cache_directory, 'public') + end + + def run_dir + ENV.fetch('RUNTIME_DIRECTORY') do + runtime_dir = which_dir("/run", ENV.fetch("XDG_RUNTIME_DIR") { File.join('/run', 'user', ::Etc.getpwuid.uid) }) + File.join(runtime_dir, packaging_name) + end + end + + def log_dir + ENV.fetch('LOGS_DIRECTORY') do + which_dir(File.join('/var', 'log', packaging_name), + File.join(ENV.fetch("XDG_STATE_HOME", "~/.local/state"), packaging_name, "logs")) + end + end + + def pkg_config_path + # automatically picked up + end + + def gem_cmd + '/usr/bin/gem' + end + + def data_dir + File.join('/usr', 'share', packaging_name) + end + + def common_module_dir + File.join(data_dir, 'modules') + end + + def vendor_module_dir + File.join(data_dir, 'vendor_modules') + end + + private + + def packaging_name + 'puppet' + end + end end end