Написание класса Ruby внутри Chef Recipe

Я пытаюсь «очистить» свой рецепт Chef для установки агента Zabbix, я знаю, что их там миллион, но это мой тестовый пример для моего понимания. У меня есть инструкции Chef, разделенные на класс и отдельные методы для каждого шага, который необходимо выполнить. Я поместил класс в файл рецепта. Итак, когда я выполняю рецепт, ссылка на него на GitHub, Я получаю эту ошибку:

NoMethodError
-------------
undefined method `execute' for #<Class:0x000000030e42c0>::Recipe_Zabbix_Agent_Unix

Я ни в коем случае не гуру Ruby, поэтому я подумал про себя, держу пари, что этот класс «отделяет» себя от наследования Chef, поэтому мне нужно, чтобы класс наследовал библиотеки Chef, используя < вещь. Тем не менее, я все еще получаю эту ошибку, указанную выше. Что я упускаю или не понимаю, когда пытаюсь это сделать? Я видел, как люди пишут библиотеку, которая в основном представляет собой просто скрипт Ruby, затем рецепт включает скрипт и выполняет там функции, но я хотел, чтобы он содержался только в рецепте для моего простого понимания. Возможно ли это или это единственный вариант, который я рассматриваю для маршрута библиотеки? Я также запускаю это на Chef 10.24.


person FilBot3    schedule 28.02.2014    source источник
comment
У вас нет доступа к Chef DSL у крупных провайдеров.   -  person sethvargo    schedule 01.03.2014
comment
Как бы я унаследовал этих провайдеров?   -  person FilBot3    schedule 01.03.2014
comment
Используйте форму класса execute = Chef::Resource::Execute.new(command)   -  person sethvargo    schedule 01.03.2014
comment
Должен ли я делать это для каждого блока Chef внутри того класса Ruby, который я туда поместил?   -  person FilBot3    schedule 02.03.2014
comment
Да, вы должны были бы сделать это.   -  person sethvargo    schedule 02.03.2014
comment
@sethvargo вам нужно сделать execute.run или что-то подобное ??   -  person vikingsteve    schedule 23.08.2016


Ответы (2)


Как правило, ресурсы на основе классов хранятся в файле библиотеки, а не в рецепте. См. https://github.com/poise/berkshelf-api/blob/master/libraries/berkshelf_api.rb для примера использования Poise для получения элементов LWRP DSL в вашем ресурсе на основе классов.

person coderanger    schedule 01.03.2014
comment
Итак, я бы написал свой класс в виде файла библиотеки, затем потребовал или включил его, а затем вызвал из него функции, которые я хочу? - person FilBot3; 02.03.2014
comment
Все файлы библиотеки поваренных книг автоматически загружаются Chef в самом начале конвергенции. - person coderanger; 05.03.2014
comment
Я думаю, что и вы, и @sethvargo правы, потому что с тем, что я пытаюсь сделать, мне пришлось бы делать то, что он говорит, и назначать функцию Chef для выполнения объекта и т. д. внутри моего класса, и мой класс принадлежит к библиотека. Поскольку я пытаюсь вызывать функции Chef в своем классе, я собираюсь сначала попробовать идею sethvargo, а затем попытаться поместить свой код в папку библиотеки. - person FilBot3; 06.03.2014
comment
@Pred как все прошло? - person vikingsteve; 23.08.2016
comment
Думаю, я подвел тебя, @vikingsteve. В итоге я отказался от идеи класса и просто использовал функции. Если вы проверите код, который я связал, я просто объявлю некоторые def. - person FilBot3; 23.08.2016

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

In libraries/useful_thing.rb:

class UsefulThing
  def initialize(blah)
    @blah = blah
  end

  def apply(recipe)
    # Chef resources use instance_eval for blocks, which hides self
    outer_self = self
    recipe.directory "/foo/#{@blah}" do
        user ...
        group outer_self.latest_group
        ...
    end
    ...
  end

  ...
end

затем в recipes/default.rb:

ut = UsefulThing.new(...)
ut.apply(self)
person andrewdotn    schedule 13.09.2017