Search code examples
puppet

Puppet exec a command before the package is installed


I am trying to run a power shell script just before the Pacakage starts installing an msi installer. The script cleans up certain un-managed resources that would block installer. What I tried is,

file { 'c:\Test\cleanup.ps1.file' :
    path               => 'c:\Test\cleanup.ps1',
    ensure             => present,
    source             => 'puppet:///modules/test/cleanup.ps1',
    source_permissions => ignore,
  }
  exec { 'c:\Test\cleanup.ps1.file':
    refreshonly => true,
    provider    => powershell,
  }
  package { 'ServiceInstaller':
    ensure  => $version,
    require => [Package['Service1Installer'],Exec['c:\Test\cleanup.ps1']],
  }

But require attribute doesn't fire the command. Could someone please help me to achieve this behaviour. There is this notify command, that would send a EXEC notification, but that happens after the installation. What I need is before the installation. Thanks in advance.


Solution

  • The trick to getting this working properly is that something has to write c:\Test\cleanup.ps1.file only when you need the script to be triggered to run, and the exec resource has to subscribe to it. Otherwise, if that file doesn't change, and the exec isn't subscribed, the exec resource does not think it needs to run so the puppet run completes but the script never fires.

    Based on the code you pasted here, it looks like you're specifying $version in the class? And I'm guessing you're updating this either in the class or in hiera explicitly when you want to upgrade? If so, you could have the c:\Test\cleanup.ps1.file file write an inline template and just put the version number in that file. When you update the version in the class/hiera/wherever in puppet you're doing this, the file would update and the exec would kick off.

    This would look something like:

    file { 'c:\Test\cleanup.ps1.file' :
        path               => 'c:\Test\cleanup.ps1',
        ensure             => present,
        content            => inline_template("<%= @version %>"),
        source_permissions => ignore,
    }
    
    exec { 'c:\Test\cleanup.ps1.file':
        refreshonly => true,
        provider    => powershell,
        subscribe   => File['c:\Test\cleanup.ps1.file'],
    }
    
    package { 'ServiceInstaller':
        ensure  => $version,
        require => [Package['Service1Installer'],Exec['c:\Test\cleanup.ps1']],
    }
    

    This is assuming you were just trying to use the cleanup.ps1.file as a trigger for the exec. If there is stuff in that file you need for other purposes, then leave that declaration as you had it, and make another file declaration as a trigger file with just the version in an inline template, and subscribe the exec to that one instead of the cleanup.ps1.file