diff --git a/REFERENCE.md b/REFERENCE.md index cb6475562..8f2a2319e 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -98,6 +98,8 @@ The following parameters are available in the `puppet_agent` class: * [`version_file_path`](#-puppet_agent--version_file_path) * [`skip_if_unavailable`](#-puppet_agent--skip_if_unavailable) * [`disable_proxy`](#-puppet_agent--disable_proxy) +* [`username`](#-puppet_agent--username) +* [`password`](#-puppet_agent--password) ##### `arch` @@ -371,6 +373,22 @@ Data type: `Boolean` Default value: `false` +##### `username` + +Data type: `Optional` + +The username to use when downloading from a source location requiring authentication. + +Default value: `undef` + +##### `password` + +Data type: `Optional[Sensitive]` + +The password to use when downloading from a source location requiring authentication. + +Default value: `undef` + ### `puppet_agent::configure` It does not require management of the agent package. @@ -843,7 +861,7 @@ The version of puppet-agent to install (defaults to latest when no agent is inst ##### `collection` -Data type: `Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly]]` +Data type: `Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly, puppetcore7, puppetcore8]]` The Puppet collection to install from (defaults to puppet, which maps to the latest collection released) @@ -895,6 +913,18 @@ Data type: `Optional[Integer]` The number of retries in case of network connectivity failures +##### `username` + +Data type: `Optional[String]` + +The username to use when downloading from a source location requiring authentication + +##### `password` + +Data type: `Optional[String]` + +The password to use when downloading from a source location requiring authentication + ### `install_powershell` Install the Puppet agent package @@ -979,7 +1009,7 @@ The version of puppet-agent to install ##### `collection` -Data type: `Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly]]` +Data type: `Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly, puppetcore7, puppetcore8]]` The Puppet collection to install from (defaults to puppet, which maps to the latest collection released) @@ -1031,6 +1061,18 @@ Data type: `Optional[Integer]` The number of retries in case of network connectivity failures +##### `username` + +Data type: `Optional[String]` + +The username to use when downloading from a source location requiring authentication + +##### `password` + +Data type: `Optional[String]` + +The password to use when downloading from a source location requiring authentication + ### `run` Run the Puppet agent. This task may cause problems if run in Puppet Enterprise. diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..8813c64e2 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,117 @@ +# README + +These directories contain Dockerfiles that are useful for testing installation and upgrades. + +All examples assume the `PUPPET_FORGE_TOKEN` environment variable is set. + +## Usage + +### Installation + +This case uses the `install_shell.sh` task to install puppet-agent 8.x and verifies +`puppet apply` works. + +#### Usage + +``` +docker/bin/install.sh [os name] [agent version] +``` + +#### Perform default install + +Without any arguments, puppet-agent 8.11.0 will be installed on Rocky 8 + +``` +$ docker/bin/install.sh +... + Installing : puppet-agent-8.11.0-1.el8.x86_64 +... +Notice: Scope(Class[main]): puppet apply +Notice: Compiled catalog for 201fbd3e5e0b in environment production in 0.02 seconds +Notice: Applied catalog in 0.02 seconds +``` + +#### Install the latest version of an OS + +When given an `os name` parameter, puppet-agent 8.11.0 will be installed on the latest +version of that OS, in this example Fedora 41. + +``` +$ docker/bin/install.sh fedora +... + Installing : puppet-agent-8.11.0-1.el9.x86_64 +... +Notice: Scope(Class[main]): puppet apply +Notice: Compiled catalog for 881280c14d12 in environment production in 0.02 seconds +Notice: Applied catalog in 0.02 seconds +``` + +#### Install a specific platform and version + +When given `os name` and `agent version` parameters, install that version of the +agent on that OS, in this example pupet-agent 8.10.0 on Fedora 40. + +``` +$ docker/bin/install.sh fedora40 8.10.0 +... + Installing : puppet-agent-8.10.0-1.fc40.x86_64 +... +Notice: Scope(Class[main]): puppet apply +Notice: Compiled catalog for 6791cd8e4da1 in environment production in 0.02 seconds +Notice: Applied catalog in 0.02 seconds +``` + +### Upgrades + +This case installs a `before` version of puppet-agent and verifies you can use +this module to upgrade to an `after` version. + +#### Usage + +``` +docker/bin/upgrade.sh [os name] [before] [after] +``` + +##### Perform default upgrade + +Without any arguments, puppet-agent 7.34.0 will be installed on Rocky 8 and will +be upgraded to 8.11.0. + +``` +$ docker/bin/upgrade.sh +... +Notice: /Stage[main]/Puppet_agent::Install/Package[puppet-agent]/ensure: ensure changed '7.34.0-1.el8' to '8.10.0' +``` + +##### Upgrade a specific platform + +When given an `os name` parameter, puppet-agent 8.11.0 will be installed on the latest +version of that OS, in this example amazon 2023. + +``` +$ docker/bin/upgrade.sh amazon +... +Notice: /Stage[main]/Puppet_agent::Install/Package[puppet-agent]/ensure: ensure changed '7.34.0-1.amazon2023' to '8.11.0' +``` + +##### Upgrade from a specific version + +When given an `os name` and `before` parameters, install that version of the +agent and upgrade to the default `after` version, in this example, 8.11.0. + +``` +$ docker/bin/upgrade.sh rocky 7.12.0 +... +Notice: /Stage[main]/Puppet_agent::Install/Package[puppet-agent]/ensure: ensure changed '7.12.0-1.el8' to '8.11.0' +``` + +##### Upgrade from and to specific versions + +When given an `os name`, `before` and `after` parameters, install the `before` +version of the agent and upgrade to the `after` version. + +``` +$ docker/bin/upgrade.sh rocky 7.16.0 8.10.0 +... +Notice: /Stage[main]/Puppet_agent::Install/Package[puppet-agent]/ensure: ensure changed '7.16.0-1.el8' to '8.10.0' +``` diff --git a/docker/bin/helpers/run-install.sh b/docker/bin/helpers/run-install.sh new file mode 100755 index 000000000..3e028cb5a --- /dev/null +++ b/docker/bin/helpers/run-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -e + +to_version="${1}" +if [[ -z "${to_version}" ]]; then + echo "$0: The version to install must be passed as an argument" + exit 1 +fi +puppet_version=( ${to_version//./ } ) +puppet_major=${puppet_version[0]} +case $puppet_major in + 7) + to_collection=puppetcore7 + ;; + 8) + to_collection=puppetcore8 + ;; + *) + echo "$0: Invalid version supplied" 1>&2 + exit 1 +esac + +export PT__installdir=../ +export PT_version=${to_version} +export PT_collection=${to_collection} +export PT_password=${PUPPET_FORGE_TOKEN} +chmod u+x tasks/install_shell.sh +tasks/install_shell.sh + +echo "puppet $(/opt/puppetlabs/puppet/bin/puppet --version)" +echo "facter $(/opt/puppetlabs/puppet/bin/facter --version)" +/opt/puppetlabs/puppet/bin/puppet apply -e 'notice("puppet apply")' + +# Make e.g. `puppet --version` work out of the box. +PATH=/opt/puppetlabs/bin:$PATH \ + read -p "Explore the container? [y/N]: " choice && \ + choice=${choice:-N} && \ + if [ "${choice}" = "y" ]; then \ + bash; \ + else \ + echo "Moving on..."; \ + fi diff --git a/docker/bin/helpers/run-upgrade.sh b/docker/bin/helpers/run-upgrade.sh index 996a6cc3b..818d024fb 100755 --- a/docker/bin/helpers/run-upgrade.sh +++ b/docker/bin/helpers/run-upgrade.sh @@ -1,32 +1,31 @@ #!/usr/bin/env bash -# Run upgrades on a container. The default upgrade TO argument will be 6.2.0 if +# Run upgrades on a container. The default upgrade TO argument will be 8.11.0 if # no arguments are passed to this script. set -e -to_version=${1:-6.2.0} +to_version=${1:-8.11.0} # Calculate which collection should be used. This is derived from the puppet # version. puppet_version=( ${to_version//./ } ) puppet_major=${puppet_version[0]} case $puppet_major in -4) - to_collection=PC1 - ;; -5) - to_collection=puppet5 - ;; -6) - to_collection=puppet6 - ;; 7) to_collection=puppet7 ;; +8) + to_collection=puppet8 + ;; *) echo "Invalid version supplied" 1>&2 exit 1 esac -FACTER_to_version=${1:-6.2.0} FACTER_to_collection=${to_collection} /opt/puppetlabs/puppet/bin/puppet apply --debug --trace --modulepath /tmp/modules /tmp/upgrade.pp +FACTER_to_version=${to_version} \ + FACTER_to_collection=${to_collection} \ + FACTER_forge_username=forge-key \ + FACTER_forge_password="${PUPPET_FORGE_TOKEN}" \ + /opt/puppetlabs/puppet/bin/puppet apply --debug --trace --modulepath /tmp/modules /tmp/upgrade.pp + # Make e.g. `puppet --version` work out of the box. PATH=/opt/puppetlabs/bin:$PATH \ read -p "Explore the upgraded container? [y/N]: " choice && \ diff --git a/docker/bin/install.sh b/docker/bin/install.sh new file mode 100755 index 000000000..78eec1094 --- /dev/null +++ b/docker/bin/install.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Usage: `./install.sh [] []` +# +# Builds an upgrade process for the puppet-agent module and tags as +# "pa-dev:". +# +# Parameters: +# - PLATFORM: The platform on which the upgrade should occur. This also +# supports comma-separated lists. Available: +# - `amazon` +# - `fedora` +# - `rocky` +# - `sles` +# - `ubuntu` +# Default: `ubuntu` +# - BEFORE: The puppet-agent package version that is installed prior to upgrade. +# Default: 7.34.0 +# - AFTER: The puppet-agent package version that should exist after upgrade. +# Default: 8.1.0 +set -e + +if [[ -z "${PUPPET_FORGE_TOKEN}" ]]; then + echo "$0: Environment variable PUPPET_FORGE_TOKEN must be set" + exit 1 +fi + +cd "$(dirname "$0")/../.." +platforms=${1:-rocky} +version=${2:-8.11.0} +for platform in ${platforms//,/ } +do + dockerfile='docker/install/dnf/Dockerfile' + + case $platform in + amazon*) + base_image='amazonlinux:2023' + ;; + + fedora40) + base_image='fedora:40' + ;; + + fedora36) + base_image='fedora:36' + ;; + + fedora*) + base_image='fedora:41' + ;; + + rocky8) + base_image='rockylinux/rockylinux:8' + ;; + + rocky*) + base_image='rockylinux/rockylinux:9' + ;; + + sles*) + base_image='registry.suse.com/suse/sle15:15.6' + dockerfile='docker/install/sles/Dockerfile' + ;; + + *) + echo "$0: Usage install.sh [amazon|fedora|rocky|sles]" + exit 1 + ;; + esac + + docker build --rm -f "${dockerfile}" . -t pa-dev:$platform.install \ + --build-arg BASE_IMAGE="${base_image}" + docker run -e PUPPET_FORGE_TOKEN --rm -ti pa-dev:$platform.install "${version}" +done +echo Complete diff --git a/docker/bin/upgrade.sh b/docker/bin/upgrade.sh index 5106fe7ab..52ecc548e 100755 --- a/docker/bin/upgrade.sh +++ b/docker/bin/upgrade.sh @@ -8,23 +8,65 @@ # - PLATFORM: The platform on which the upgrade should occur. This also # supports comma-separated lists. Available: # - `ubuntu` -# - `centos` +# - `amazon` +# - `fedora` # - `rocky` +# - `sles` # Default: `ubuntu` # - BEFORE: The puppet-agent package version that is installed prior to upgrade. -# Default: 1.10.14 +# Default: 7.34.0 # - AFTER: The puppet-agent package version that should exist after upgrade. -# Default: 6.2.0 +# Default: 8.1.0 set -e +if [ -z "${PUPPET_FORGE_TOKEN}" ]; then + echo "Environment variable PUPPET_FORGE_TOKEN must be set" + exit 1 +fi + cd "$(dirname "$0")/../.." -platforms=${1:-ubuntu} -before=${2:-1.10.14} -after=${3:-6.2.0} +platforms=${1:-rocky} +before=${2:-7.34.0} +after=${3:-8.11.0} for platform in ${platforms//,/ } do - docker build --rm -f docker/$platform/Dockerfile . -t pa-dev:$platform \ - --build-arg before=${before} - docker run --rm -ti pa-dev:$platform ${after} + dockerfile='docker/upgrade/dnf/Dockerfile' + + # REMIND: if (7.35 <= before && before < 8.0) OR (8.11.0 <= before), then install release + # package from yum-puppetcore. + case $platform in + amazon) + base_image='amazonlinux:2023' + release_package='http://yum.puppet.com/puppet7-release-amazon-2023.noarch.rpm' + ;; + + fedora) + base_image='fedora:40' + release_package='http://yum.puppet.com/puppet7-release-fedora-40.noarch.rpm' + ;; + + rocky) + base_image='rockylinux/rockylinux:8' + release_package='http://yum.puppet.com/puppet7-release-el-8.noarch.rpm' + ;; + + sles) + base_image='registry.suse.com/suse/sle15:15.6' + release_package='http://yum.puppet.com/puppet7-release-sles-15.noarch.rpm' + dockerfile='docker/upgrade/sles/Dockerfile' + ;; + + *) + echo "$0: Usage upgrade.sh [amazon|fedora|rocky|sles] [before] [after]" + exit 1 + ;; + esac + + docker build --rm -f ${dockerfile} . -t pa-dev:$platform \ + --build-arg before=${before} \ + --build-arg BASE_IMAGE=${base_image} \ + --build-arg RELEASE_PACKAGE=${release_package} + + docker run -e PUPPET_FORGE_TOKEN --rm -ti pa-dev:$platform ${after} done -echo Complete \ No newline at end of file +echo Complete diff --git a/docker/bin/versions.sh b/docker/bin/versions.sh index a8fd3ad99..4f887cd07 100755 --- a/docker/bin/versions.sh +++ b/docker/bin/versions.sh @@ -7,7 +7,6 @@ # Parameters: # - PLATFORM: The platform on which the upgrade should occur. Available: # - `ubuntu` -# - `centos` # - `rocky` # Default: `ubuntu` set -e @@ -15,9 +14,9 @@ set -e platform=${1:-ubuntu} case "${platform}" in - ubuntu|centos|rocky) + ubuntu|rocky) ;; - *) echo "Invalid platform: '${platform}'. Must be 'ubuntu' or 'centos'" + *) echo "Invalid platform: '${platform}'. Must be 'ubuntu' or 'rocky'" exit 1 ;; esac diff --git a/docker/centos/Dockerfile.versions b/docker/centos/Dockerfile.versions deleted file mode 100644 index ecc3d5012..000000000 --- a/docker/centos/Dockerfile.versions +++ /dev/null @@ -1,20 +0,0 @@ -FROM centos:8 - -# Install some other dependencies for ease of life. -RUN yum update -y \ - && yum install -y wget git \ - && yum clean all - -# Install several repos: PC1 (puppet 4), puppet 5, puppet 6, and puppet7. -RUN wget -O puppet-pc1.rpm http://yum.puppet.com/puppetlabs-release-pc1-el-7.noarch.rpm && \ - rpm -i puppet-pc1.rpm --force --replacefiles && \ - wget -O puppet5.rpm http://yum.puppet.com/puppet5-release-el-7.noarch.rpm && \ - rpm -i puppet5.rpm --force --replacefiles && \ - wget -O puppet6.rpm http://yum.puppet.com/puppet6-release-el-7.noarch.rpm && \ - rpm -i puppet6.rpm --force --replacefiles --nodeps && \ - wget -O puppet7.rpm http://yum.puppet.com/puppet7-release-el-7.noarch.rpm && \ - rpm -i puppet7.rpm --force --replacefiles --nodeps - -# Print out available package versions for puppet-agent. If a specific version -# is desired, pass that in with e.g. `--build-arg before=1.1.1` -ENTRYPOINT ["yum", "list", "puppet-agent", "--showduplicates"] \ No newline at end of file diff --git a/docker/install/dnf/Dockerfile b/docker/install/dnf/Dockerfile new file mode 100644 index 000000000..5459af90d --- /dev/null +++ b/docker/install/dnf/Dockerfile @@ -0,0 +1,60 @@ +# This Dockerfile enables an iterative development workflow where you can make +# a change and test it out quickly. The majority of commands in this file will +# be cached, making the feedback loop typically quite short. The workflow is +# as follows: +# 1. Set up pre-conditions for the system in puppet code using `deploy.pp`. +# 2. Make a change to the module. +# 3. Run `./docker/bin/install.sh rocky` from the project directory. +# 4. Review the output. Repeat steps 2-3 as needed. +# +# At the end of execution, you will see a line like: +# Dependencies resolved. +# ======================================================================================================================================== +# Package Architecture Version Repository Size +# ======================================================================================================================================== +# Installing: +# puppet-agent x86_64 8.10.0-1.el8 puppet8 27 M + +ARG BASE_IMAGE=rocky:8 +FROM ${BASE_IMAGE} + +# Use this to force a cache reset (e.g. for output purposes) +#COPY $0 /tmp/Dockerfile + +# Install some other dependencies for ease of life. +RUN dnf update -y \ + && dnf install -y git \ + && dnf clean all + +# This is also duplicated in the docker/bin/helpers/run-upgrade.sh. +ENV module_path=/tmp/modules +WORKDIR "${module_path}/puppet_agent" +COPY metadata.json ./ + +# Installing dependencies from source. These versions should be within the range +# of `dependencies` in metadata.json. +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-stdlib ../stdlib && \ + $(cd ../stdlib && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-inifile ../inifile && \ + $(cd ../inifile && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-apt ../apt && \ + $(cd ../apt && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-facts ../facts && \ + $(cd ../facts && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) + +# Now move the project directory's files into the image. That way, if these +# files change, caching will skip everything before this. +COPY docker/bin/helpers/run-install.sh /tmp/bin/run-install.sh +COPY files/ ./files/ +COPY locales/ ./locales/ +COPY spec/ ./spec/ +COPY task_spec/ ./task_spec/ +COPY tasks/ ./tasks/ +COPY templates/ ./templates +COPY types/ ./types/ +COPY Gemfile Gemfile.lock Rakefile ./ +COPY lib/ ./lib/ +COPY manifests/ ./manifests/ + +# Perform the install. +ENTRYPOINT ["/tmp/bin/run-install.sh"] diff --git a/docker/install/sles/Dockerfile b/docker/install/sles/Dockerfile new file mode 100644 index 000000000..b508854d7 --- /dev/null +++ b/docker/install/sles/Dockerfile @@ -0,0 +1,54 @@ +# This Dockerfile enables an iterative development workflow where you can make +# a change and test it out quickly. The majority of commands in this file will +# be cached, making the feedback loop typically quite short. The workflow is +# as follows: +# 1. Set up pre-conditions for the system in puppet code using `deploy.pp`. +# 2. Make a change to the module. +# 3. Run `./docker/bin/install.sh rocky` from the project directory. +# 4. Review the output. Repeat steps 2-3 as needed. +# +# At the end of execution, you will see a line like: +# +# (19/19) Installing: puppet-agent-8.11.0-1.sles15.x86_64 ..........................................................................[done] + +ARG BASE_IMAGE=registry.suse.com/suse/sle15:15.6 +FROM ${BASE_IMAGE} + +# Use this to force a cache reset (e.g. for output purposes) +#COPY $0 /tmp/Dockerfile + +# Install some other dependencies for ease of life. +RUN zypper install --no-confirm wget git-core + +# This is also duplicated in the docker/bin/helpers/run-upgrade.sh. +ENV module_path=/tmp/modules +WORKDIR "${module_path}/puppet_agent" +COPY metadata.json ./ + +# Installing dependencies from source. These versions should be within the range +# of `dependencies` in metadata.json. +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-stdlib ../stdlib && \ + $(cd ../stdlib && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-inifile ../inifile && \ + $(cd ../inifile && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-apt ../apt && \ + $(cd ../apt && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +RUN git clone --tags https://github.com/puppetlabs/puppetlabs-facts ../facts && \ + $(cd ../facts && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) + +# Now move the project directory's files into the image. That way, if these +# files change, caching will skip everything before this. +COPY docker/bin/helpers/run-install.sh /tmp/bin/run-install.sh +COPY files/ ./files/ +COPY locales/ ./locales/ +COPY spec/ ./spec/ +COPY task_spec/ ./task_spec/ +COPY tasks/ ./tasks/ +COPY templates/ ./templates +COPY types/ ./types/ +COPY Gemfile Gemfile.lock Rakefile ./ +COPY lib/ ./lib/ +COPY manifests/ ./manifests/ + +# Perform the install. +ENTRYPOINT ["/tmp/bin/run-install.sh"] diff --git a/docker/rocky/Dockerfile.versions b/docker/rocky/Dockerfile.versions index 151ae54dc..8cd8df8e2 100644 --- a/docker/rocky/Dockerfile.versions +++ b/docker/rocky/Dockerfile.versions @@ -5,11 +5,11 @@ RUN dnf update -y \ && dnf install -y wget git \ && dnf clean all -# Install several repos: puppet 6, and puppet7. -RUN wget -O puppet6.rpm http://yum.puppet.com/puppet6-release-el-8.noarch.rpm && \ - rpm -i puppet6.rpm --force --replacefiles --nodeps && \ - wget -O puppet7.rpm http://yum.puppet.com/puppet7-release-el-8.noarch.rpm && \ - rpm -i puppet7.rpm --force --replacefiles --nodeps +# Install several repos: puppet 7 and 8 +RUN wget -O puppet7.rpm http://yum.puppet.com/puppet7-release-el-8.noarch.rpm && \ + rpm -i puppet7.rpm --force --replacefiles --nodeps && \ + wget -O puppet8.rpm http://yum.puppet.com/puppet8-release-el-8.noarch.rpm && \ + rpm -i puppet8.rpm --force --replacefiles --nodeps # Print out available package versions for puppet-agent. If a specific version # is desired, pass that in with e.g. `--build-arg before=1.1.1` diff --git a/docker/upgrade.pp b/docker/upgrade.pp index eb1d52a16..b1d839bbe 100644 --- a/docker/upgrade.pp +++ b/docker/upgrade.pp @@ -8,5 +8,7 @@ # process. service_names => [], collection => $facts['to_collection'], + username => $facts['forge_username'], + password => Sensitive($facts['forge_password']), } } diff --git a/docker/rocky/Dockerfile b/docker/upgrade/dnf/Dockerfile similarity index 73% rename from docker/rocky/Dockerfile rename to docker/upgrade/dnf/Dockerfile index 2a9083ad3..9469f0915 100644 --- a/docker/rocky/Dockerfile +++ b/docker/upgrade/dnf/Dockerfile @@ -22,30 +22,28 @@ # This specifies the versions that were used for upgrade. # # Arguments: -# - before: The version to do upgrade FROM. Default: "1.10.14" +# - before: The version to do upgrade FROM. Default: "7.34.0" -FROM rockylinux/rockylinux:8 +ARG BASE_IMAGE=rocky:8 +FROM ${BASE_IMAGE} # Use this to force a cache reset (e.g. for output purposes) #COPY $0 /tmp/Dockerfile # Install some other dependencies for ease of life. RUN dnf update -y \ - && dnf install -y wget git \ + && dnf install -y git \ && dnf clean all -ARG before=1.10.14 +ARG before=7.34.0 LABEL before=${before} -# Install proper FROM repo: puppet 6 or puppet 7. -RUN if [[ ${before} == 6.* ]]; then \ - echo Installing puppet6 repo; \ - wget -O puppet6.rpm http://yum.puppet.com/puppet6-release-el-8.noarch.rpm && \ - rpm -i puppet6.rpm; \ - elif [[ ${before} == 7.* ]]; then \ +ARG RELEASE_PACKAGE + +# Install proper FROM repo pupet 7 +RUN if [[ ${before} == 7.* ]]; then \ echo Installing puppet7 repo; \ - wget -O puppet7.rpm http://yum.puppet.com/puppet7-release-el-8.noarch.rpm && \ - rpm -i puppet7.rpm; \ + rpm -Uvh ${RELEASE_PACKAGE}; \ else echo no; \ fi @@ -54,7 +52,8 @@ RUN if [[ ${before} == 6.* ]]; then \ # Install FROM version of puppet-agent. RUN dnf -y update && \ - dnf install -y puppet-agent-${before}-1.el8 + dnf install -y puppet-agent-${before} && \ + dnf clean all # This is also duplicated in the docker/bin/helpers/run-upgrade.sh. ENV module_path=/tmp/modules @@ -67,13 +66,18 @@ COPY metadata.json ./ RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-stdlib RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-inifile RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-apt +RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-facts # Installing dependencies from source. These versions should be within the range -# of `dependencies` in metadata.json. `translate` is a dependency for inifile. -#RUN git clone https://github.com/puppetlabs/puppetlabs-stdlib ../stdlib --branch 5.2.0 -#RUN git clone https://github.com/puppetlabs/puppetlabs-inifile ../inifile --branch 2.5.0 -#RUN git clone https://github.com/puppetlabs/puppetlabs-translate ../translate --branch 1.2.0 -#RUN git clone https://github.com/puppetlabs/puppetlabs-apt ../apt --branch 6.3.0 +# of `dependencies` in metadata.json. +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-stdlib ../stdlib && \ +# $(cd ../stdlib && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-inifile ../inifile && \ +# $(cd ../inifile && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-apt ../apt && \ +# $(cd ../apt && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-facts ../facts && \ +# $(cd ../facts && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) # Check that all dependencies are installed. RUN /opt/puppetlabs/puppet/bin/puppet module --modulepath $module_path list --tree diff --git a/docker/centos/Dockerfile b/docker/upgrade/sles/Dockerfile similarity index 56% rename from docker/centos/Dockerfile rename to docker/upgrade/sles/Dockerfile index ab53ec406..c801add31 100644 --- a/docker/centos/Dockerfile +++ b/docker/upgrade/sles/Dockerfile @@ -5,64 +5,49 @@ # 1. Set up pre-conditions for the system in puppet code using `deploy.pp`. # 2. Make a change to the module. # 3. Run `docker build -f docker/Dockerfile .` or -# `./docker/bin/upgrade.sh centos` from the project directory. If you would +# `./docker/bin/upgrade.sh rocky` from the project directory. If you would # like to test specific version upgrades, you can add run this like so: -# `docker build -f docker/centos/Dockerfile . \ -# -t pa-dev:centos --build-arg before=1.10.14` +# `docker build -f docker/rocky/Dockerfile . \ +# -t pa-dev:rocky --build-arg before=1.10.14` # 4. Upgrade the container by running the image: -# `docker run -it pa-dev:centos` +# `docker run -it pa-dev:rocky` # Specify your upgrade TO version as an argument to the `docker run` # command. # 5. Review the output. Repeat steps 2-5 as needed. # # At the end of execution, you will see a line like: # -# Notice: /Stage[main]/Puppet_agent::Install/Package[puppet-agent]/ensure: ensure changed '1.10.14-1.el7' to '6.2.0' +# Notice: /Stage[main]/Puppet_agent::Install/Package[puppet-agent]/ensure: ensure changed '1.10.14-1.el8' to '6.2.0' # # This specifies the versions that were used for upgrade. # # Arguments: -# - before: The version to do upgrade FROM. Default: "1.10.14" +# - before: The version to do upgrade FROM. Default: "7.34.0" -FROM centos:8 +ARG BASE_IMAGE=registry.suse.com/suse/sle15:15.6 +FROM ${BASE_IMAGE} # Use this to force a cache reset (e.g. for output purposes) #COPY $0 /tmp/Dockerfile # Install some other dependencies for ease of life. -RUN yum update -y \ - && yum install -y wget git \ - && yum clean all +RUN zypper install --no-confirm wget git-core -ARG before=1.10.14 +ARG before=7.34.0 LABEL before=${before} -# Install proper FROM repo: PC1 (puppet 4), puppet 5, or puppet 6. -RUN if [[ ${before} == 1.* ]]; then \ - echo Installing PC1 repo; \ - wget -O puppet-pc1.rpm http://yum.puppet.com/puppetlabs-release-pc1-el-7.noarch.rpm && \ - rpm -i puppet-pc1.rpm; \ - elif [[ ${before} == 5.* ]]; then \ - echo Installing puppet5 repo; \ - wget -O puppet5.rpm http://yum.puppet.com/puppet5-release-el-7.noarch.rpm && \ - rpm -i puppet5.rpm; \ - elif [[ ${before} == 6.* ]]; then \ - echo Installing puppet6 repo; \ - wget -O puppet6.rpm http://yum.puppet.com/puppet6-release-el-7.noarch.rpm && \ - rpm -i puppet6.rpm; \ - elif [[ ${before} == 7.* ]]; then \ - echo Installing puppet7 repo; \ - wget -O puppet7.rpm http://yum.puppet.com/puppet7-release-el-7.noarch.rpm && \ - rpm -i puppet7.rpm; \ +ARG RELEASE_PACKAGE + +# Install proper FROM repo pupet 7 +RUN if [[ ${before} == 7.* ]]; then \ + wget -O puppet7.rpm ${RELEASE_PACKAGE} && \ + rpm -i puppet7.rpm; \ else echo no; \ fi -# Print out which versions of the puppet-agent package are available (for reference). -#RUN yum list puppet-agent --showduplicates - # Install FROM version of puppet-agent. -RUN yum -y update && \ - yum install -y puppet-agent-${before}-1.el7 +RUN rpm --import https://yum.puppet.com/RPM-GPG-KEY-puppet-20250406 && \ + zypper install --no-confirm --oldpackage --no-recommends --no-confirm puppet-agent-${before} # This is also duplicated in the docker/bin/helpers/run-upgrade.sh. ENV module_path=/tmp/modules @@ -75,13 +60,18 @@ COPY metadata.json ./ RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-stdlib RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-inifile RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-apt +RUN /opt/puppetlabs/puppet/bin/puppet module install --modulepath $module_path --target-dir .. puppetlabs-facts # Installing dependencies from source. These versions should be within the range -# of `dependencies` in metadata.json. `translate` is a dependency for inifile. -#RUN git clone https://github.com/puppetlabs/puppetlabs-stdlib ../stdlib --branch 5.2.0 -#RUN git clone https://github.com/puppetlabs/puppetlabs-inifile ../inifile --branch 2.5.0 -#RUN git clone https://github.com/puppetlabs/puppetlabs-translate ../translate --branch 1.2.0 -#RUN git clone https://github.com/puppetlabs/puppetlabs-apt ../apt --branch 6.3.0 +# of `dependencies` in metadata.json. +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-stdlib ../stdlib && \ +# $(cd ../stdlib && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-inifile ../inifile && \ +# $(cd ../inifile && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-apt ../apt && \ +# $(cd ../apt && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) +# RUN git clone --tags https://github.com/puppetlabs/puppetlabs-facts ../facts && \ +# $(cd ../facts && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))) # Check that all dependencies are installed. RUN /opt/puppetlabs/puppet/bin/puppet module --modulepath $module_path list --tree @@ -104,8 +94,5 @@ COPY manifests/ ./manifests/ COPY docker/upgrade.pp /tmp/upgrade.pp -# Print out which versions of the puppet-agent package are available (for reference). -#RUN yum list puppet-agent --showduplicates - # Perform the upgrade. ENTRYPOINT ["/tmp/bin/run-upgrade.sh"] diff --git a/manifests/init.pp b/manifests/init.pp index 4ff9f5db5..9fad7b6b5 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -103,6 +103,8 @@ # @param skip_if_unavailable # For yum-based repositories, set the skip_if_unavailable option of the `yumrepo` type. # @param disable_proxy +# @param username The username to use when downloading from a source location requiring authentication. +# @param password The password to use when downloading from a source location requiring authentication. class puppet_agent ( String $arch = $facts['os']['architecture'], String $collection = $puppet_agent::params::collection, @@ -131,7 +133,9 @@ Optional $wait_for_pxp_agent_exit = undef, Optional $wait_for_puppet_run = undef, Array[Puppet_agent::Config] $config = [], - Stdlib::Absolutepath $version_file_path = '/opt/puppetlabs/puppet/VERSION' + Stdlib::Absolutepath $version_file_path = '/opt/puppetlabs/puppet/VERSION', + Optional $username = undef, + Optional[Sensitive] $password = undef, ) inherits puppet_agent::params { # The configure class uses $puppet_agent::config to manage settings in # puppet.conf, and will always be present. It does not require management of diff --git a/manifests/osfamily/redhat.pp b/manifests/osfamily/redhat.pp index 5192853d1..f0e640bec 100644 --- a/manifests/osfamily/redhat.pp +++ b/manifests/osfamily/redhat.pp @@ -175,6 +175,14 @@ sslclientcert => $_sslclientcert_path, sslclientkey => $_sslclientkey_path, skip_if_unavailable => $puppet_agent::skip_if_unavailable, + username => $puppet_agent::username, + password => $puppet_agent::password, + } + file { '/etc/yum.repos.d/pc_repo.repo': + ensure => file, + owner => 0, + group => 0, + mode => '0600', } } } diff --git a/manifests/osfamily/suse.pp b/manifests/osfamily/suse.pp index 86032ae64..01aa40223 100644 --- a/manifests/osfamily/suse.pp +++ b/manifests/osfamily/suse.pp @@ -137,12 +137,30 @@ # In Puppet Enterprise, agent packages are served by the same server # as the master, which can be using either a self signed CA, or an external CA. # Zypper has issues with validating a self signed CA, so for now disable ssl verification. + # don't leak credentials + $repo_username = getvar('puppet_agent::username') + $repo_password = unwrap(getvar('puppet_agent::password')) + + if $repo_username and $repo_password { + # lint:ignore:strict_indent + file { '/etc/zypp/credentials.d/PuppetcoreCreds': + ensure => file, + owner => 0, + group => 0, + mode => '0600', + content => Sensitive(@("EOT")) + username=${repo_username} + password=${repo_password} + | EOT + } + # lint:endignore + } $repo_settings = { 'name' => $repo_name, 'enabled' => '1', 'gpgcheck' => '1', 'autorefresh' => '0', - 'baseurl' => "${source}?ssl_verify=no", + 'baseurl' => "${source}?ssl_verify=no&auth=basic&credentials=PuppetcoreCreds", 'type' => 'rpm-md', } diff --git a/spec/classes/puppet_agent_osfamily_redhat_spec.rb b/spec/classes/puppet_agent_osfamily_redhat_spec.rb index 5698ea1a0..833983703 100644 --- a/spec/classes/puppet_agent_osfamily_redhat_spec.rb +++ b/spec/classes/puppet_agent_osfamily_redhat_spec.rb @@ -261,6 +261,24 @@ is_expected.to contain_yumrepo('pc_repo').with_skip_if_unavailable(true) } end + describe 'with credentials' do + let(:params) do + { + manage_repo: true, + package_version: package_version, + username: 'forge-key', + password: sensitive('open-sesame'), + } + end + + it { + is_expected.to contain_yumrepo('pc_repo') + .with( + username: 'forge-key', + password: sensitive('open-sesame'), + ) + } + end end context 'with manage_repo disabled' do diff --git a/spec/classes/puppet_agent_osfamily_suse_spec.rb b/spec/classes/puppet_agent_osfamily_suse_spec.rb index 3148fa210..79b455b3f 100644 --- a/spec/classes/puppet_agent_osfamily_suse_spec.rb +++ b/spec/classes/puppet_agent_osfamily_suse_spec.rb @@ -151,7 +151,7 @@ 'enabled' => '1', 'gpgcheck' => '1', 'autorefresh' => '0', - 'baseurl' => "http://yum.puppet.com/puppet6/sles/#{os_version}/x86_64?ssl_verify=no", + 'baseurl' => "http://yum.puppet.com/puppet6/sles/#{os_version}/x86_64?ssl_verify=no&auth=basic&credentials=PuppetcoreCreds", 'type' => 'rpm-md', }.each do |setting, value| it { @@ -203,7 +203,7 @@ 'path' => '/etc/zypp/repos.d/pc_repo.repo', 'section' => 'pc_repo', 'setting' => 'baseurl', - 'value' => "https://nightlies.puppet.com/yum/puppet6/sles/#{os_version}/x86_64?ssl_verify=no", + 'value' => "https://nightlies.puppet.com/yum/puppet6/sles/#{os_version}/x86_64?ssl_verify=no&auth=basic&credentials=PuppetcoreCreds", }) } end @@ -291,7 +291,7 @@ 'enabled' => '1', 'gpgcheck' => '1', 'autorefresh' => '0', - 'baseurl' => "https://master.example.vm:8140/packages/2000.0.0/sles-#{os_version}-x86_64?ssl_verify=no", + 'baseurl' => "https://master.example.vm:8140/packages/2000.0.0/sles-#{os_version}-x86_64?ssl_verify=no&auth=basic&credentials=PuppetcoreCreds", 'type' => 'rpm-md', }.each do |setting, value| it { @@ -341,7 +341,7 @@ 'path' => '/etc/zypp/repos.d/pc_repo.repo', 'section' => 'pc_repo', 'setting' => 'baseurl', - 'value' => "https://fake-sles-source.com/packages/2000.0.0/sles-#{os_version}-x86_64?ssl_verify=no", + 'value' => "https://fake-sles-source.com/packages/2000.0.0/sles-#{os_version}-x86_64?ssl_verify=no&auth=basic&credentials=PuppetcoreCreds", }) } end diff --git a/tasks/install.json b/tasks/install.json index 275f813f5..0df119162 100644 --- a/tasks/install.json +++ b/tasks/install.json @@ -7,7 +7,7 @@ }, "collection": { "description": "The Puppet collection to install from (defaults to puppet, which maps to the latest collection released)", - "type": "Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly]]" + "type": "Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly, puppetcore7, puppetcore8]]" }, "absolute_source": { "description": "The absolute source location to find the Puppet agent package", @@ -41,6 +41,14 @@ "description": "The number of retries in case of network connectivity failures", "type": "Optional[Integer]", "default": 5 + }, + "username": { + "description": "The username to use when downloading from a source location requiring authentication", + "type": "Optional[String]" + }, + "password": { + "description": "The password to use when downloading from a source location requiring authentication", + "type": "Optional[String]" } }, "implementations": [ diff --git a/tasks/install_shell.json b/tasks/install_shell.json index 879ca7e3d..0fc475e06 100644 --- a/tasks/install_shell.json +++ b/tasks/install_shell.json @@ -9,7 +9,7 @@ }, "collection": { "description": "The Puppet collection to install from (defaults to puppet, which maps to the latest collection released)", - "type": "Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly]]" + "type": "Optional[Enum[puppet7, puppet8, puppet, puppet7-nightly, puppet8-nightly, puppet-nightly, puppetcore7, puppetcore8]]" }, "absolute_source": { "description": "The absolute source location to find the Puppet agent package", @@ -43,6 +43,14 @@ "description": "The number of retries in case of network connectivity failures", "type": "Optional[Integer]", "default": 5 + }, + "username": { + "description": "The username to use when downloading from a source location requiring authentication", + "type": "Optional[String]" + }, + "password": { + "description": "The password to use when downloading from a source location requiring authentication", + "type": "Optional[String]" } }, "files": ["facts/tasks/bash.sh"], diff --git a/tasks/install_shell.sh b/tasks/install_shell.sh index 4a41fc41c..73104f9bd 100644 --- a/tasks/install_shell.sh +++ b/tasks/install_shell.sh @@ -100,6 +100,16 @@ if [ -n "$PT_version" ]; then version=$PT_version fi +if [ -n "$PT_username" ]; then + username=$PT_username +else + username='forge-key' +fi + +if [ -n "$PT_password" ]; then + password=$PT_password +fi + if [ -n "$PT_collection" ]; then # Check whether collection is nightly if [[ "$PT_collection" == *"nightly"* ]]; then @@ -116,10 +126,18 @@ fi if [ -n "$PT_yum_source" ]; then yum_source=$PT_yum_source else - if [ "$nightly" = true ]; then - yum_source='http://nightlies.puppet.com/yum' + if [[ "$collection" == "puppetcore"* ]]; then + yum_source='https://yum-puppetcore.puppet.com/public' + if [ -z "$password" ]; then + echo "A password parameter is required to install from ${yum_source}" + exit 1 + fi else - yum_source='http://yum.puppet.com' + if [ "$nightly" = true ]; then + yum_source='http://nightlies.puppet.com/yum' + else + yum_source='http://yum.puppet.com' + fi fi fi @@ -577,12 +595,19 @@ install_file() { if echo $2 | grep $pkg; then info "No collection upgrade detected" else - info "Collection upgrade detected, replacing puppet${major}-release" - rpm -e "puppet${major}-release" + info "Collection upgrade detected, replacing $pkg" + rpm -e "$pkg" fi fi + repo="/etc/yum.repos.d/${collection/core/}-release.repo" rpm -Uvh --oldpackage --replacepkgs "$2" + if [[ -n $username ]]; then + sed -i "s/^#\?username=.*/username=${username}/" "${repo}" + fi + if [[ -n $password ]]; then + sed -i "s/^#\?password=.*/password=${password}/" "${repo}" + fi exists dnf && PKGCMD=dnf || PKGCMD=yum if test "$version" = 'latest'; then run_cmd "${PKGCMD} install -y puppet-agent && ${PKGCMD} upgrade -y puppet-agent" @@ -601,12 +626,18 @@ install_file() { if echo $2 | grep $pkg; then info "No collection upgrade detected" else - info "Collection upgrade detected, replacing puppet${major}-release" - zypper remove --no-confirm "puppet${major}-release" + info "Collection upgrade detected, replacing $pkg" + zypper remove --no-confirm "$pkg" fi fi run_cmd "zypper install --no-confirm '$2'" + if [[ -n $username ]]; then + sed -i "s/^username=.*/username=${username}/" "/etc/zypp/credentials.d/PuppetcoreCreds" + fi + if [[ -n $password ]]; then + sed -i "s/^password=.*/password=${password}/" "/etc/zypp/credentials.d/PuppetcoreCreds" + fi if test "$version" = "latest"; then run_cmd "zypper install --no-confirm 'puppet-agent'" else @@ -624,8 +655,8 @@ install_file() { if echo $2 | grep $pkg; then info "No collection upgrade detected" else - info "Collection upgrade detected, replacing puppet${major}-release" - dpkg --purge "puppet${major}-release" + info "Collection upgrade detected, replacing $pkg" + dpkg --purge "$pkg" fi fi @@ -669,22 +700,31 @@ case $platform in info "SLES platform! Lets get you an RPM..." if [[ $PT__noop != true ]]; then - for key in "puppet" "puppet-20250406"; do - gpg_key="${tmp_dir}/RPM-GPG-KEY-${key}" - do_download "https://yum.puppet.com/RPM-GPG-KEY-${key}" "$gpg_key" - rpm --import "$gpg_key" - rm -f "$gpg_key" - done + if [[ "$PT_collection" =~ core ]]; then + for key in "puppet"; do + gpg_key="${tmp_dir}/RPM-GPG-KEY-${key}" + do_download "https://yum-puppetcore.puppet.com/public/RPM-GPG-KEY-${key}" "$gpg_key" + rpm --import "$gpg_key" + rm -f "$gpg_key" + done + else + for key in "puppet" "puppet-20250406"; do + gpg_key="${tmp_dir}/RPM-GPG-KEY-${key}" + do_download "https://yum.puppet.com/public/RPM-GPG-KEY-${key}" "$gpg_key" + rpm --import "$gpg_key" + rm -f "$gpg_key" + done + fi fi filetype="noarch.rpm" - filename="${collection}-release-sles-${platform_version}.noarch.rpm" + filename="${collection/core/}-release-sles-${platform_version}.noarch.rpm" download_url="${yum_source}/${filename}" ;; "el") info "Red hat like platform! Lets get you an RPM..." filetype="rpm" - filename="${collection}-release-el-${platform_version}.noarch.rpm" + filename="${collection/core/}-release-el-${platform_version}.noarch.rpm" download_url="${yum_source}/${filename}" ;; "Amzn"|"Amazon Linux") @@ -698,13 +738,13 @@ case $platform in elif (( platform_version == 2 || platform_version >= 2023 )); then platform_package="amazon" fi - filename="${collection}-release-${platform_package}-${platform_version}.noarch.rpm" + filename="${collection/core/}-release-${platform_package}-${platform_version}.noarch.rpm" download_url="${yum_source}/${filename}" ;; "Fedora") info "Fedora platform! Lets get the RPM..." filetype="rpm" - filename="${collection}-release-fedora-${platform_version}.noarch.rpm" + filename="${collection/core/}-release-fedora-${platform_version}.noarch.rpm" download_url="${yum_source}/${filename}" ;; "Debian")