Dependency cycle with apt source - puppet

I'm trying to install the puppet module at https://github.com/dwerder/puppet-mongodb
One of the requirements for it to work is to have the mongodb repository set-up. Since I'm trying to deploy it on Debian I tried using the following class to add the source:
class mongodb::apt::repo {
include apt
apt::source { '10gen':
location => 'http://downloads-distro.mongodb.org/repo/debian-sysvinit',
release => 'dist',
repos => '10gen',
key => '7F0CEB10',
key_server => 'keyserver.ubuntu.com',
include_src => false
}
}
However, upon trying to install the module (on a test node) I get the following output:
root#debian:/etc/puppet/modules# puppet agent --test
info: Caching catalog for debian.lan
info: Applying configuration version '1353946258'
err: Could not apply complete catalog: Found 1 dependency cycle:
(Exec[apt_update] => Class[Apt::Update] => Anchor[apt::source::10gen] => Anchor[apt::source::10gen] => Apt::Source[10gen] => Class[Mongodb::Apt::Repo] => Package[mongodb-10gen] => Anchor[mongodb::install::end] => Anchor[mongodb::install::end] => File[10gen.list] => Apt::Source[10gen])
Try the '--graph' option and opening the resulting '.dot' file in OmniGraffle or GraphViz
notice: Finished catalog run in 0.06 seconds
The class is included in the module's install class at https://github.com/dwerder/puppet-mongodb/blob/master/manifests/install.pp
I'm not quite sure why this dependency cycle happens, any ideas?

