itchef/cookbooks/cpe_remote/resources/pkg.rb (167 lines of code) (raw):
# Cookbook Name:: cpe_remote
# Resource:: cpe_remote_pkg
#
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
resource_name :cpe_remote_pkg
default_action :install
provides :cpe_remote_pkg, :os => 'darwin'
property :allow_downgrade, [TrueClass, FalseClass], :default => true
property :app, String, :name_property => true
property :checksum, String
property :backup, [FalseClass, Integer], :default => false
property :force_arm64, [TrueClass, FalseClass], :default => false
property :mpkg, [TrueClass, FalseClass], :default => false
property :pkg_name, String
property :pkg_url, String
property :receipt, String, :desired_state => false
property :remote, [TrueClass, FalseClass], :default => true
property :version, String
action_class do
include CPE::Remote
def log_info(msg)
CPE::Log.log(
msg,
:level => :info,
:type => 'cpe_remote_pkg',
:action => 'install',
:status => 'success',
)
end
def log_warn(msg)
CPE::Log.log(
msg,
:level => :warn,
:type => 'cpe_remote_pkg',
:action => 'install',
:status => 'fail',
)
end
def log_unless(msg)
CPE::Log.unless(
msg, :type => 'cpe_remote_pkg', :action => 'install', :status => 'fail'
) { yield }
end
end
load_current_value do
cmd = "/usr/sbin/pkgutil --pkg-info '#{receipt}'"
version shell_out(cmd).stdout.to_s[/version: (.*)/, 1]
end
action :install do
return unless log_unless(
'Distro server inaccessible',
) { node['cpe_remote']['server_accessible'] }
desired_version = new_resource.version
installed_version = current_resource.version
unless new_resource.allow_downgrade
if Gem::Version.new(installed_version) > Gem::Version.new(desired_version)
log_info(
"Installed version (#{installed_version}) is higher than desired " +
"version (#{desired_version}), but allow_downgrade is false.",
)
return
end
end
converge_if_changed :version do
pkg_name = new_resource.app
pkg_version_str = "-#{desired_version}"
if new_resource.pkg_name
pkg_name = new_resource.pkg_name
pkg_version_str = ''
end
is_mpkg = new_resource.mpkg
chef_cache = Chef::Config[:file_cache_path]
# Download vars
ext = is_mpkg ? 'zip' : 'pkg'
download_file = "#{pkg_name}#{pkg_version_str}.#{ext}"
download_file_path = "#{chef_cache}/#{download_file}"
pkg_source = gen_url(new_resource.app, download_file)
# someone can choose to override where there pkg is coming from
pkg_source = new_resource.pkg_url if new_resource.pkg_url
valid_url = valid_url?(pkg_source)
cpe_remote_file download_file do
only_if do
CPE::Log.unless(
"Failed to download package since url(#{pkg_source}) is invalid",
:level => :warn,
:type => 'cpe_remote_pkg',
:action => "remote_file/#{download_file}",
:status => 'fail',
) { valid_url }
end
path download_file_path
file_url pkg_source
folder_name new_resource.app
backup new_resource.backup
checksum new_resource.checksum
unless node['cpe_remote']['additional_headers'].empty?
headers node['cpe_remote']['additional_headers']
end
end
# Unzip if is_mpkg
execute "Unzipping #{download_file_path}" do
only_if { is_mpkg }
only_if { valid_url }
command "cd #{chef_cache} && /usr/bin/unzip -o '#{download_file_path}'"
end
# install vars
pkg_file = "#{pkg_name}#{pkg_version_str}.pkg"
pkg_file_path = "#{chef_cache}/#{pkg_file}"
pkg_on_disk = pkg_file_path
if is_mpkg
pkg_file = "#{pkg_name}#{pkg_version_str}.mpkg"
pkg_file_path = "#{chef_cache}/#{pkg_name}/#{pkg_file}"
pkg_on_disk = download_file_path
end
force_arm64 = new_resource.force_arm64
cmd = "/usr/sbin/installer -pkg '#{pkg_file_path}' -target /"
if force_arm64
cmd = '/usr/bin/arch --arm64 ' + cmd
end
execute "Installing #{pkg_file}" do
only_if { valid_url }
only_if { validate_checksum(pkg_on_disk, new_resource.checksum) }
command cmd
end
Chef.event_handler do
on :resource_failed do |resource, _action, exception|
if resource.to_s == "cpe_remote_pkg[#{pkg_name}]"
CPE::Log.log(
"#{pkg_file} install failed with exception: #{exception}",
:level => :error,
:type => 'cpe_remote_pkg',
:action => 'install',
:status => 'fail',
)
end
end
end
Chef.event_handler do
on :resource_updated do |resource|
if resource.to_s == "cpe_remote_pkg[#{pkg_name}]"
CPE::Log.log(
"#{pkg_file} install succeeded",
:level => :debug,
:type => 'cpe_remote_pkg',
:action => 'install',
:status => 'success',
)
end
end
end
keep_pkg = new_resource.backup ? true : false
# Delete Zip if there is a ZIP
file download_file_path do
only_if { is_mpkg }
only_if { valid_url }
not_if { keep_pkg }
action :delete
backup false
end
# Delete MPKG
directory pkg_file_path do
only_if { is_mpkg }
only_if { valid_url }
not_if { keep_pkg }
action :delete
recursive true
end
# Delete PKG
file "delete-#{pkg_file_path}" do
not_if { is_mpkg }
only_if { valid_url }
not_if { keep_pkg }
path pkg_file_path
action :delete
backup false
end
end
end