Karthik
Karthik

Reputation: 107

How do I get a package conditionally executed in Puppet?

How do I get the packages to execute only if and when exec['get-chocolatey'] is complete and successful? Right now, the packages try to get executed before the exec command and hence fails with the error reading

Chocolatey is not functional on the node

I don't get why 'require' doesn't work here.

exec { 'get-chocolatey':
    path        => 'C:\Windows\system32\WindowsPowerShell\v1.0',
    command     => 'Powershell.exe "Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression"',
    refreshonly => true,
    logoutput   => true
}

package { 'webpi':
    provider => 'chocolatey',
    ensure   => latest,
    require  => Exec['get-chocolatey']
}

package { 'redis-64':
    provider => 'chocolatey',
    ensure   => latest,
    require  => Exec['get-chocolatey']
}

Upvotes: 1

Views: 1626

Answers (3)

Anthony Mastrean
Anthony Mastrean

Reputation: 22384

There's a generalizable form of this dependency that might be helpful in reducing the repetition of the require statement.

This says "get-chocolatey" should happen before any package resource with a Chocolatey provider.

Exec['get-chocolatey'] -> Package<| provider == 'chocolatey' |>

You can read more about it here.

https://docs.puppet.com/puppet/latest/reference/lang_relationships.html#syntax-chaining-arrows

and here

https://docs.puppet.com/puppet/latest/reference/lang_collectors.html

Upvotes: 0

ferventcoder
ferventcoder

Reputation: 12561

Use the Official Chocolatey Installer from the Puppet Provider

Chaining resources works, but why not just use the chocolatey class to ensure installation?

https://forge.puppet.com/chocolatey/chocolatey#usage

include chocolatey

OR

class {'chocolatey':
  chocolatey_download_url         => 'https://internalurl/to/chocolatey.nupkg',
  use_7zip                        => false,
  choco_install_timeout_seconds   => 2700,
}

Organizational Use of Chocolatey.org Packages

If you are an organization, you should be building your own packages or recompiling packages to not use external download and hosting your own internal package server for these packages.

This is due to both trust, control, and a low tolerance of breakages. The following resources provide more context and explanation surrounding the reasoning.

See

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 180113

How do I get the packages to only execute if and when exec['get-chocolatey'] is complete and successful?

You set up resource relationships that require that. Which you have done with your require attributes, and which you could alternatively do with chain operators.

Right now, the packages try to get executed before the exec command

I think not. I observe that your Exec is marked refreshonly. Its command will therefore not be executed at all unless that resource receives an event from some other resource. There is nothing in your class that would generate such an event. It is possible that an event could be received from outside, either directly or by some resource signaling the containing class, but since the command is not running, that seems not to be the case.

and hence fails with the error reading 'chocolatey is not functional on the node'. I don't get why 'require' doesn't work here.

I see no reason to think that require is not working.

I also don't see why you have marked your Exec refreshonly. If you want to arrange for the command to run only if needed, then instead use an appropriate 'unless' or 'onlyif' command, or else use its 'creates' attribute.

Upvotes: 2

Related Questions