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

puppetlabs-postgresql: как правильно установить глобальные переменные без повторяющихся определений

В документации puppetlabs-postgresql рекомендуется устанавливать значения в postgresql :: globals следующим образом:

class { 'postgresql::globals':
  encoding => 'UTF8',
  locale   => 'en_NG',
}->
class { 'postgresql::server':
}

Однако это не работает:

class { 'postgresql::client: }
class { 'postgresql::globals':
  encoding => 'UTF8',
  locale   => 'en_NG',
}->
class { 'postgresql::server':
}

Поскольку postgresql :: client наследуется от postgresql :: parameters, который наследуется от postgresql :: globals. Поэтому, когда доходит до явного создания экземпляра класса postgresql :: globals, он жалуется на повторяющееся определение.

меняя порядок, он работает:

class { 'postgresql::globals':
  encoding => 'UTF8',
  locale   => 'en_NG',
}->
class { 'postgresql::server':
}
class { 'postgresql::client: }

Однако на практике мои экземпляры postgresql :: client и postgresql :: server находятся в разных классах, связанных с классами серверов, которые я использую, и я действительно не хочу создавать требуемый порядок для этих классов. Кроме того, я хочу, чтобы определения глобальных переменных применялись к postgresql :: client даже на серверах, на которых не запущен postgresql :: server.

Если бы мы использовали марионетку 3.x, я бы определил необходимые глобальные значения в hiera, но мы все еще находимся на марионетке 2.7.

Есть ли способ исправить это, не изменяя распределение puppetlabs? В настоящее время я думаю, что это может потребовать сообщения об ошибке в марионеточные лаборатории, но все же задаюсь вопросом, не хватает ли мне простого решения.

РЕДАКТИРОВАТЬ: прочитав ввод @FelixFrank, я создал отчет об ошибке на https://tickets.puppetlabs.com/browse/MODULES-1466.

Да, Hiera было бы лучшим решением. Обратите внимание, что вы можете (и должны) добавить Hiera в Pupet 2.7.x в виде плагина.

За исключением этого, ваши возможности ограничены. В require отношения между любыми двумя классами не буду иметь эффект. Напротив, обратите внимание, что следующий рефакторинг вашего рабочего манифеста также приводит к вашей ошибке:

class { 'postgresql::server': }
<-
class { 'postgresql::globals':
    encoding => 'UTF8',
    locale   => 'en_NG',
}

Причина в том, что проблема основана на порядок анализа или порядок оценки - порядок, в котором компилятор манифеста встречает объявления классов. В require/before параметры (и соединяющие стрелки) только добавляют отношения к создаваемому каталогу для использования puppet agent.

По сути, вам нужно будет убедиться, что ваш собственный серверный класс PostgreSQL всегда оценивается перед клиентским классом, например

role::posgre_server_with_client {
    include profiles::postgre_server
    include profiles::postgre_client
}

Такой порядок не всегда может быть гарантирован в сложных манифестах (что может include особенно клиентская функциональность из множества контекстов). Таким образом, я думаю, что есть веские основания объявлять это ошибкой в ​​модуле. Поскольку паттерны, которые приводят к проблеме, довольно распространены (я думаю), может быть причина поставить под сомнение текущую практику проектирования модулей в целом.

Я постараюсь собрать еще несколько мнений сообщества по этому поводу.