Does Chef really just try to re-install software to check state?

Trying to understand exactly how chef server validates installed apps for a given node and it appears it just tries to run the cookbook and perform the silent install letting the application installer report back whether it is installed or not?

It looks like it will do this every 30mins by default via the scheduled task choice when the client is installed?

What is the point of the Ohai gathered attributes, is there any validation of those items? Does it make any attempt to validate the attributes in the attribute file or data bags?

The way that Chef Infra works is that the chef-client runs and gathers Ohai data from the node. The client compares the state of resources ( against what the desired state is as defined by the cookbooks applied to that node. This is a "test-and-repair" model that is idempotent; meaning that if the running state of a resource matches the desired state, the client skips applying the resource. This is not the same as repeatedly attempting to execute an install script that does not have any awareness of state. I think it would be helpful for you to go through a few of our free Learn Chef Rally modules that walk you through what each part of the Chef stack does and how they relate to each other in enforcing and validating desired state. Here is a link to our training site:

I am using the 'sql_server' cookbook downloaded from the Chef marketplace, which uses the 'package' resource:

package ssms_pkg_name do # ~FC009
	  only_if { ssms_feature = true }
	  source ssms_src_url
	  timeout 1500
	  installer_type :custom
	  options "/#{node['cs_sql_server']['setup_action']} /quiet /norestart /log #{ssms_log}"
	  action :install
	  returns [0, 1641, 3010]

There are several SQL related packages showing installed within the Ohai data:

I don't see anything linked between the components of the sql_server 'package' resource and the Ohai package data. So, how is chef-infra determining that the running version from the Ohai data is what was intended from the 'package' resource?

@jnalewak In addition, the SQL setup.exe program shows up in task manager during the Chef client check every 30 minutes, and if I add the flag to show the screens in the options string, you can see the SQL installer window open so it is trying to reinstall. The installer is passing back something to chef that indicates it is installed because the cookbook completes all resources green showing SQL is installed.

I have tried using windows_package resource to no avail. I get the warning message that it is being deprecated and to use the package resource instead, which is why the author of this cookbook uses that resource. I did try to use the windows_package instead but the installer_type: custom did not support setup.exe as MS SQL Install is not an .msi, I could not get it to run the executable successfully with many different component changes.

@jnalewak I posted on the sql_server cookbook git hub issue and @TheLunaticScripter replyed and said instead of using the server.rb recipe, I should call the install.rb custom resource and wrap it like so:

sql_server_install "Install SQL Server #{node['sql_server']['version']}" do
  source_url "C:\\Sources\\SQL_#{node['sql_server']['version']}\\setup.exe"
  version node['sql_server']['version']
  package_checksum node['sql_server']['server']['checksum']
  accept_eula true
  instance_name 'MSSQLSERVER'
  netfx35_install false if node['sql_server']['version'] == 2016
  feature %w(SQLENGINE)

However, I don't see how that will match any of the Ohai data for installed programs related to SQL Server either. How will this skip the resource and not try to just re-install SQL???


The magic is inside of the package resource. sql_server_install is a custom resource that calls the package resource:
which behaves in this way:

Inside of that is the check where it compares the product code to what the system reports. There are some installers that either don't update this for sub-versions of their products, or otherwise give it bad data. In those cases you can use a guard to query some aspect of system state to determine if the resource should run.

The ohai data is gathered at the start of a Chef Client run and is used to drive behavior during the run (what platform are we on, what disks do we have, are we on Amazon or Azure, etc). It is not used for a version check as it is possible things changed since Ohai ran. So the package resource does the check in real time to determine if it needs to install the package.

@Galen_Emery1 Right, so I updated my recipe to call that install name from the registry key and the programs and features entry using package.

package 'Microsoft SQL Server 2016(64-bit)' do
  installer_type :custom
  source package_url
  options "/Q /ACTION=#{node['cs_sql_server']['setup_action']} #{passwords_options} /ConfigurationFile=#{config_file_path} /IAcceptSQLServerLicenseTerms=#{node['cs_sql_server']['accept_eula']}"
  action :install
  returns [0, -2068643838, -2147467259, 42, 127, 3010]

It still tries to reinstall sql by executing the setup.exe again on the next client run:

I don't see a requirement for the wrapper if the wrapper is going to call package anyway??

@jnalewak @Galen_Emery1
I created my recipe off the install.rb resource. It pulls the properties from data bags and attributes file; I skip DREPLAY_CLT, security mode check and netfx35 checks; I do use config_file_path, x86_64 and sql_sys_admin_list; template_config builds the confi.ini file correctly; I use package_url but just pull in the package_name from attributes and skip checksum; I use the same passwords resource; and the package resource above matches the one in the install.rb. It is installing and creating the config.ini file all successfully. It works.

SO, why is a wrapper necessary just for chef to compare the package_name against the Ohai data when everything else works successfully???

The custom resource calls the package resource, where the check to compare the product code happens. IF the check happens in the package resource code underneath, why does it need the wrapper? IF the package resource code underneath has the correct name specified, it should successfully complete it's check right? It is not in my scenario, using almost the exact same code as the install.rb custom resource in a recipe, but yet it installs completely successfully???

anyone have any thoughts on this? The post on the sql cookbook issue is silent, going to pursue a support ticket next...

sorry i found the discrepancy.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ had 2 keys with the same value:

Microsoft SQL Server 13 - "Microsoft SQL Server 2016 (64-bit)"
Microsoft SQL Server SQLServer2016 - "Microsoft SQL Server 2016 (64-bit)"

Package resource was using "Microsoft SQL Server 2016(64-bit)"
NO space between 2016 and (64-bit).