Domanda

I want to achieve dependency between puppet classes, so that the classes (their content) get executed in a deterministic way. Reading the documentation I came up with the following two ways:

ORDERING

class Level1 {
  Class['Level2']->Class[Level1']
  package { "A":
    ensure => "installed"
  }
}

class Level2 {
  include Level3
  package { "B":
    ensure => "installed"
  }
}

class Level3 {
  package { "C":
    ensure => "installed"
  }
}

according to the documentation

-> (ordering arrow) Causes the resource on the left to be applied before the resource on the right. Written with a hyphen and a greater-than sign.

I expect the following to happen:

  • Level2 is called before Level1
  • package B or C get installed (order can be random because it was not specified)
  • package A gets installed.

REQUIRE

class Level1 {

  require Level2
  package { "A":
    ensure => "installed"
  }

}

class Level2 {
  require Level3
  package { "B":
    ensure => "installed"
  }
}

class Level3 {
  package { "C":
    ensure => "installed"
  }
}

According to the documentation

cause every resource in the required classes to be applied before any of the resources in the requiring class.

I expect the following to happen:

  • Level3 is called by Level2
  • package C gets installed
  • Level2 is called by Level1
  • package B gets installed
  • package A gets installed

alternative ORDERING

class Level1 {
  Class['Level3']->Class['Level2']->Class[Level1']
  package { "A":
    ensure => "installed"
  }
}

class Level2 {
  package { "B":
    ensure => "installed"
  }
}

class Level3 {
  package { "C":
    ensure => "installed"
  }
}
  • level 1 is needed by level 2
  • level 2 is needed by level 3
  • package C gets installed
  • package B gets installed
  • package A gets installed

Are my assumptions and conclusions correct? I've been messing with these kind of dependencies for a while now and they don't seem to behave how I imagine them to behave. Maybe I'm missing something when it comes to the usage of require and -> when used with classes. Any feedback is appreciated!!

EDIT1

staging seems to be a good mechanism for fixing the dependency between two classes (see here), since you have to manually define the stage dependencies between each class pair. How would you use staging with three or four class levels?

EDIT2

Consider this more realistic case, where classes a used as wrappers to install multiple packages at the same time.

Every node is loading some pre-defined role:

node 'some-host' {
    include role::processing_machine
}

the role is defined as follows:

class role::processing_machine {

    include role::ubuntu_desktop_standard_software
    include xorg::lts_12_04_quantal
    include software::standard_packages


    # define order in which classes should be executed
    Class["role::ubuntu_desktop_standard_software"] -> Class["xorg::lts_12_04_quantal"] -> Class["software::standard_packages"] -> Class["role::processing_machine"] 

}

and here's the role::ubuntu_desktop_standard_software definition:

class role::ubuntu_desktop_standard_software {
    include role
    include profile::ubuntu_desktop
    include role::server::no_apache

    # define order in which classes should be executed.
    Class["role"] -> Class["profile::ubuntu_desktop"] -> Class["role::server::no_apache"] -> Class["role::ubuntu_desktop_standard_software"]

}

As you can see, I'm trying to chain multiple classes so that they get executed in a particular order (Class["a"] -> Class["b"]). Previously I've only used include in my classes but puppet would execute the include commands in arbitrary order, so that some commands (which have to run first!) wouldn't run first.

Despite these chaining efforts it still seems like puppet is executing the classes random fashion. What am I doing wrong? Is there a cleaner / better way of defining nodes so that I can be sure they are deployed in a particular, predefined way?

È stato utile?

Soluzione

Here is an example :

 class L {
   package { "C" :
      ensure => installed,
      require => Package["A", "B",],
   }

   package { "B" :
      ensure => installed,
      require => Package["A"],
   }

   package { "A" :
      ensure => installed,
   }
 }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top