Chefspec отключает Win32 :: Service в Linux

#linux #winapi #chef-infra #chefspec

#linux #winapi #шеф-повар-инфра #chefspec

Вопрос:

Наша кулинарная книга используется как на компьютерах с Linux, так и на Windows, и когда она запускается / сходится, код отлично работает на системах обоих типов. Однако модульный тест rake не выполняется в Linux. В моем рецепте у меня есть:

 service 'MyService' do
  action %i[enable start]
  only_if { ::Win32::Service.exists?("MyService") }
  not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
  

Ошибка, которую мы получаем, это:

Сбои:

  1. perfagent::install_windows При установке агента установки в Windows успешно сходится Сбой / ошибка: ожидайте { chef_run }.to_not raise_error

    не ожидал исключения, получил #<Ошибка имени: неинициализированная константа Win32> с обратным отслеживанием: # /tmp/chefspec20200924-2530-350e0zfile_cache_path/cookbooks/perfagent/resources/install_agent.rb:83:в `блоке (3 уровня) в class_from_file’

Возможно ли только для систем Linux подставить значение в моем файле спецификации для «only_if» выше, чтобы мой модульный тест rake был успешным всякий раз, когда мы запускаем rakes в Linux?


Обновить:

Поскольку поваренная книга выполняется как в системах Linux, так и в Windows, у нас есть проверка на ранних этапах выполнения поваренной книги, например:

 if node['platform_family'] == 'windows'
  include_recipe 'cookbook::install_windows'
elsif node['platform_family'] == 'rhel'
  include_recipe 'cookbook::install_linux'
else
  log "This OS family (#{node['platform_family']})  is not supported" do
    level :info
  end
end
  

Это означает, что кулинарная книга вызывает только соответствующие рецепты в зависимости от platform_family. Однако, когда мы запускаем rake unit в Linux, мы получаем указанную выше ошибку, а в Windows rake завершается успешно.

Я попытался добавить:

 allow(::Win32::Service).to receive(:exists?).with(windows_service[:name]).and_return(true)
  

в файл спецификации, но это по-прежнему приводит к сбою в Linux и приводит к сбою модуля Windows rake.

Ответ №1:

В случае вложенных классов заглушение немного сложнее. Вам также необходимо заглушить сам класс. Используйте stub_const для этого RSpec:

 let :subject do
  fake_win32 = Class.new
  stub_const('Win32::Service', fake_win32)
  allow(fake_win32).to receive(:exists?).and_return false
  ChefSpec::Runner.new(platform: 'windows', version: '2008R2').converge described_recipe
end
  

Комментарии:

1. Фантастика. Работает отлично. Модуль rake теперь успешно работает как в Linux, так и в Windows. Большое спасибо.

Ответ №2:

Можно использовать if условия внутри ресурсов Chef. Я не уверен, что элегантно использовать условные обозначения для охранников, таких как only_if или not_if (сами условные обозначения).

Но вы могли бы сделать что-то вроде приведенного ниже:

 service 'MyService' do
  action %i[enable start]
  if node['platform'] == 'windows'
    only_if { ::Win32::Service.exists?("MyService") }
  end
  not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
  

Если ваша платформа операционной системы является windows единственной, тогда only_if будет проверена защита.


Обновить:

Другой вариант — установить имя службы в соответствии с платформой и избавиться от only_if guard. Что-то вроде этого:

 # Set the service name appropriate to platform
svc_name = case node['platform']
when 'windows'
  'MyService'
when 'linux'
  'my-service'
end

# Then use the service name that was set:
service svc_name do
  action [ :enable, :start ]
  not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
  

Комментарии:

1. К сожалению, я уже пробовал это, и я получаю ту же ошибку … 🙁

2. Другой вариант — заранее задать имя службы в зависимости от платформы и использовать это имя в service <name> do .

3. Добавлено обновление, дающее представление о том, как в кулинарной книге выполняется рассматриваемый рецепт. Также пытался добавить «разрешить (Win32:: Service).получать (:существует?).с помощью (windows_service [:name]).and_return (true)» в файл спецификации, но в Linux это по-прежнему не удается.