What was your last change (that's probably the moment you added the cycle).
Try the suggestion to generate the graph. Post the generated dot file as gist so that we can investigate further.
Take a look at Debugging cycle or missing dependency.
Note that some dependencies are explicit (require, ->) or implicit (the resource provider add the dependency by it self)... having a look at the dot file should help.

Related

Verifying if package is installed before downloading it in PUPPET

That is my manifest code which download, install and remove installer on a host.
class googlechrome_2 {
package { 'GoogleChrome':
ensure => installed,
source => 'C:\Soft\ChromeSetup.msi',
install_options => ['/qn'],
require => File['GoogleChromeMsi'],
}
file { 'GoogleChromeMsi':
ensure => file,
path => 'C:\Soft\ChromeSetup.msi',
source => 'puppet:///files/production/ChromeSetup.msi',
}
exec { 'msi_removing':
command => 'C:\Windows\System32\cmd.exe /c del C:\Soft\ChromeSetup.msi',
}
}
In this case my windows host always download chromesetup.msi regardless if google chrome already installed or not. How can I realize kind of "if condition" here to avoid downloading msi package each time in case if this package already installed?
In this case my windows host always download chromesetup.msi regardless if google chrome already installed or not.
Yes. Having the File resource in the node's catalog specifies that the file should be managed. Therefore, if it is not initially in the target state then Puppet will attempt to fix that.
By managing the file present but also including an Exec that removes the file, you ensure that the target node cannot achieve a stable state.
How can I realize kind of "if condition" here to avoid downloading msi package each time in case if this package already installed?
Simplest option: don't remove the installer.
Variation: Put the installer in an accessible network folder, so that you not only don't remove it, but you also don't install it.
If you really want a conditional: then it should be based on a custom fact that reports on the installation status of the package in question. You then use a Puppet if statement to control the contents of the node's catalog appropriately. Something along these lines, for example:
package { 'GoogleChrome':
ensure => 'installed',
source => 'C:\Soft\ChromeSetup.msi',
install_options => ['/qn'],
# relationhip with File['GoogleChromeMsi'] now declared on the other end
}
if $facts['chrome_is_installed'] {
file { 'GoogleChromeMsi':
ensure => 'absent',
path => 'C:\Soft\ChromeSetup.msi',
}
} else {
file { 'GoogleChromeMsi':
ensure => 'file',
path => 'C:\Soft\ChromeSetup.msi',
source => 'puppet:///files/production/ChromeSetup.msi',
before => Package['GoogleChrome'],
}
exec { 'msi_removing':
command => 'C:\Windows\System32\cmd.exe /c del C:\Soft\ChromeSetup.msi',
require => Package['GoogleChrome'],
}
}
I've solved this by using network shared folder in the package source:
class googlechrome_smb {
package { 'Google Chrome':
ensure => installed,
source => '\\\xxx.xxx.xxx.xxx\winfiles\ChromeSetup.msi',
install_options => ['/qn'],
}
}

puppet / facter: "created(corrective)"

I use puppet to update / maintain itself (among other things). For some reason every time the client runs I get these two actions:
Notice: /Stage[main]/Servers::Packages::Puppet/Package[facter]/ensure: created (corrective)
Notice: /Stage[main]/Servers::Packages::Puppet/Package[puppet]/ensure: created (corrective)
The definitions in question look like this:
package { 'puppet' :
ensure => 'latest',
require => Package['facter'];
}
package { 'facter' :
ensure => 'latest',
}
file { '/etc/default/puppet' :
ensure => 'file',
mode => '644',
source => 'puppet:///modules/servers/packages/puppet/default';
}
file{ '/etc/puppetlabs/puppet/puppet.conf' :
mode => '644',
content => template("servers/packages/puppet/puppet_conf.erb"),
require => Package[ 'puppet' ];
}
service{ 'puppet' :
ensure => 'running',
enable => true,
require => Package[ 'puppet' ],
subscribe => [
File[ '/etc/default/puppet'],
File[ '/etc/puppetlabs/puppet/puppet.conf'],
];
}
What's wrong with my definition(s)? Why do puppet / facter appear to be reinstalled with every run?
Since Puppet 4, Puppet, Inc. has provided only all-in-one packages of client-side components, not named either 'puppet' or 'facter'. The package for Puppet 6 is named puppet-agent -- this is what you should be managing, not packages named 'puppet' or 'facter'.
The messages you report indicate that Puppet does not see up-to-date 'puppet' or 'facter' packages, which is natural because these do not exist. They also indicate that puppet thinks it has corrected the problem -- which it will have attempted to do by installing / updating packages with those names, and which apparently succeeded. This seeming incongruity will have arisen because the puppet-agent packages declare that they provide features named "puppet" and "facter", which your package manager is using to associate those package names with the puppet-agent package. As a result, the installation / update succeeds without actually installing anything new, leaving the system primed to do the same thing over again on the next run.
I suspect that the "(corrective)" marks on the log output reflect package-manager exit statuses indicating success without doing anything.

puppetlabs-dhcp: Could not find dependency File[/etc/dhcp/dhcpd.conf]

I'm pretty new to puppet and I'm trying to use the module puppetlabs-dhcp (v0.3.0) with puppet master/agent v3.7.2. I'm using a very simple class declaration following the example given by the README file.
When I try to run the class on the node using puppet agent -t the run fails with the error
Error: Failed to apply catalog: Could not find dependency File[/etc/dhcp/dhcpd.conf] for Service[isc-dhcp-server] at /etc/puppet/modules/dhcp/manifests/init.pp:173
I tried adding a file resource before the dhcp class declaration but the file stays blank. None of the configurations are taken into account.
I checked the dependencies:
concat > 1.0.1 (using 2.0.2)
stdlib > 2.0.0 (using 4.13.1)
Here is the dhcp portion of the node in site.pp:
class {'dhcp':
dnsdomain => [
'jecks.lab',
'0.0.10.IN-ADDR.ARPA',],
nameservers => ['10.0.0.2'],
ntpservers => ['us.pool.ntp.org'],
interfaces => ['eth0','eth1'],
}
dhcp::pool{'ops.jecks.lab':
network => '10.0.0.0',
mask => '255.255.255.0',
range => ['10.0.0.100','10.0.0.254'],
gateway => '10.0.0.1',
}
dhcp::host {'debian-main':
mac => 'xxxxxxxxxxxxxx',
ip => '10.0.0.3',
}
What am I doing wrong? I assumed the dhcpd.conf file was created using concat from the parameters given in the class declaration.
This is a bug in puppetlabs-dhcp 0.3.0 when using concat 2.x that was fixed in 0.4.0. Using a newer version of the dhcp module or downgrading concat to 1.x would fix it.
Note that the puppetlabs-dhcp module moved to the Vox Pupuli community organisation a while ago, so you can find updates at puppet/dhcp on the Forge. The latest at the time of writing is 1.0.1, rather than 0.3.0.

Puppet code to download extract and install

I have a file at some web URL (http://www.somewhere.com/something.tar.gz).
This is direct download link.
I need a puppet code that would download this file, extract it and install the file.
Can we do this using package {} in puppet?
There isn't really an intrinsic provider for the package type that understands tarballs. There is, however, this VoxPopuli module: https://forge.puppet.com/puppet/archive which was recently Puppet certified and should do what you need.
Note under their usage example it could be modified for your needs like:
archive { '/tmp/something':
ensure => present,
extract => true,
extract_path => '/tmp',
source => 'http://www.somewhere.com/something.tar.gz',
checksum => 'checksum hash',
checksum_type => 'sha1',
creates => '/tmp/something',
cleanup => true,
}

Can not find class during Puppet apply

My puppet structure is as follows
/puppet
/manifests
/nodes
redis.pp
site.pp
/modules
The site.pp resembles
class base {
include ml-basefw
include ml-users
include ml-filelimits
include repoforge
include epel
class { 'ml-yumrepo':
base_url => "http://${puppet_server}/yumrepo"
}
}
import 'nodes/*.pp'
node default {
include base
}
When I run
puppet apply --modulepath=/puppet/modules:/puppet/manifests --noop --debug /puppet/manifests/nodes/redis.pp
I receive
Error: Could not find class base for redis-1.test.ml.com on node redis-1.test.ml.com
Is there something non-standard about my file layout that precludes me from using apply?
I am not the maintainer of the puppet module so I am not able to alter the file structure or layout.
There are numerous related questions but I wasn't able to relate them to the problem that I am having.
Edit1 : Adding redis.pp
node /^redis-\d+(.stage)?(.test)?(.aws)?.ml.com$/ {
include base
include epel
class { 'redis':
package_ensure => '2.8.15-1.el6.remi',
service_ensure => 'running',
conf_bind => '0.0.0.0',
conf_port => '6379',
}
firewall { '176 allow port 6379 for redis traffic':
chain => 'INPUT',
state => ['NEW'],
dport => '6379',
proto => 'tcp',
action => 'accept'
}
}
What happens when you run puppet apply against your site.pp file instead? You probably don't have a node definition in your redis.pp file (nor should you).
This does in fact look a little messy and convoluted.
What you want is
an actual base module
defining class base in /puppet/modules/base/manifests/init.pp
You should also loose the import statement by arranging your manifests better. If your version of Puppet is recent enough (I think 3.6+), just see the docs.
fist of all, puppet have the entry manifest file.
in master mode, the entry is site.pp and puppet deprated deprecated it from version 3.5, it started auto imported all manifest files in specified directory.
in apply mode, the entry is specified file in your command.
so it works fine in your production environment, puppet master read site.pp(contains class base) and import nodes/*.pp(redis.pp, contains node definition). but when you use "puppet apply /puppet/manifests/nodes/redis.pp", puppet just read redis.pp, no anyone tell puppet where the base class is.

Resources