Назад | Перейти на главную страницу

Путаница наследования классов марионетки

Я прочитал документацию по области применения, но мне все еще не удается решить эту проблему. У меня есть две очень похожие среды, поэтому у меня есть:

модули / django-env / манифесты / init.pp

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

модули / django-env / манифесты / 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
}

манифесты / modules.pp

import "django-env"

манифесты / nodes.pp

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

В результате "наследование" работает - но действует только первый элемент "er-" в узле 'centos-dev', я получаю либо er-bce-dev, либо er-dev, но не оба сразу. Должна быть какая-то основная вещь, которую я здесь неправильно понимаю.

Это разница между Импортировать и включают ? (не уверен, что понимаю это)

Puppet не поддерживает такую ​​конфигурацию, но ограничение можно легко обойти. Причина в двух основных «правилах» марионеток:

  1. Класс может быть включен только один раз (последующие инструкции include ничего не сделают)
  2. Порядок выполнения строго не определен и даже может быть случайным.

er-dev и er-bce-dev оба включают класс er. Но класс не может быть включен два раза, поэтому er класс выполняется только со значением по умолчанию $venvname = "er", или с переопределенным $venvname = "er-dev", но не то и другое одновременно.

Решение: изменить er класс в определение (см. «Определения» в Руководстве по языку марионеток (http://docs.puppetlabs.com/guides/language_tutorial.html)):

модули / django-env / манифесты / er.pp

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

Нам не нужен $venvname и $venvpath переменные, они указаны как значения по умолчанию в определении. Имя django-env::er добавляет определение в django-env пространство имен и разрешает автоматический импорт (см. ниже).

Импортировать и включить

Разница между import и include statemens это:

  • import работает с файлами и не выполняет классы
  • include проводит занятия
  • файлы должны быть импортированы, прежде чем классы могут быть включены

Примечание: из последнего правила есть очень сильное исключение: Поиск модуля марионетки. include оператор выполняет автоматический импорт во многих ситуациях. Вот некоторые из них:

  • include foo пытается импортировать файл module_dir/foo/manifests/init.pp
  • include foo::bar импорт module_dir/foo/manifests/bar.pp

С помощью этого автоматического импорта и определения ресурсов вы можете очень легко определить несколько виртуальных сред. + Изменить 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'}
}

И вы можете удалить практически все import заявления с учетом django-env модуль.

Счастливого марионетки!

Синтаксис Puppet эволюционировал, начиная с Puppet 3.7 вы будете получать много предупреждений об устаревании. Ключевые слова import и inherits устарели. Вместо использования такого макета:

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

Вам следует использовать:

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

Вместо использования традиционных site.pp config:

import 'nodes/*.pp'

node default {
   classs{'ntp': }
}

вы должны использовать стандартные class (но ты не можешь это назвать class default как это зарезервированное слово), файл manifets/01_common.pp:

class common {
  classs{'ntp': }
}

Файлы загружаются в алфавитном порядке, поэтому вы должны убедиться, что «базовые классы» будут загружены первыми (нумерация может быть хорошей идеей).

Тогда вместо определения узла вроде:

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

используйте скорее (решает классическую проблему множественного наследования, так называемую проблема с алмазом), например определено в manifests/web.pp

node /^web\d+/ {
  include common
  # include something_else   
}