From fd5342f595051df27e11543cdc3bacdcaa175c06 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Tue, 18 Mar 2025 12:50:35 -0700 Subject: [PATCH 1/2] Upgrade puppetcore* msi from artifacts-puppetcore.puppet.com When using the puppetcore collection on Windows, if we detect the installed version does not match, then upgrade the MSI. Due to a puppet bug, we cannot pass credentials in the `source` parameter. And `curl.exe` is not present in our puppet-agent packages. So use powershell to download. Co-authored-by: Kevin <114269618+klab-systems@users.noreply.github.com> --- REFERENCE.md | 29 +++++++++++++++++++++++++++++ manifests/osfamily/windows.pp | 2 ++ 2 files changed, 31 insertions(+) diff --git a/REFERENCE.md b/REFERENCE.md index e8b419ea..55eacd71 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -619,6 +619,35 @@ The puppet-agent version to install. Default value: `undef` +### `puppet_agent::prepare::package` + +for installation. This is used on platforms without package managers capable of +working with a remote https repository. + +#### Parameters + +The following parameters are available in the `puppet_agent::prepare::package` class: + +* [`source`](#-puppet_agent--prepare--package--source) +* [`package_file_name`](#-puppet_agent--prepare--package--package_file_name) + +##### `source` + +Data type: `Variant[String, Array]` + +The source file for the puppet-agent package. Can use any of the data types +and protocols that the File resource's source attribute can. + +##### `package_file_name` + +Data type: `Optional[String]` + +The destination file name for the puppet-agent package. If no destination +is given, then the basename component of the source will be used as the +destination filename. + +Default value: `undef` + ### `puppet_agent::prepare::puppet_config` Private class called from puppet_agent::prepare class. diff --git a/manifests/osfamily/windows.pp b/manifests/osfamily/windows.pp index 98ed62ae..5a29d837 100644 --- a/manifests/osfamily/windows.pp +++ b/manifests/osfamily/windows.pp @@ -2,6 +2,8 @@ class puppet_agent::osfamily::windows { assert_private() + $destination_name = undef + if $puppet_agent::absolute_source { $source = $puppet_agent::absolute_source } elsif $puppet_agent::source { From 4c2832f62148b7667c8d6c2f2a5d9c03eafacf20 Mon Sep 17 00:00:00 2001 From: Christopher Thorn Date: Tue, 1 Apr 2025 14:14:51 -0700 Subject: [PATCH 2/2] (maint) Update MacOS for puppetcore work This updates the download of puppet-agent when puppetcore packages are used. The new 'puppetcore7' and 'puppetcore8' collections when used for MacOS will now download puppetcore packages. Due to a bug in Puppet for now we're going to depend on Curl to download the package. --- manifests/osfamily/darwin.pp | 28 ++++++++++----- manifests/osfamily/windows.pp | 2 -- manifests/prepare/package.pp | 39 +++++++++++++++++++++ tasks/install_shell.sh | 64 ++++++++++++++++++++++++++++------- 4 files changed, 111 insertions(+), 22 deletions(-) diff --git a/manifests/osfamily/darwin.pp b/manifests/osfamily/darwin.pp index ab3dfd15..226c511a 100644 --- a/manifests/osfamily/darwin.pp +++ b/manifests/osfamily/darwin.pp @@ -8,24 +8,36 @@ $productversion_array = split($facts['os']['macosx']['version']['major'], '[.]') $productversion_major = $productversion_array[0] } - - if $puppet_agent::absolute_source { - $source = $puppet_agent::absolute_source + $source = if $puppet_agent::absolute_source { + $puppet_agent::absolute_source } elsif ($puppet_agent::is_pe and (!$puppet_agent::use_alternate_sources)) { $pe_server_version = pe_build_version() if $puppet_agent::alternate_pe_source { - $source = "${puppet_agent::alternate_pe_source}/packages/${pe_server_version}/${facts['platform_tag']}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${$productversion_major}.dmg" + "${puppet_agent::alternate_pe_source}/packages/${pe_server_version}/${facts['platform_tag']}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${productversion_major}.dmg" } elsif $puppet_agent::source { - $source = "${puppet_agent::source}/packages/${pe_server_version}/${facts['platform_tag']}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${$productversion_major}.dmg" + "${puppet_agent::source}/packages/${pe_server_version}/${facts['platform_tag']}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${productversion_major}.dmg" + } else { + "puppet:///pe_packages/${pe_server_version}/${facts['platform_tag']}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${productversion_major}.dmg" + } + } elsif $puppet_agent::collection =~ /core/ { + if $puppet_agent::prepare::package_version =~ /^\d+\.\d+\.\d+\.\d+\.g([a-f0-9]+)+$/ { + "https://artifacts-puppetcore.puppet.com/v1/download?type=native&version=${puppet_agent::prepare::package_version}&os_name=osx&os_version=${productversion_major}&os_arch=${puppet_agent::arch}&dev=true" } else { - $source = "puppet:///pe_packages/${pe_server_version}/${facts['platform_tag']}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${$productversion_major}.dmg" + "https://artifacts-puppetcore.puppet.com/v1/download?type=native&version=${puppet_agent::prepare::package_version}&os_name=osx&os_version=${productversion_major}&os_arch=${puppet_agent::arch}" } } else { - $source = "${puppet_agent::mac_source}/mac/${puppet_agent::collection}/${productversion_major}/${puppet_agent::arch}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${$productversion_major}.dmg" + "${puppet_agent::mac_source}/mac/${puppet_agent::collection}/${productversion_major}/${puppet_agent::arch}/${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${productversion_major}.dmg" + } + + $destination_name = if $puppet_agent::collection =~ /core/ { + "${puppet_agent::package_name}-${puppet_agent::prepare::package_version}-1.osx${productversion_major}.dmg" + } else { + undef } class { 'puppet_agent::prepare::package': - source => $source, + source => $source, + destination_name => $destination_name, } contain puppet_agent::prepare::package diff --git a/manifests/osfamily/windows.pp b/manifests/osfamily/windows.pp index 5a29d837..98ed62ae 100644 --- a/manifests/osfamily/windows.pp +++ b/manifests/osfamily/windows.pp @@ -2,8 +2,6 @@ class puppet_agent::osfamily::windows { assert_private() - $destination_name = undef - if $puppet_agent::absolute_source { $source = $puppet_agent::absolute_source } elsif $puppet_agent::source { diff --git a/manifests/prepare/package.pp b/manifests/prepare/package.pp index a1b1e549..5cd5ed99 100644 --- a/manifests/prepare/package.pp +++ b/manifests/prepare/package.pp @@ -56,6 +56,45 @@ creates => $local_package_file_path, require => File[$puppet_agent::params::local_packages_dir], } + } elsif $puppet_agent::collection =~ /core/ and $facts['os']['family'] =~ /Darwin/ { + $download_username = getvar('puppet_agent::username', 'forge-key') + $download_password = unwrap(getvar('puppet_agent::password')) + + $response_file = "${local_package_file_path}.response" + $netrc_file = "${facts['env_temp_variable']}/.netrc" + file { $netrc_file: + ensure => file, + content => "machine artifacts-puppetcore.puppet.com\nlogin ${download_username}\npassword ${download_password}\n", + mode => '0600', + show_diff => false, + } + + $curl_command = "curl -1 -sL --netrc-file '${netrc_file}' -w '%{http_code}' -o '${local_package_file_path}' '${source}' > '${response_file}'" + exec { 'Download Puppet Agent for Darwin': + command => $curl_command, + creates => $local_package_file_path, + path => ['/usr/bin', '/usr/sbin', '/bin', '/sbin'], + } + + exec { 'Remove .netrc file': + command => "rm -f '${netrc_file}'", + path => ['/usr/bin', '/bin'], + onlyif => "test -f '${netrc_file}'", + require => Exec['Download Puppet Agent for Darwin'], + } + # + # TODO: This is a temporary workaround to get the HTTP response code from the curl command. + # For now just outputting the response is good enough. + # We need to find a way to interspect this value and fail the catalog if the response + # code is not 200, and then logging the output wont be as important. + # + exec { 'Read HTTP Response Code': + command => "cat '${response_file}'", + path => ['/usr/bin', '/bin'], + onlyif => "test -f '${response_file}'", + logoutput => true, + require => Exec['Download Puppet Agent for Darwin'], + } } else { file { $local_package_file_path: ensure => file, diff --git a/tasks/install_shell.sh b/tasks/install_shell.sh index f5c64a8e..a448aad2 100644 --- a/tasks/install_shell.sh +++ b/tasks/install_shell.sh @@ -26,6 +26,14 @@ warn () { log "WARN: ${1}" } +url_parameters() { + if [[ "$version" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\.g([a-f0-9]+)$ ]]; then + echo "&dev=true" + else + echo "" + fi +} + critical () { log "CRIT: ${1}" } @@ -162,10 +170,18 @@ fi if [ -n "$PT_mac_source" ]; then mac_source=$PT_mac_source else - if [ "$nightly" = true ]; then - mac_source='http://nightlies.puppet.com/downloads' - else - mac_source='http://downloads.puppet.com' + if [[ "$PT_collection" =~ core ]]; then + if [ -z "$password" ]; then + echo "A password parameter is required to install with puppetcore" + exit 1 + fi + mac_source='https://artifacts-puppetcore.puppet.com/v1/download' + else + if [ "$nightly" = true ]; then + mac_source='http://nightlies.puppet.com/downloads' + else + mac_source='http://downloads.puppet.com' + fi fi fi @@ -421,7 +437,11 @@ do_wget() { # do_curl URL FILENAME do_curl() { info "Trying curl..." - run_cmd "curl -1 -sL -D $tmp_stderr '$1' > '$2'" + if [[ -n "$3" && -n "$4" ]]; then + run_cmd "curl -1 -sL -u '$3:$4' -D $tmp_stderr '$1' > '$2'" + else + run_cmd "curl -1 -sL -D $tmp_stderr '$1' > '$2'" + fi rc=$? # check for 404 @@ -431,6 +451,12 @@ do_curl() { unable_to_retrieve_package fi + grep "HTTP/2 401" $tmp_stderr 2>&1 >/dev/null + if test $? -eq 0; then + critical "ERROR 401: Unauthorized access" + unable_to_retrieve_package + fi + # check for bad return status or empty output if test $rc -ne 0 || test ! -s "$2"; then capture_tmp_stderr "curl" @@ -557,7 +583,11 @@ do_download() { fi if exists curl; then - do_curl $1 $2 && return 0 + if [[ "$collection" =~ core ]]; then + do_curl $1 $2 "$username" "$password" && return 0 + else + do_curl $1 $2 && return 0 + fi fi if exists fetch; then @@ -810,19 +840,29 @@ case $platform in download_url="${apt_source}/${filename}" ;; "mac_os_x") - info "Mac platform! Lets get you a DMG..." - filetype="dmg" + arch="x86_64" + if [[ $(uname -p) == "arm" ]]; then + arch="arm64" + fi if test "$version" = "latest"; then filename="puppet-agent-latest.dmg" else filename="puppet-agent-${version}-1.osx${platform_version}.dmg" fi + info "Mac platform! Lets get you a DMG...!!" + if [[ "$collection" =~ core ]]; then + if [ -z "$password" ]; then + echo "A password parameter is required to install" + exit 1 + fi - arch="x86_64" - if [[ $(uname -p) == "arm" ]]; then - arch="arm64" + # Call the url_parameters function to append to the download_url + download_url="${mac_source}/?version=${version}&os_name=osx&os_version=${platform_version}&os_arch=${arch}&fips=false$(url_parameters)" + else + download_url="${mac_source}/mac/${collection}/${platform_version}/${arch}/${filename}" fi - download_url="${mac_source}/mac/${collection}/${platform_version}/${arch}/${filename}" + filetype="dmg" + ;; *) critical "Sorry $platform is not supported yet!"