From 010c0f451f0037c53fc524ceb6486bc623803e5e Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Mon, 6 Oct 2025 00:07:39 +0200 Subject: [PATCH 1/2] Introduce the Linux runmode This builds on the previous work to define all paths in the RunMode class and has a few interesting aspects. The parts that make it Linux specific is that it prefers systemd environment variables to determine locations. When those aren't available, it instead uses hardcoded paths for root and follows the XDG specification for non-root. Currently this mode is not used yet, but by having it in the codebase distribution packagers can easily use it without having to change all paths. Link: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory= Link: https://specifications.freedesktop.org/basedir-spec/latest/ --- lib/puppet/util/run_mode.rb | 80 +++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/lib/puppet/util/run_mode.rb b/lib/puppet/util/run_mode.rb index cf331e4532..0e84de152c 100644 --- a/lib/puppet/util/run_mode.rb +++ b/lib/puppet/util/run_mode.rb @@ -160,5 +160,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 From 19515a0fa816c8bb483e7efab48559b3a3419fc2 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Mon, 6 Oct 2025 02:16:08 +0200 Subject: [PATCH 2/2] Switch to using Linux run mode on Linux --- lib/puppet/util/platform.rb | 5 +++++ lib/puppet/util/run_mode.rb | 2 ++ 2 files changed, 7 insertions(+) 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 0e84de152c..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