Let me explain my problem in detail.
As part of my chef run, i install Microsoft Visual Studio 2012 followed by the installation of Microsoft Visual Studio 2015.
I have two cookbooks: one for Microsoft Visual Studio 2012 and one for Microsoft Visual Studio 2015
Composition of the cookbook for Microsoft Visual Studio 2015
In the libraries/helper.rb file of this cookbook, i have the following code defined
require 'chef/version_constraint’
require ‘win32/registry’
module Ctx_VisualStudio
module Helper
def self.is_vs_installed?(vsDetectionRegKey)
#File.exists?(File.join(node['vs-2015']['install_dir'], '\Common7\IDE\devenv.exe'))
if(!registry_key_exists?(vsDetectionRegKey,:i386))
Chef::Log.info("The registry key #{vsDetectionKey} does not exist.")
return false
end
registry_data_exists?(
vsDetectionRegKey,
{:name => 'Install', :type => :dword, :data => 1},
:i386
)
end
def self.get_sp_version(vsVersion)
Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\DevDiv\vs\Servicing\#{vsVersion}\enterprise') do |reg|
reg_val = reg['UpdateVersion']
return reg_val
end
end
def self.is_sp_installed?(vsDetectionRegKey,vsVersion,reqSpVersion)
if(!is_vs_installed?(vsDetectionRegKey))
return false
end
sp_version = get_sp_version(vsVersion)
Chef::Log.info("The installed version of the service pack is:#{sp_version}")
Chef::VersionConstraint.new(">= #{reqSpVersion}").include?(sp_version)
end
end
end
Chef::Recipe.send(:include, Ctx_VisualStudio::Helper)
Chef::Resource.send(:include, Ctx_VisualStudio::Helper)
These functions are used to detect the presence of the requisite version of Visual Studio, check if the correct service pack is installed for Visual Studio etc.
My recipes directory in the Microsoft Visual Studio 2015 has the following files:
recipes/defaul.rb
recipes/install.rb
recipes/install_update.rb
The code for default.rb looks as follows:
include_recipe ‘vs-2015::dotnet_prereq’
# We require 7-zip in order to extract the ISOs
include_recipe 'seven_zip'
# Enable/disable Nuget package restore
include_recipe 'vs-2015::nuget'
# Install VS
include_recipe 'vs-2015::install
I can successfully make use of the library functions defined in the libraries/helper.rb, in install.rb as well as install_update.rb of Microsoft Visual Studio 2015. This is not an issue as the library functions are defined in the libraries/helper.rb of the same cookbook.
The problem arises when i try to make use of the library functions in the cookbook for Microsoft Visual Studio 2015 in the cookbook for Microsoft Visual Studio 2012.
The structure of the cookbook for Microsoft Visual Studio 2012 is identical to the structure of the cookbook for Microsoft Visual Studio 2015.
What i am trying to do is , in the install.rb and install_update.rb files of the cookbook for Microsoft Visual Studio 2012, i try to access the functions defined in libraries/helper.rb of Microsoft Visual Studio 2015.
The install.rb file of Microsoft Visual Studio 2012, from where i try to consume the library functions in Microsoft Visual Studio 2015 has the following code:
# Ensure the installation ISO url has been set by the user
if !node['vs-2012']['source']
raise 'visualstudio source attribute must be set before running this cookbook'
end
Chef::Log.info("Starting Visual Studio #{node['vs-2012']['year']} installation. ")
edition = node['vs-2012']['edition']
vsDetectionRegKey = node['vs-2012']['premium']['detection_regkey']
install_url = File.join(node['vs-2012']['source'], node['vs-2012'][edition]['filename'])
cache_iso = win_friendly_path(File.join(Chef::Config[:file_cache_path], node['vs-2012'][edition]['filename']))
install_log_file = win_friendly_path(
File.join(node['vs-2012']['install_dir'], 'vsinstall.log'))
iso_extraction_dir = win_friendly_path(File.join(Chef::Config[:file_cache_path], node['vs-2012']['version']))
setup_exe_path = File.join(iso_extraction_dir, node['vs-2012'][edition]['installer_file'])
admin_deployment_xml_file = win_friendly_path(File.join(iso_extraction_dir, 'AdminDeployment.xml'))
# Extract the ISO image to the tmp dir
seven_zip_archive "extract_#{node['vs-2012']['version']}_iso" do
path iso_extraction_dir
source install_url
overwrite true
checksum node['vs-2012'][edition]['checksum']
not_if { Ctx_VisualStudio::Helper.is_vs_installed?(vsDetectionRegKey) }
end
# Create installation config file
#cookbook_file admin_deployment_xml_file do
# source 'AdminDeployment-' + edition + '.xml'
# action :create
#not_if { vs_is_installed }
#end
# This allows us to use recipe to install other versions of Visual Studio such as 2013.
# This allows an user to specify their custom AdminDeployment.xml from anywhere such as Visual Studio 2013.
# By default this doesn't gets executed if you don't define in a role or attributes file the a value for node['vs-2012']['admin_deployment_xml_file_src']
if node['vs-2012']['admin_deployment_xml_file_src']
remote_file admin_deployment_xml_file do
source node['vs-2012']['admin_deployment_xml_file_src']
checksum node['vs-2012']['admin_deployment_xml_file_checksum']
action :create
not_if {Ctx_VisualStudio::Helper.is_vs_installed?(vsDetectionRegKey)}
end
end
# Install Visual Studio
#windows_package node['vs-2012'][edition]['package_name'] do
# source setup_exe_path
# installer_type :custom
# options "/Q /norestart /Log \"#{install_log_file}\" /AdminFile \"#{admin_deployment_xml_file}\""
# notifies :delete, "directory[#{iso_extraction_dir}]", :immediately
# notifies :delete, "file[#{cache_iso}]", :immediately
#success_codes [0, 127, 3010]
# timeout node['vs-2012']['timeout'] # 1hour
# not_if { vs_is_installed }
#end
# Install Visual Studio
#There is no way to capture the exit codes from the previously used Chef resource: windows_package
#The windows_package resource internally uses the Mixlib::ShellOut class.
#Hence, i am using the same class explicitly and capturing the status of the execution from the exitstatus member.
ruby_block "Installing Microsoft Visual Studio Premium 2012" do
block do
cmd = Mixlib::ShellOut.new("#{setup_exe_path} /Q /NoRestart /Log \"#{install_log_file}\" /AdminFile \"#{admin_deployment_xml_file}\"")
cmd.timeout = node['vs-2012']['timeout']
cmd.run_command
#Check for the exit codes here
case
when cmd.exitstatus == 0
Chef::Log.info("Successful installation.")
when cmd.exitstatus == 3010
Chef::Log.info("Successful installation.")
Chef::Log.warn("Please reboot the system after a successful run of Install-BuildMachine.ps1")
when cmd.exitstatus == -2147205120
Chef::Log.error("Installation is blocked.")
Chef::Log.error("More information can be found in the log file:#{install_log_file}")
raise
when cmd.exitstatus == -2147172352
Chef::Log.error("Installation is blocked due to a pending reboot.")
Chef::Log.error("Please reboot the system and execute Install-BuildMachine.ps1 to continue with the installation.")
raise
when cmd.exitstatus == -2147185721
Chef::Log.error("Restart is required before installation can continue.")
Chef::Log.error("The installation of Visual Studio 2015 Enterprise with Update 3 will resume after a reboot.")
raise
else
Chef::Log.fatal("There was an error installing Visual Studio Enterprise 2015 with Update 3.")
Chef::Log.fatal("More information can be found in the log file:#{install_log_file}. Exit code:#{cmd.exitstatus}")
raise
end
end
notifies :delete, "directory[#{iso_extraction_dir}]", :immediately
notifies :delete, "file[#{cache_iso}]", :immediately
not_if {Ctx_VisualStudio::Helper.is_vs_installed?(vsDetectionRegKey)}
end
# Cleanup extracted ISO files from tmp dir
directory iso_extraction_dir do
action :nothing
recursive true
not_if { node['vs-2012']['preserve_extracted_files'] }
end
file cache_iso do
action :nothing
backup false
not_if { node['vs-2012']['preserve_cache_iso']}
end
When i try to do that, i am blocked with the following error:
NoMethodError
-------------
undefined method `registry_key_exists?’ for Chef::DSL::RegistryHelper:Module
What am i doing wrong here?
In the metadata.rb of Microsoft Visual Studio 2012 cookbook, i have introduced a dependency on the cookbook for Microsoft Visual Studio 2015.
Any pointers would be very much appreciated.