#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
Ошибка, которую мы получаем, это:
Сбои:
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 это по-прежнему не удается.