Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/puppet/util/platform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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?

Expand Down
82 changes: 82 additions & 0 deletions lib/puppet/util/run_mode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines 16 to 22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple run modes will require further logic here de determine which one to prefer. For some operating systems, a simple test of the os is enough, but for Linux it will probably need something smarted, e.g. detect if AIO or not (to run in AIO RunMode), test if parent PID is 1 or not (for SystemdRunMode), etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be more of an OpenVox 9 question, but do we continue to push the AIO model with paths in /opt at all? If so, should the patching patch this class to achieve that instead?

Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UnixRunMode is puppetlabs-centric (the WindowsRunMode too). I wonder if we should rather make a hierarchy of classes where we override functions as needed.

A SystemdRunMode would basically be a specialization of a LinuxRunMode class, where functions call super unless the ad-hoc env variable is set.

I also think that the AIO RunMode should be a specialization a of more generic class rather than a base class like it is today, basically some tree of classes like:

  • RunMode
    • PosixRunMode
      • FreebsdRunMode
      • LinuxRunMode
        • AIOLinuxRunMode (what is called UnixRunMode today)
        • SystemdRunMode
    • WindowsRunMode

I am not sure about what levels of hierarchy are required, I put FreeBSD there because I know I would benefit from it. If it help, here is the special config we set in the generated puppet.conf on FreeBSD so that the various bits are in what we consider the "right" place (where $ETCDIR is /usr/local/etc/puppet): https://github.com/freebsd/freebsd-ports/blob/main/sysutils/openvox-agent8/Makefile#L116

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was indeed thinking we need something like that hierarchy. I think the splitting up of LinuxRunMode may not be needed at all because I'd suggest to drop the specific AIO paths. Only use normal paths. The application code could still be shipped in /opt if desired.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm... i'm not familiar with this, but we have UnixRunMode up there which we seemed to be using before this patch, what is it if not PosixRunMode here?

or, to put this another way, why don't we treat all UnixRunMode as following the XDG standard? i think it's mostly compatible with FreeBSD, for example, except for the /usr/local bits

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is XDG a POSIX standard? I don't mind applying that to all platforms.

But the /usr/local bit vs / is one I have a hard time unifying.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XDG is, obviously, not in POSIX.

but then if you derive Linux from POSIX, you're kind of kidding yourself as well... Linux is not, strictly speaking, POSIX either: https://en.wikipedia.org/wiki/POSIX#POSIX-oriented_operating_systems

but we're splitting hairs here: i was mostly wondering where the UnixRunMode fits in your class hierarchy there, i overlooked the AIOLinuxRunMode bits there...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that XDG can be handled quite low in the hierarchy: it is indeed available on FreeBSD.

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')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense for non-root users to ignore the /etc code directory?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so: when compiling catalogs, doesn't the ccode run as the puppet user?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps .config should be prioritized over /etc, at least when running as a non-root user, though? is that the case here?

at least that's the way it works now, i think...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so: when compiling catalogs, doesn't the ccode run as the puppet user?

No, the agent runs as root.

perhaps .config should be prioritized over /etc, at least when running as a non-root user, though? is that the case here?

That should indeed be the case, but today if you install OpenVox AIO packages you get an empty configuration file (only comments) so the built in defaults matter.

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'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to make it easy to switch to OpenVox paths. Perhaps it should be defined in the base class so all packaging can be switched over in 1 go.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for having it a single time.

end
end
end
end
Loading