Ask Your Question
1

Anchor patterns not containing classes in a simple setup

asked 2014-12-17 01:00:22 -0500

shadyabhi gravatar image

I've 2 simple base classes:

class profile::base {
  anchor { 'base_repos_start': }
  class { '::yum::repo::epel': require   => Anchor['base_repos_start']}
  class { '::yum::repo::puppet': require =>  Anchor['base_repos_start']}
  anchor { 'base_repos_end': }
}

class profile::openstack::base {
  anchor { 'rdo_repo_start': }
  class { '::yum::repo::rdo': require => Anchor['rdo_repo_start']}
  anchor { 'rdo_repo_end': }
}

And then I use this classes in another class which is related to a particular class of servers.

class role::openstack::controller {
  class { '::profile::base': } ->
  class { '::profile::openstack::base': } ->
  class { '::profile::openstack::keystone': } ->
  class { '::profile::openstack::glance': } ->
  class { '::profile::openstack::nova::controller': } ->
  class { '::profile::openstack::neutron::controller': }
}

When I run puppet, I observe that "stuff" in class ::profile::openstack::glance starts happening before the repos get added via base classes profile::base & profile::openstack::base. The reason I say that resources from ::profile::openstack::glance start getting applied before base classes is (The output is from the first puppet run and the package installation of openstack-glance is present in class ::profile::openstack::glance):

Info: Applying configuration version '1418737032'
Debug: Prefetching yum resources for package
Debug: Executing '/usr/bin/rpm --version'
Debug: Executing '/usr/bin/rpm -qa --nosignature --nodigest --qf '%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}\n''
Debug: Executing '/usr/bin/rpm -q openstack-glance --nosignature --nodigest --qf %{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}\n'
Debug: Executing '/usr/bin/yum -d 0 -e 0 -y list openstack-glance'
Error: Execution of '/usr/bin/yum -d 0 -e 0 -y list openstack-glance' returned 1: Error: No matching Packages to list
Error: /Stage[main]/Glance/Package[openstack-glance]/ensure: change from absent to present failed: Execution of '/usr/bin/yum -d 0 -e 0 -y list openstack-glance' returned
 1: Error: No matching Packages to list

I think I'm using anchor patterns correctly but they don't seem to be working. Is there anything that I'm doing fundamentally wrong? Any possible reasons this might not be working?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2014-12-17 16:53:19 -0500

cbarbour gravatar image

updated 2015-06-01 19:37:30 -0500

I think I'm using anchor patterns correctly but they don't seem to be working. Is there anything that I'm doing fundamentally wrong? Any possible reasons this might not be working?

In your example, your classes don't seem to have any relationship with the end anchor. Try this:

class profile::base {
  anchor { 'base_repos_start': }
  class { '::yum::repo::epel':
    require => Anchor['base_repos_start'],
    before  => Anchor['base_repos_end'],
  }
  class { '::yum::repo::puppet':
    require => Anchor['base_repos_start'],
    before  => Anchor['base_repos_end'],
  }
  anchor { 'base_repos_end': }
}

class profile::openstack::base {
  anchor { 'rdo_repo_start': }
  class { '::yum::repo::rdo':
    require => Anchor['rdo_repo_start'],
    before  => Anchor['rdo_repo_end'],
  }
  anchor { 'rdo_repo_end': }
}

As a stylistic thing, consider using the include keyword and chaining arrows instead of resource style class declaration and the before/require keyword. This approach is a little easier to read, and is less likely to create conflicts if two profiles include the same class.

class profile::openstack::base {
  anchor { 'rdo_repo_start': }
  include ::yum::repo::rdo
  anchor { 'rdo_repo_end': }

  Anchor['rdo_repo_start'] ->
  Class['yum::repo::rdo']  ->
  Anchor['rdo_repo_end']
}

If you're on Puppet 3.5 or later, anchors are deprecated. Your example could more simply be written using the contains function.

class profile::base {
  contain ::yum::repo::epel
  contain ::yum::repo::puppet
}

class profile::openstack::base {
  contain ::yum::repo::rdo
}

Be aware that until Puppet 3.7, the contain function does not support fully qualified class names, which can create some problems in Roles and Profiles. To work around this, remove the leading double colons (::) on each class.

See PUP-1597 for details.


To answer this quesiton from @stefanlasiewski :

@cbarbour : If I understand correctly, the second example with anchor does enforce ordering, whereas the third example with contain does not enforce order. ::yum::repo::puppet may get called before ::yum::repo::epel, and the ordering is lost. Is that what you intended?

Neither example enforces ordering with anything other than the anchors. Class[::yum::repo::epel] and Class[::yum::repo::puppet] have no relationship with each other. The anchors allow us to create ordering between the two profiles if necessary. Useful in this case because profile::base declares yum repos.

In these examples, an ordering relationship doesn't seem to be necessary, or advised. Remember that ordering creates dependencies, meaning that a failure in one class will prevent the resources from the other from being applied. If one class isn't strictly dependent on the other, it's best not to create resource relationships between them.

FWIW... I would probably use run-stages here rather than class based ordering. The reason being that profile::base seems like it needs to be applied before every other resource on the system. Using a run-stage would prevent failures in the base profile from aborting the rest of the run.

edit flag offensive delete link more

Comments

@cbarbour : If I understand correctly, the second example with `anchor` does enforce ordering, whereas the third example with `contain` does not enforce order. `::yum::repo::puppet` may get called before `::yum::repo::epel`, and the ordering is lost. Is that what you intended?

stefanlasiewski gravatar imagestefanlasiewski ( 2015-06-01 18:45:24 -0500 )edit

Aha. I see that I was confused and I understand now. Unlike the Anchor example listed at https://docs.puppetlabs.com/guides/module_guides/bgtm.html#containment-and-anchoring, this example did not try to contain classes *and* enforce order at the same time.

stefanlasiewski gravatar imagestefanlasiewski ( 2015-06-02 17:30:07 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2014-12-17 01:00:22 -0500

Seen: 737 times

Last updated: Jun 01 '15