The Puppet Resource Abstraction Layer (RAL) Explained: Part 4

Day 25 in the #vDM30in30 Image from https://flic.kr/p/6t59b So, we’ve talked about the RAL, getters, setters and the resource command. Now let’s talk about implementing a RAL interface of our own. swap_file type and provider I ended up implementing a RAL layer in my swap_file module, mainly as an exercise in figuring out how types and providers work. It looks like this: Puppet::Type.type(:swap_file).provide(:linux) do desc "Swap file management via `swapon`, `swapoff` and `mkswap`" confine :kernel => :linux commands :swapon => 'swapon' commands :swapoff => 'swapoff' commands :mkswap => 'mkswap' mk_resource_methods def initialize(value={}) super(value) @property_flush = {} end def self.get_swap_files swapfiles = swapon(['-s']).split("\n") swapfiles.shift swapfiles.sort end def self.prefetch(resources) instances.each do |prov| if resource = resources[prov.name] resource.provider = prov end end end def self.instances get_swap_files.collect do |swapfile_line| new(get_swapfile_properties(swapfile_line)) end end def self.get_swapfile_properties(swapfile_line) swapfile_properties = {} # swapon -s output formats thus: # Filename Type Size Used Priority # Split on spaces output_array = swapfile_line.strip.split(/\s+/) # Assign properties based on headers swapfile_properties = { :ensure => :present, :name => output_array[0], :file => output_array[0], :type => output_array[1], :size => output_array[2], :used => output_array[3], :priority => output_array[4] } swapfile_properties[:provider] = :swap_file Puppet.debug "Swapfile: #{swapfile_properties.inspect}" swapfile_properties end def exists? @property_hash[:ensure] == :present end def create @property_flush[:ensure] = :present end def destroy @property_flush[:ensure] = :absent end def create_swap_file(file_path) mk_swap(file_path) swap_on(file_path) end def mk_swap(file_path) Puppet.debug "Running `mkswap #{file_path}`" output = mkswap([file_path]) Puppet.debug "Returned value: #{output}`" end def swap_on(file_path) Puppet.debug "Running `swapon #{file_path}`" output = swapon([file_path]) Puppet.debug "Returned value: #{output}" end def swap_off(file_path) Puppet.debug "Running `swapoff #{file_path}`" output = swapoff([file_path]) Puppet.debug "Returned value: #{output}" end def set_swapfile if @property_flush[:ensure] == :absent swap_off(resource[:name]) return end create_swap_file(resource[:name]) unless exists? end def flush set_swapfile # Collect the resources again once they've been changed (that way `puppet # resource` will show the correct values after changes have been made). @property_hash = self.class.get_swapfile_properties(resource[:name]) end end Now, there’s a bunch of weird stuff in there, that to be honest even know I only vaguely understand… ...

November 25, 2016 · 5 min · Peter Souter

The Puppet Resource Abstraction Layer (RAL) Explained: Part 3

Day 24 in the #vDM30in30 Image from https://flic.kr/p/DY38HH So, we’ve talked about how the RAL is a getter and setter, but let’s talk about a lesser known feature of puppet that uses the RAL: The puppet resource command. The puppet resource command is basically a CLI for the RAL. Hey, it used to even be called “ralsh”, for RAL Shell. What it’s doing is using that instances method from before, and running it on the system, and returning the current state as valid Puppet code. ...

November 24, 2016 · 2 min · Peter Souter

The Puppet Resource Abstraction Layer (RAL) Explained: Part 2

Day 23 in the #vDM30in30 Image from https://flic.kr/p/c5U1bW So, previously we talked about the RAL as a Swan. Let’s look at those legs kicking below the water. RAL with a package installation Let’s continue with our example of a resource on a system, a package called tree. package {'tree': ensure => present, } Let’s look at how the RAL will manage this: We’ve given the type as package. I’m running this on a RHEL7 system, so the default provider is yum. yum is a “child” provider of rpm: it uses the RPM command to check if the package is installed on the system. This is a lot faster than running “yum info”, as it doesn’t make any internet calls, and won’t fail if a yumrepo is failing. The install command however, will be yum install. So previously we talked about how Puppet uses the RAL to both read and modify the state of resources on a system. ...

November 23, 2016 · 7 min · Peter Souter

The Puppet Resource Abstraction Layer (RAL) Explained: Part 1

Day 22 in the #vDM30in30 “All problems in computer science can be solved by another level of indirection, except of course for the problem of too many indirections.” - Wheeler More talk about Puppet, explaining a concept that takes a bit of understanding to get: The Resource Abstraction Layer. Turtles all the way down Puppet’s secret sauce is abstraction. When it’s all boiled down, Puppet is not doing anything magical: the commands that are being run on the system are the same commands that would be run by a human operator. ...

November 22, 2016 · 5 min · Peter Souter

Drying up rspec with shared_examples

Day 17 in the #vDM30in30 Header image taken from https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples One of the areas where it’s easy to have WET (We Enjoy Typing) code that you want to DRY (Don’t Repeat Yourself) up, is tests. When writing tests for similar areas of code, it’s easy to end up copy and pasting. You have to pieces of functionality that need to be tested in the same way, so why not copy and paste the testing code? ...

November 17, 2016 · 11 min · Peter Souter