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

Как написать определения марионеток, которые можно использовать повторно?

Я хотел бы написать марионеточный манифест для установки и настройки приложения на целевых серверах.

Части этого манифеста подлежат повторному использованию. Таким образом я использовал define для определения моей многоразовой функциональности. При этом у меня всегда проблема с тем, что есть части определения, которые нельзя использовать повторно.

Простой пример - это набор файлов конфигурации, которые необходимо создать. Эти файлы должны быть помещены в тот же каталог. Этот каталог необходимо создать только один раз.

Пример:

node.pp

node 'myNode.in.a.domain' {
  mymodule::addconfig {'configfile1.xml':
    param => 'somevalue',
  }
  mymodule::addconfig {'configfile2.xml':
    param => 'someothervalue',
  }
}

mymodule.pp

define mymodule::addconfig ($param) {

  $config_dir = "/the/directory/"

  #ensure that directory exits:
  file { $config_dir:
    ensure  => directory,
  }

  #create the configuration file:     
  file { $name:
    path    => "${config_dir}/${name}"
    content => template('a_template.erb'),
    require => File[$config_dir],
  }
}

Этот пример будет потерпеть поражение, потому что теперь ресурс file {$config_dir: определяется дважды.

Насколько я понял, требуется извлечь эти части в class. Тогда это выглядит так:

node.pp

node 'myNode.in.a.domain' {

  class { 'mymodule::createConfigurationDirectory':
  }

  mymodule::addconfig {'configfile1.xml':
    param => 'somevalue',
    require => Class ['mymodule::createConfigurationDirectory'],
  }
  mymodule::addconfig {'configfile2.xml':
    param => 'someothervalue',
    require => Class ['mymodule::createConfigurationDirectory'],
  }
}

Но это затрудняет использование моего интерфейса. Каждый пользователь моего модуля должен знать, что есть дополнительный класс. Для этого простого случая использования дополнительный класс может быть приемлемым. Но с ростом сложности модуля (много определений) я немного боюсь запутать пользователя модуля.

Итак, я хотел бы знать, есть ли лучший способ справиться с этими зависимостями. В идеале классы вроде createConfigurationDirectory скрыты от пользователя модулей api.

Или есть какие-то другие "лучшие практики" / шаблоны для обработки таких зависимостей?

Разбейте весь функционал на отдельные файлы внутри модуля каждый файл, содержащий один класс или определенный тип. Использовать ресурс заказ управлять ресурсами в правильном порядке.

В определении вашего узла:

class {'mymodule':
  conffile => 'file_name',
}

В каталоге манифеста вашего модуля:

init.pp:

# This class does basic setup,
# and optionally allows you to define a config file
class mymodule ( $conffile = undef ) {
  include mymodule::confdir

  if $conffile {
    mymodule::conffile { $conffile: }
  }
}

params.pp:

# This class defines variables
class mymodule::params {
  $confdir = '/path/to/dir'
}

confdir.pp:

# This class creates a conf dir
class mymodule::confdir {
  include mymodule::params

  file { $mymodule::params::confdir:
    ensure = directory,
  }
}

conffile.pp:

# This define creates a config file
define mymodule::conffile($file=$title) {
  include mymodule::params

  file { "${mymodule::params::confdir}/${file}":
    ensure  => present,
    require => Class['mymodule::confdir'],
  }
}

Лучше всего, если вы можете вынуть каталог config из файла define. Это пример

class def($config_dir) {
    file { $config_dir:
        ensure => directory
     }   
}

define def::template($file_location) {
     file { $file_location:
         path    => "${def::config_dir}/${file_location}",
         content => 'hi',
         require => Class['def'],
     }   
 }
if $fqdn == 'my_host' {
    class { 'def':
            config_dir => '/tmp/d1'
        }   
    def::template { 'f1.txt':
        file_location => "f1.txt"
    }   
    def::template { 'f2.txt':
        file_location => "f2.txt"
    }   
}

ls  /tmp/d1/
f1.txt  f2.txt