Zamieszanie dziedziczenia klas lalek

6

Przeczytałem dokumentację dotyczącą zakresu, ale nadal mam problemy z jej rozwiązaniem. Mam dwa środowiska, które są bardzo podobne - więc mam:

moduły / django-env / manifests / init.pp

class django-env {
    package { "python26":
        ensure => installed
    }
    # etc ...
}
import "er.pp"

moduły / django-env / manifests / er.pp

$venvname = "er"
$venvpath = "/home/django/virtualenvs"

class er {
    file { "$venvpath/$venvname" :
        ensure => directory
    }
    # etc ...
}
class er-dev {
    include er
}
class er-bce-dev {
    $venvname = "er-bce"
    include er
}

manifests / modules.pp

import "django-env"

manifests / nodes.pp

node default {
    # etc ...
}
node 'centos-dev' imports default {
    include django-env
    include er-bce-dev
    include er-dev
}

Rezultat jest taki, że „dziedziczenie” działa - ale działa tylko pierwszy element „er-” w węźle „centos-dev”, albo dostaję er-bce-dev lub er-dev, ale nie oba. Musi tu być podstawowa rzecz, której nie rozumiem.

Czy to jest różnica między importem a dołączeniem ? (nie jestem pewien, czy to rozumiem)

EMiller
źródło
IIRC FAQ marionetki zawierało element stwierdzający, że dziedziczenie węzłów ma problemy i nie powinno być używane. Ale teraz FAQ poruszyło i zgubiło tę informację po drodze.
ptman

Odpowiedzi:

11

Puppet nie obsługuje tego rodzaju konfiguracji, ale ograniczenie można łatwo ominąć. Powodem są dwie podstawowe „zasady” marionetek:

  1. Klasę można dołączyć tylko raz (kolejne dołączenia -statements nic nie zrobią)
  2. Kolejność wykonywania nie jest ściśle określona, ​​a nawet może być losowa

er-devi er-bce-devoba obejmują klasę er. Ale klasa nie może być dołączona dwa razy, więc erklasa jest wykonywana tylko z wartością domyślną $venvname = "er"lub z przesłonięciem $venvname = "er-dev", ale nie z obydwoma.

Rozwiązanie: zmień erklasę na definicję (patrz „Definicje” z samouczka języka kukiełkowego ( http://docs.puppetlabs.com/guides/language_tutorial.html )):

moduły / django-env / manifests / er.pp

# Create new er resource definition
define django-env::er($vpath="/home/django/virtualenvs", $vname="er") {
    file { "$vpath/$vname" :
        ensure => directory
    }
    # etc ...
}

Nie potrzebujemy zmiennych $venvnamei $venvpath, są one określone jako wartości domyślne w definicji. Nazwa django-env::erdodaje definicję do django-envprzestrzeni nazw i umożliwia automatyczny import (patrz poniżej).

Importuj i dołączaj

Różnica pomiędzy importi includestatemens jest:

  • import współpracuje z plikami i nie wykonuje klas
  • include wykonuje zajęcia
  • pliki muszą zostać zaimportowane, aby można było uwzględnić klasy

Uwaga: istnieje bardzo silny wyjątek od ostatniej reguły: wyszukiwanie modułu marionetek . includeinstrukcja wykonuje automatyczny import w wielu sytuacjach. Tutaj jest kilka z nich:

  • include foo próbuje zaimportować plik module_dir/foo/manifests/init.pp
  • include foo::bar import module_dir/foo/manifests/bar.pp

Dzięki tym automatycznym importom i definicji zasobów możesz bardzo łatwo zdefiniować wiele środowisk wirtualnych. Zmień node 'centos-dev':

node 'centos-dev' imports default {
    include django-env
    # The er resource with default values:
    django-env::er { 'er-bce': }
    # Another er resource with different environment name:
    django-env::er { 'er-bce-dev': vname => 'bce-dev'}
}

I możesz usunąć w zasadzie wszystkie importinstrukcje dotyczące django-envmodułu.

Happy Puppeting!

Mikko
źródło
Czy nie powinno być inheritszamiast imports default? inheritsjest również przestarzałe, ale przynajmniej jest to poprawna składnia.
Tombart
0

Składnia marionetek ewoluowała, od Puppet 3.7 pojawi się wiele ostrzeżeń o rezygnacji. Słowa kluczowe importi inheritssą przestarzałe. Zamiast używać układu takiego jak:

 /etc/puppet
   /manifests
      /nodes
      site.pp
   /modules
   puppet.conf

Powinieneś użyć:

 /etc/puppet
   /environments
     /production
       /manifests
          01_base_node.pp
       /modules
       environment.conf
   puppet.conf

Zamiast używać tradycyjnej site.ppkonfiguracji:

import 'nodes/*.pp'

node default {
   classs{'ntp': }
}

powinieneś użyć standardowego class(ale nie możesz go nazwać, class defaultponieważ jest to słowo zastrzeżone ) pliku manifets/01_common.pp:

class common {
  classs{'ntp': }
}

Pliki są ładowane w kolejności alfabetycznej, dlatego najpierw należy załadować „klasy podstawowe” (dobrym pomysłem może być numeracja).

Następnie zamiast definiować węzeł, taki jak:

node /^web\d+/ inherits default {
}

użyj raczej (rozwiązuje klasyczny problem wielokrotnego dziedziczenia, tzw. problem diamentów ), np. zdefiniowany wmanifests/web.pp

node /^web\d+/ {
  include common
  # include something_else   
}
Tombart
źródło