Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Declare dependency between array elements in Puppet

Is there any way to declare in Puppet’s language that packages in an array should installed in the order they are given in the array?

I want to automate the installation of CUDA, which requires nvidia-driver-latest-dkms, cuda and cuda-drivers (on RHEL7 as an example) to be installed in that order. I do not want to hard-code the array of packages, because I need to support different distributions, which require different packages. Therefore, an array holding the packages provided via Hiera seemed to be a good idea.

My first solution was ensure_packages($packages_parameter_filled_via_hiera), which stopped working recently (probably due to changes in NVIDIA’s packages). The problem seems to be that this code installs the packages in a random order, and you cannot install nvidia-driver-latest-dkms (any more) if any of the other packages is already installed.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

My next approach,

$packages.each | $package | {
    ensure_packages($package)
}

has the very same problem as does

$packages.each | $package | {
    package { "cuda-${package}":
        name => $package
    }
}

What I am looking for is something that is equivalent to the -> or ~> operator between the loop instances, or alternatively, some "dangling-pointer" construct that would give me access to the previous $package such that I can write require => Package[$magic_previous_instance] in the package resource. That is, I want to create something equivalent to

package { 'cuda-epel-release': 
    name => 'epel-release'
}
-> package { 'cuda-nvidia-driver-latest-dkms': 
    name => 'nvidia-driver-latest-dkms'
}
-> package { 'cuda-cuda': 
    name => 'cuda'
}
-> package { 'cuda-cuda-drivers': 
    name => 'cuda-drivers'
}

(which actually works, but exactly for RHEL 7) dynamically from Hiera data.

>Solution :

Yes, this is actually possible with a "wrapper" defined resource type:

define custom::install(Hash $pkg_hash) {
  # iterates through the packages in the hash using their keys, and creates a package default where each requires the previous package
  # index > 0 ensures the first package does not attempt to require a nonexistent previous package
  keys($pkg_hash).each |Integer $index, String $pkg| { if $index > 0 { Package[keys($pkg_hash)[$index - 1]] -> Package[$pkg] } }

  create_resources(package, $pkg_hash)
}

To give credit where credit is due, I was originally pointed in this direction by Henrik Lindberg, so it is not entirely my creation. The input Hash $pkg_hash for the defined resource type is a package hash type analogous to the input argument structure for the create_resources function second argument. For example:

$pkg_hash = {
  'cuda-epel-release'              => { ensure => installed },
  'cuda-nvidia-driver-latest-dkms' => { ensure => installed }
}

or in Hiera data YAML format:

pkg_hash:
  'cuda-epel-release':
    ensure: installed
  'cuda-nvidia-driver-latest-dkms':
    ensure: installed
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading