I am getting a duplicate declaration error when I don't think I should.
I am using the following puppet version
puppet --version
4.3.2
This is the directory structure
./manifests
./manifests/site.pp
./modules
./modules/main
./modules/main/manifests
./modules/main/manifests/init.pp
./modules/main/manifests/sub.pp
site.pp
node default {
include main
include main::sub
}
init.pp
class main {
notice("main")
}
sub.pp
class main::sub {
notice("sub")
}
I run this command
puppet apply --modulepath ./modules manifests/site.pp
It yields this output:
Notice: Scope(Class[Main]): main
Notice: Scope(Class[Main::Sub]): sub
Notice: Compiled catalog for black-pearl.hsd1.il.comcast.net in environment production in 0.82 seconds
Error: Duplicate declaration: Class[Main] is already declared; cannot redeclare
I'm not sure why this happens, perhaps puppet has a main already. When I substituted ryan in for main all was well.
$ find .
.
./manifests
./manifests/site.pp
./modules
./modules/ryan
./modules/ryan/manifests
./modules/ryan/manifests/init.pp
./modules/ryan/manifests/sub.pp
site.pp
node default {
include ryan
include ryan::sub
}
Puppet 4 is a lot stricter about names, and there are a number of reserved names, including main:
Reserved Class Names
The following are built-in namespaces used by Puppet and so must not be used as class names:
main — Puppet automatically creates a main class, which contains any resources not contained by any other class.
See https://docs.puppetlabs.com/puppet/latest/reference/lang_reserved.html
for more
Related
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.
This is a pretty simple problem, and I have read a number of suggested solutions, but I still can't get puppet apply to import the git::config class. Here is my file setup:
I import the git module via nodes.pp:
#/etc/puppet/manifests/nodes.pp
node default {
}
include git
site.pp imports nodes.pp:
#/etc/puppet/manifests/site.pp
import 'nodes.pp'
The git module is defined as follows:
#/etc/puppet/modules/git/manifests/init.pp
class git {
include git::install
include git::config
}
class git::install{
package {'git': => present }
}
and the config file:
#/etc/puppet/modules/git/manifests/config.pp
define git::config{
[some code here]
}
When I run puppet apply, puppet does not find the git::config class:
sudo puppet apply --modulepath=/etc/puppet/modules /etc/puppet/manifests/site.pp
Error: Could not find class git::config for xxxx on node xxxx.
The original module was puppetlabs-git (same folder structure), but I have recreated the error using the simplified file structure (above).
Update 1
Typo above, the git config.pp and init.pp are in folder /modules/git/manifests and the config.pp file reads 'define git::config'
You cannot call include on git::config. git::config is a defined type, not a class. The syntax to use a defined type is as follows:
git::config { 'the_name_var':
param1 => 'foo',
param2 => 'bar'
}
Hope this helps
Your puppet code structure is wrong. You need move your pp file to manifests folders.
/etc/puppet/modules/git/init.pp
/etc/puppet/modules/git/config.pp
to
/etc/puppet/modules/git/manifests/init.pp
/etc/puppet/modules/git/manifests/config.pp
I am trying to pull things out into roles and profiles and am having an issue. I am using puppet apply for all of this as I am using it to finish setting up my Puppet Master. If I define my node in site.pp as shown here:
[root#puppet puppetdbsetup]# cat manifests/site.pp
node 'puppet' {
include ::roles::puppetmaster
}
I get this error:
[root#puppet puppetdbsetup]# puppet apply manifests/site.pp --environmentpath /etc/puppet/environments --environment puppetdbsetup --noop
Notice: Compiled catalog for puppet.belkin in environment puppetdbsetup in 1.29 seconds
Error: Could not find dependency Class[Puppet::Install] for File[/etc/puppet/hiera.yaml] at /etc/puppet/environments/puppetdbsetup/modules/p
uppet/manifests/master.pp:31
If I run puppetmaster.pp (shown below) with puppet apply directly it doesn't throw the same error.
[root#puppet puppetdbsetup]# cat modules/roles/manifests/puppetmaster.pp
class roles::puppetmaster {
#include profiles::base
include profiles::puppet::master
}
Can anyone tell me why this is and how to fix it? As a side note, all three modules referenced here are hand written... none are Forge modules.
Update 1
Here is my puppet::install class:
[root#puppet puppetdbsetup]# cat modules/puppet/manifests/install.pp
class puppet::install {
package { 'puppet':
ensure => present,
}
}
Somewhere in your manifest, you are declaring a File[/etc/puppet/hiera.yaml] that depends on Class[Puppet::Install], like
file { '/etc/puppet/hiera.yaml': require => Class['puppet::install'] }
or so
Class['puppet::install'] -> file { '/etc/puppet/hiera.yaml': ... }
or something in that vein.
What you are lacking is the actual declaration of the class either via
include puppet::install # nice!
or
class { 'puppet::install': } # please don't
If in doubt, add the include line near the file declaration. It is usually safe to include a class multiple times.
If you apply puppetmaster.pp directly, you're just defining the class not applying it.
You need to do puppet apply -e 'include ::roles::puppetmaster' to be comparible.
The other error is probably caused by modules/puppet/manifests/install.pp not existing, or the class definition in the file not starting with
class puppet::install (
....
....
) {
It seems pretty simple thing, and it works on Vagrant, but I can't make it work on a EC2 server.
When:
puppet apply manifests/init.pp
Error:
Could not find class base for s1.ec2.internal at /var/lib/jenkins/jobs/s1/workspace/manifests/init.pp:1 on node s1.ec2.internal
File ./manifests/init.pp:
include base
File ./manifests/base.pp:
class base {
exec { "apt-get update":
command => "/usr/bin/apt-get update",
timeout => 0
}
package { ["vim", "git", "build-essential"]:
ensure => present,
require => Exec["apt-get update"]
}
}
Puppet v2.7.23
Like Felix stated the class base is being looked for in the modules of your puppet manifests. The directory structure of your modules as follows:
$confdir/
|- manifests
|- init.pp <- The file you reference to when executing puppet apply
|- modules
|- base
|- manifests
|- init.pp <- The file containing your base class
What Felix forgot to mention was that there needs to be another manifests directory within the base module directory.
See also https://docs.puppetlabs.com/puppet/latest/reference/modules_fundamentals.html
Usually class base will be found only in a module named base.
Try putting it into modules/base/init.pp instead of manifests/base.pp.
In my case it was a permissions issue - the files were owned by root but I wasn't running puppet with sudo
I'm using Puppet 3.5.1 on Linux 6 machine.
I have a local module "A" that includes a sub-module "B". Such that sub-module "B" is located in "/etc/puppet/modules/A/modules/B".
I refer to sub-module "B" in my module "A" classes: (/etc/puppet/modules/A/manifest/init.pp file)
class A::one (
...
class { 'B':
val1 => 'abc',
val2 => 'abc',
}
...
)
B is then not reference any were else.
When I start up puppet master and the puppet agent, I get the following error on the agent:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error ArgumentError: Could not find declared class B
What have I missed?
I saw some posts had the resolution as adding a 'include B' for the puppet agent node. If that's the solution, since this is a module inside another module, how do I refer to it?
Edit 1
I moved the sub module "B" into the main modules folder, from "/etc/puppet/modules/A/modules" to "/etc/puppet/modules". It gave the the error:
Error: Duplicate declaration: Class[B] is already declared; cannot redeclare at /etc/puppet/modules/A/manifest/init.pp
Having a modules/ subtree in a module is no valid structure as far as the autoloader is concerned. There is no semantics for submodules.
If you desperately want this particular case to work, you will have to add /etc/puppet/modules/A to your modulepath config setting.
You may wish to ask a new question and describe what you are actually trying to solve, because it seems that your code architecture is a little unclean.