diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f871f10e..b4d4ec9d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,13 +8,12 @@ name: "Test" jobs: lint-unit: - uses: sous-chefs/.github/.github/workflows/lint-unit.yml@8.0.2 + uses: sous-chefs/.github/.github/workflows/lint-unit.yml@8.0.4 permissions: - actions: write checks: write pull-requests: write statuses: write - issues: write + secrets: inherit integration: needs: "lint-unit" @@ -22,29 +21,39 @@ jobs: strategy: matrix: os: + - almalinux-8 + - almalinux-9 + - almalinux-10 - amazonlinux-2023 + - centos-stream-9 + - centos-stream-10 - debian-12 - debian-13 - - rockylinux-9 + - fedora-latest + - oraclelinux-8 + - oraclelinux-9 - rockylinux-8 + - rockylinux-9 + - rockylinux-10 - ubuntu-2204 - - ubuntu-2004 + - ubuntu-2404 suite: - - corretto-11 - - corretto-17 - - corretto-18 - - temurin-8 + - openjdk-11 + - openjdk-17 - temurin-11 - temurin-17 - temurin-21 + - temurin-25 + - corretto-11 + - corretto-17 fail-fast: false steps: - name: Check out code uses: actions/checkout@v6 - name: Install Chef - uses: actionshub/chef-install@6.0.0 + uses: sous-chefs/.github/.github/actions/install-workstation@8.0.4 - name: Dokken - uses: actionshub/test-kitchen@3.0.0 + uses: actionshub/test-kitchen@main env: CHEF_LICENSE: accept-no-persist KITCHEN_LOCAL_YAML: kitchen.dokken.yml @@ -56,4 +65,4 @@ jobs: runs-on: ubuntu-latest needs: [integration] steps: - - run: echo ${{needs.integration.outputs}} + - run: echo "integration completed" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe2dca8fc..7334bb529 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ permissions: jobs: release: - uses: sous-chefs/.github/.github/workflows/release-cookbook.yml@8.0.2 + uses: sous-chefs/.github/.github/workflows/release-cookbook.yml@8.0.4 secrets: token: ${{ secrets.PORTER_GITHUB_TOKEN }} supermarket_user: ${{ secrets.CHEF_SUPERMARKET_USER }} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..4013626d6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,79 @@ +# AGENTS.md + +## Purpose + +This file records maintainer and agent decisions for the Java cookbook. Keep it focused on durable +patterns, support boundaries, and non-obvious implementation choices. Do not use it as a task +changelog. + +## Modernization Scope + +This cookbook is being modernized incrementally. Preserve the existing custom-resource API where it +is still useful, and avoid broad rewrites unless the requested work explicitly calls for a full +migration. + +Prefer resource properties and helper-derived defaults over cookbook node attributes. Do not add +`attributes/` back to provide defaults for resources. + +## Resource Defaults + +Cookbook-owned defaults should live on resources as static defaults, `lazy` helper calls, or helper +methods in `libraries/`. This keeps defaults visible at the resource boundary and testable through +ChefSpec. + +Do not write cookbook state into `node.default`, `node.normal`, `node.override`, or +`node.automatic`. In particular, do not reintroduce `node['java']` as an API surface for +`java_home`, `jdk_version`, `download_path`, install type, JCE values, or similar resource inputs. + +Do not create custom Ohai plugins for cookbook defaults. Ohai automatic attributes should describe +discovered machine facts, not cookbook policy or resource configuration. + +## Platform Support + +Keep `metadata.rb`, Kitchen files, and GitHub Actions matrices aligned. Platform entries should be +current, non-EOL, and backed by either vendor support or explicit cookbook helper behavior. + +OpenJDK package installs use the platform package manager where helper logic supports the requested +Java version. Source installs remain the fallback when a requested version is not available through +the package path. + +## Dependency Management + +Use `Policyfile.rb` for dependency resolution. Keep it local-only unless a real external cookbook +dependency is introduced. Do not add `default_source :supermarket` when every cookbook in the policy +is supplied by a path. + +Avoid external cookbook dependencies for simple file edits in custom resources. Prefer native Chef +resources so unit tests and Kitchen do not need to contact Supermarket during Policyfile setup. + +Do not reintroduce Berkshelf files or ChefSpec Berkshelf loading unless there is an explicit +compatibility reason. + +## Resource Notes + +`java_alternatives` accepts `bin_cmds` as an Array. Its public actions are `:set` and `:unset`. +Keep both actions covered by ChefSpec when changing alternatives behavior. + +Linux install resources that include the shared Linux partial (`openjdk_pkg_install`, +`openjdk_source_install`, `openjdk_install`, `corretto_install`, and `temurin_package_install`) +default `reset_alternatives` to `true` through that partial. + +`java_certificate` should provide sensible resource defaults without reading `node['java']`. +Current defaults are Java 17 and a platform-specific OpenJDK package `java_home` derived from helper +logic. + +`java_jce` documents legacy Oracle JCE policy file installation only. It should not be described as +a general Java vendor installation path. JCE URL, checksum, and Java home are explicit resource +inputs; staging defaults to Chef's file cache path. + +`temurin_package_install` does not have an `air_gap` property. It supports `repository_uri` for +alternate or mirrored package repositories. The resource must not make live Adoptium API calls while +evaluating defaults. + +Amazon Corretto installs are source archive based and support the architecture-specific Corretto +archive naming handled by helper code (`x64` and `aarch64`). Kitchen and CI cover Corretto 11 and 17 +only; do not add Corretto suites for other majors unless `libraries/corretto_helpers.rb`, docs, and +tests are updated with explicit archive metadata. + +`openjdk_source_install` documentation examples should call `openjdk_source_install`, not the +dispatcher resource `openjdk_install`. diff --git a/Berksfile b/Berksfile deleted file mode 100644 index e09849c75..000000000 --- a/Berksfile +++ /dev/null @@ -1,7 +0,0 @@ -source 'https://supermarket.chef.io' - -metadata - -group :integration do - cookbook 'test', path: 'test/fixtures/cookbooks/test' -end diff --git a/Policyfile.rb b/Policyfile.rb new file mode 100644 index 000000000..9fea7a53d --- /dev/null +++ b/Policyfile.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +name 'java' + +cookbook 'java', path: '.' +cookbook 'test', path: 'test/fixtures/cookbooks/test' + +run_list 'test::base' + +named_run_list :base, 'test::base' +named_run_list :openjdk, 'test::openjdk' +named_run_list :openjdk_pkg, 'test::openjdk_pkg' +named_run_list :temurin_pkg, 'test::temurin_pkg' +named_run_list :corretto, 'test::corretto' +named_run_list :java_cert, 'test::java_cert' diff --git a/README.md b/README.md index 1673d7afa..656647478 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors) [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) -This cookbook installs a Java JDK/JRE. It defaults to installing [OpenJDK](https://openjdk.java.net/), but it can also install [AdoptOpenJDK](https://adoptopenjdk.net/) and [Amazon Corretto](https://corretto.aws/). +This cookbook installs a Java JDK/JRE. It defaults to installing [OpenJDK](https://openjdk.java.net/), but it can also install [Eclipse Temurin](https://adoptium.net/temurin/) and [Amazon Corretto](https://corretto.aws/). ## Maintainers @@ -25,14 +25,14 @@ Chef 15.3+ ## Resources -- [adoptopenjdk_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/adoptopenjdk_install.md) -- [adoptopenjdk_macos_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/adoptopenjdk_macos_install.md) - [alternatives](https://github.com/sous-chefs/java/blob/master/documentation/resources/alternatives.md) - [certificate](https://github.com/sous-chefs/java/blob/master/documentation/resources/certificate.md) - [corretto_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/corretto_install.md) - [jce](https://github.com/sous-chefs/java/blob/master/documentation/resources/jce.md) - [openjdk_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/openjdk_install.md) - [openjdk_pkg_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/openjdk_pkg_install.md) +- [openjdk_source_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/openjdk_source_install.md) +- [temurin_package_install](https://github.com/sous-chefs/java/blob/master/documentation/resources/temurin_package_install.md) ## Contributors diff --git a/documentation/resources/alternatives.md b/documentation/resources/alternatives.md index 902e4f6b5..cb599c9d1 100644 --- a/documentation/resources/alternatives.md +++ b/documentation/resources/alternatives.md @@ -15,10 +15,10 @@ The `java_alternatives` resource uses `update-alternatives` command to set and u | Name | Type | Default | Description | | -------------------- | ------------- | ------- | ---------------------------------------------------------------------------- | | `java_location` | `String` | | Java installation location | -| `bin_cmds` | `String` | | Array of Java tool names to set or unset alternatives on | +| `bin_cmds` | `Array` | | Array of Java tool names to set or unset alternatives on | | `default` | `true, false` | `true` | Whether to set the Java tools as system default. Boolean, defaults to `true` | | `priority` | `Integer` | `1061` | Priority of the alternatives. Integer, defaults to `1061` | -| `reset_alternatives` | `true, false` | `true` | Whether to reset alternatives before setting them | +| `reset_alternatives` | `true, false` | `false` | Whether to reset alternatives before setting them | - `java_location`: Java installation location. - `bin_cmds`: . @@ -29,7 +29,7 @@ The `java_alternatives` resource uses `update-alternatives` command to set and u ```ruby java_alternatives "set java alternatives" do - java_location '/usr/local/java' - bin_cmds ["java", "javac"] + java_location '/usr/local/java' + bin_cmds ["java", "javac"] end ``` diff --git a/documentation/resources/certificate.md b/documentation/resources/certificate.md index 019f1a774..864c0c873 100644 --- a/documentation/resources/certificate.md +++ b/documentation/resources/certificate.md @@ -13,17 +13,17 @@ It can also populate the keystore with a certificate retrieved from a given SSL ## Properties -| Name | Type | Default | Description | -| ----------------- | ------ | --------------------------- | --------------------------------------------------------------------------------------- | -| `java_home` | | `node['java']['java_home']` | The java home directory | -| `java_version` | | `node['java']['jdk_version']` | The java version | -| `keystore_path` | String | | Path to the keystore | -| `keystore_passwd` | String | `changeit` | Password to the keystore | -| `cert_alias` | String | | The alias of the certificate in the keystore. This defaults to the name of the resource | -| `cert_data` | String | | The certificate data to install | -| `cert_file` | String | | Path to a certificate file to install | -| `ssl_endpoint` | String | | An SSL end-point from which to download the certificate | -| `starttls` | String | | Control the TLS protocol handler when fetching a remote certificate from `ssl_endpoint` | +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `java_home` | String | Platform-specific path for `java_version` | The java home directory | +| `java_version` | String | `17` | The java version | +| `keystore_path` | String | | Path to the keystore | +| `keystore_passwd` | String | `changeit` | Password to the keystore | +| `cert_alias` | String | | The alias of the certificate in the keystore. This defaults to the name of the resource | +| `cert_data` | String | | The certificate data to install | +| `cert_file` | String | | Path to a certificate file to install | +| `ssl_endpoint` | String | | An SSL end-point from which to download the certificate | +| `starttls` | String | | Control the TLS protocol handler when fetching a remote certificate from `ssl_endpoint` | ## Examples diff --git a/documentation/resources/corretto_install.md b/documentation/resources/corretto_install.md index 2c078524d..58e9fddf9 100644 --- a/documentation/resources/corretto_install.md +++ b/documentation/resources/corretto_install.md @@ -14,21 +14,21 @@ Introduced: v8.0.0 ## Properties -| Name | Type | Default | Description | -| --------------------- | --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | -| version | String | | Java version to install | -| full_version | String | | Used to configure the package directory, change this is the version installed by the package is no longer correct | -| url | String | `default_corretto_url(version)` | The URL to download from | -| checksum | String | | The checksum for the downloaded file | -| java_home | String | Based on the version | Set to override the java_home | -| java_home_mode | Integer, String | `0755` | The permission for the Java home directory | -| java_home_owner | String | `root` | Owner of the Java Home | -| java_home_group | String | `node['root_group']` | Group for the Java Home | -| default | Boolean | `true` | Whether to set this as the default Java | -| bin_cmds | Array | `default_corretto_bin_cmds(version)` | A list of bin_cmds based on the version and variant | -| alternatives_priority | Integer | `1` | Alternatives priority to set for this Java | -| reset_alternatives | Boolean | `true` | Whether to reset alternatives before setting | -| skip_alternatives | Boolean | `false` | Skip alternatives installation completely | +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| version | String | | Java version to install | +| full_version | String | | Used to configure the package directory, change this is the version installed by the package is no longer correct | +| url | String | `default_corretto_url(version)` | The URL to download from | +| checksum | String | | The checksum for the downloaded file | +| java_home | String | Based on the version | Set to override the java_home | +| java_home_mode | Integer, String | `0755` | The permission for the Java home directory | +| java_home_owner | String | `root` | Owner of the Java Home | +| java_home_group | String | `node['root_group']` | Group for the Java Home | +| default | Boolean | `true` | Whether to set this as the default Java | +| bin_cmds | Array | `default_corretto_bin_cmds(version)` | A list of bin_cmds based on the version and variant | +| alternatives_priority | Integer | `1` | Alternatives priority to set for this Java | +| reset_alternatives | Boolean | `true` | Whether to reset alternatives before setting | +| skip_alternatives | Boolean | `false` | Skip alternatives installation completely | ## Examples diff --git a/documentation/resources/jce.md b/documentation/resources/jce.md index d07148555..3a154fa1c 100644 --- a/documentation/resources/jce.md +++ b/documentation/resources/jce.md @@ -8,18 +8,21 @@ ## Actions - `:install`: Installs the JCE policy files. +- `:remove`: Removes the staged JCE policy files, archive, and managed policy symlinks. ## Properties -| Name | Type | Default | Description | -| -------------- | ------ | -------------------------------------------------------- | -------------------------------------------------------------------------- | -| `jdk_version` | String | `node['java']['jdk_version']` | The Java version to install into | -| `jce_url` | String | `node['java']['oracle']['jce'][jdk_version]['url']` | The URL for the JCE distribution | -| `jce_checksum` | String | `node['java']['oracle']['jce'][jdk_version]['checksum']` | The checksum of the JCE distribution | -| `jce_cookie` | String | `node['java']['oracle']['accept_oracle_download_terms']` | Indicates that you accept Oracle's EULA | -| `jce_home` | String | `node['java']['oracle']['jce']['home']` | The location where JCE files will be decompressed for installation | -| `java_home` | String | `node['java']['java_home']` | The location of the Java installation | -| `principal` | String | `node['java']['windows']['owner']` | For Windows installations only, this determines the owner of the JCE files | +| Name | Type | Default | Description | +| --------------- | ------ | -------------------------------------------------------- | -------------------------------------------------------------------------- | +| `jdk_version` | String | Resource name | The Java version to install into | +| `jce_url` | String | Required | The URL for the JCE distribution | +| `jce_checksum` | String | Required | The checksum of the JCE distribution | +| `jce_cookie` | String | `''` | Indicates that you accept Oracle's EULA | +| `jce_home` | String | `/usr/lib/jvm/jce` | The location where JCE files will be decompressed for installation | +| `java_home` | String | Required | The location of the Java installation | +| `principal` | String | `administrator` | For Windows installations only, this determines the owner of the JCE files | +| `download_path` | String | Chef file cache path | Path used to stage the JCE archive | +| `install_type` | String | `jdk` | Whether the Java install is a jdk or jre layout | ## Examples diff --git a/documentation/resources/openjdk_pkg_install.md b/documentation/resources/openjdk_pkg_install.md index b135c2913..885d5bb15 100644 --- a/documentation/resources/openjdk_pkg_install.md +++ b/documentation/resources/openjdk_pkg_install.md @@ -14,18 +14,18 @@ Introduced: v8.1.0 ## Properties -| Name | Type | Default | Description | -| --------------------- | ------- | ------------------------------------ | --------------------------------------------------- | -| version | String | | Java major version to install | -| pkg_names | Array | `default_openjdk_pkg_names(version)` | List of packages to install | -| pkg_version | String | `nil` | Package version to install | -| java_home | String | Based on the version | Set to override the java_home | -| default | Boolean | `true` | Whether to set this as the default Java | -| bin_cmds | Array | `default_bin_cmds(version)` | A list of bin_cmds based on the version and variant | -| alternatives_priority | Integer | `1062` | Alternatives priority to set for this Java | -| reset_alternatives | Boolean | `true` | Whether to reset alternatives before setting | -| skip_alternatives | Boolean | `false` | Skip alternatives installation completely | -| repository_uri | String | `nil` | URI for the repository mirror to use instead of default repository URLs | +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| version | String | | Java major version to install | +| pkg_names | Array | `default_openjdk_pkg_names(version)` | List of packages to install | +| pkg_version | String | `nil` | Package version to install | +| java_home | String | Based on the version | Set to override the java_home | +| default | Boolean | `true` | Whether to set this as the default Java | +| bin_cmds | Array | `default_bin_cmds(version)` | A list of bin_cmds based on the version and variant | +| alternatives_priority | Integer | `1062` | Alternatives priority to set for this Java | +| reset_alternatives | Boolean | `true` | Whether to reset alternatives before setting | +| skip_alternatives | Boolean | `false` | Skip alternatives installation completely | +| repository_uri | String | `nil` | URI for the repository mirror to use instead of default repository URLs | ## Examples diff --git a/documentation/resources/openjdk_source_install.md b/documentation/resources/openjdk_source_install.md index c6d2f11b4..7032ba8d3 100644 --- a/documentation/resources/openjdk_source_install.md +++ b/documentation/resources/openjdk_source_install.md @@ -24,7 +24,7 @@ Introduced: v8.0.0 | java_home_owner | String | `root` | Owner of the Java Home | | java_home_group | String | `node['root_group']` | Group for the Java Home | | default | Boolean | `true` | Whether to set this as the default Java | -| bin_cmds | Array | `default_bin_cmds(version)` | A list of bin_cmds based on the version and variant | +| bin_cmds | Array | `default_bin_cmds(version)` | A list of bin_cmds based on the version and variant | | alternatives_priority | Integer | `1` | Alternatives priority to set for this Java | | reset_alternatives | Boolean | `true` | Whether to reset alternatives before setting | | skip_alternatives | Boolean | `false` | Skip alternatives installation completely | @@ -34,13 +34,13 @@ Introduced: v8.0.0 To install OpenJDK 11 and set it as the default Java: ```ruby -openjdk_install '11' +openjdk_source_install '11' ``` To install OpenJDK 11 and set it as second highest priority: ```ruby -openjdk_install '11' do +openjdk_source_install '11' do alternatives_priority 2 end ``` diff --git a/documentation/resources/temurin_package_install.md b/documentation/resources/temurin_package_install.md index 82e9779c5..a1965f8a0 100644 --- a/documentation/resources/temurin_package_install.md +++ b/documentation/resources/temurin_package_install.md @@ -2,7 +2,7 @@ [back to resource list](https://github.com/sous-chefs/java#resources) -Installs Java Temurin (AdoptOpenJDK) packages provided by Adoptium. This resource handles the repository setup and package installation for Temurin JDK packages across various platforms. +Installs Eclipse Temurin packages provided by Adoptium. This resource handles the repository setup and package installation for Temurin JDK packages across various platforms. Introduced: v12.0.0 @@ -13,19 +13,18 @@ Introduced: v12.0.0 ## Properties -| Property | Type | Default | Description | -|-----------------------|----------------|----------------------------------------|----------------------------------------------| -| `version` | String | Name Property | Java version to install (e.g. '8', '11', '17') | -| `pkg_name` | String | `temurin-#{version}-jdk` | Package name to install | -| `pkg_version` | String | `nil` | Package version to install | -| `java_home` | String | Platform-specific JAVA_HOME | Path to set as JAVA_HOME | -| `bin_cmds` | Array | Version-specific binary commands | Commands for alternatives | -| `alternatives_priority` | Integer | 1062 | Priority for alternatives system | -| `reset_alternatives` | Boolean | true | Whether to reset alternatives before setting | -| `default` | Boolean | true | Whether to set this as the default Java | -| `skip_alternatives` | Boolean | false | Skip alternatives installation completely | -| `repository_uri` | String | `nil` | URI for the repository mirror to use instead of default repository URLs | -| air_gap | Boolean | false | Whether to install in air-gap mode | +| Property | Type | Default | Description | +| --- | --- | --- | --- | +| `version` | String | Name Property | Java version to install (e.g. '8', '11', '17') | +| `pkg_name` | String | `temurin-#{version}-jdk` | Package name to install | +| `pkg_version` | String | `nil` | Package version to install | +| `java_home` | String | Platform-specific JAVA_HOME | Path to set as JAVA_HOME | +| `bin_cmds` | Array | Version-specific binary commands | Commands for alternatives | +| `alternatives_priority` | Integer | `1062` | Priority for alternatives system | +| `reset_alternatives` | Boolean | `true` | Whether to reset alternatives before setting | +| `default` | Boolean | `true` | Whether to set this as the default Java | +| `skip_alternatives` | Boolean | `false` | Skip alternatives installation completely | +| `repository_uri` | String | `nil` | URI for the repository mirror to use instead of default repository URLs | ## Platform Support @@ -80,7 +79,5 @@ Each platform will have the appropriate Adoptium repository configured automatic ## Additional Information -- This resource uses the Adoptium API to validate available releases. -- The resource will warn if a requested version is not available as an LTS release. - For most use cases, you can simply specify the major version number. -- Air-gap mode disables version checking via the Adoptium API and instead uses the version specified in the `pkg_version` property. +- `repository_uri` can point package repository setup at an internal mirror. diff --git a/kitchen.dokken.yml b/kitchen.dokken.yml index 1d8623e02..e898fcd03 100644 --- a/kitchen.dokken.yml +++ b/kitchen.dokken.yml @@ -52,11 +52,6 @@ platforms: image: dokken/fedora-latest pid_one_command: /usr/lib/systemd/systemd - - name: opensuse-leap-15 - driver: - image: dokken/opensuse-leap-15 - pid_one_command: /usr/lib/systemd/systemd - - name: oraclelinux-8 driver: image: dokken/oraclelinux-8 @@ -82,11 +77,6 @@ platforms: image: dokken/rockylinux-10 pid_one_command: /usr/lib/systemd/systemd - - name: ubuntu-20.04 - driver: - image: dokken/ubuntu-20.04 - pid_one_command: /bin/systemd - - name: ubuntu-22.04 driver: image: dokken/ubuntu-22.04 diff --git a/kitchen.global.yml b/kitchen.global.yml index 1740e4614..ad83b6239 100644 --- a/kitchen.global.yml +++ b/kitchen.global.yml @@ -17,16 +17,17 @@ verifier: platforms: - name: almalinux-8 - name: almalinux-9 + - name: almalinux-10 - name: amazonlinux-2023 - name: centos-stream-9 - - name: debian-11 + - name: centos-stream-10 - name: debian-12 + - name: debian-13 - name: fedora-latest - - name: opensuse-leap-15 - name: oraclelinux-8 - name: oraclelinux-9 - name: rockylinux-8 - name: rockylinux-9 - - name: ubuntu-20.04 + - name: rockylinux-10 - name: ubuntu-22.04 - name: ubuntu-24.04 diff --git a/kitchen.yml b/kitchen.yml index 21f690a09..cdb91a2c8 100644 --- a/kitchen.yml +++ b/kitchen.yml @@ -11,19 +11,28 @@ verifier: name: inspec platforms: + - name: almalinux-8 + - name: almalinux-9 + - name: almalinux-10 - name: amazonlinux-2023 + - name: centos-stream-9 + - name: centos-stream-10 - name: debian-12 - name: debian-13 - - name: freebsd-13 - name: fedora-latest - - name: rockylinux-9 + - name: oraclelinux-8 + - name: oraclelinux-9 - name: rockylinux-8 + - name: rockylinux-9 + - name: rockylinux-10 - name: ubuntu-22.04 - - name: ubuntu-20.04 + - name: ubuntu-24.04 suites: # OpenJDK - name: openjdk-11 + provisioner: + named_run_list: openjdk run_list: - recipe[test::openjdk] attributes: { version: "11" } @@ -32,6 +41,8 @@ suites: inputs: { java_version: "11" } - name: openjdk-17 + provisioner: + named_run_list: openjdk run_list: - recipe[test::openjdk] attributes: { version: "17" } @@ -41,6 +52,8 @@ suites: # Temurin - name: temurin-11 + provisioner: + named_run_list: temurin_pkg run_list: - recipe[test::temurin_pkg] attributes: @@ -50,6 +63,8 @@ suites: inputs: { java_version: "11" } - name: temurin-17 + provisioner: + named_run_list: temurin_pkg run_list: - recipe[test::temurin_pkg] attributes: @@ -60,6 +75,8 @@ suites: inputs: { java_version: "17" } - name: temurin-21 + provisioner: + named_run_list: temurin_pkg run_list: - recipe[test::temurin_pkg] attributes: @@ -70,6 +87,8 @@ suites: inputs: { java_version: "21" } - name: temurin-25 + provisioner: + named_run_list: temurin_pkg run_list: - recipe[test::temurin_pkg] attributes: @@ -80,15 +99,9 @@ suites: inputs: { java_version: "25" } # Corretto - - name: corretto-8 - run_list: - - recipe[test::corretto] - attributes: { version: "8" } - verifier: - inspec_tests: [test/integration/corretto] - inputs: { java_version: "8" } - - name: corretto-11 + provisioner: + named_run_list: corretto run_list: - recipe[test::corretto] attributes: { version: "11" } @@ -97,25 +110,11 @@ suites: inputs: { java_version: "11" } - name: corretto-17 + provisioner: + named_run_list: corretto run_list: - recipe[test::corretto] attributes: { version: "17" } verifier: inspec_tests: [test/integration/corretto] inputs: { java_version: "17" } - - - name: corretto-21 - run_list: - - recipe[test::corretto] - attributes: { version: "21" } - verifier: - inspec_tests: [test/integration/corretto] - inputs: { java_version: "21" } - - - name: corretto-25 - run_list: - - recipe[test::corretto] - attributes: { version: "25" } - verifier: - inspec_tests: [test/integration/corretto] - inputs: { java_version: "25" } diff --git a/libraries/bin_cmd_helpers.rb b/libraries/bin_cmd_helpers.rb index 3127b71d6..ac8de87b5 100644 --- a/libraries/bin_cmd_helpers.rb +++ b/libraries/bin_cmd_helpers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Java module Cookbook module BinCmdHelpers @@ -15,7 +17,7 @@ def default_bin_cmds(version) %w(jaotc jarsigner javac javap jconsole jdeprscan jfr jimage jjs jmap jps jshell jstat keytool rmic rmiregistry unpack200 jar java javadoc jcmd jdb jdeps jhsdb jinfo jlink jmod jrunscript jstack jstatd pack200 rmid serialver) when '17' %w(jarsigner javac javap jconsole jdeprscan jfr jimage jjs jmap jps jshell jstat keytool rmic rmiregistry unpack200 jar java javadoc jcmd jdb jdeps jhsdb jinfo jlink jmod jrunscript jstack jstatd pack200 rmid serialver) - when '18', '19', '20', '21', '22', 'latest' + when '18', '19', '20', '21', '22', '23', '24', '25', 'latest' %w(jarsigner javac javap jconsole jdeprscan jfr jimage jjs jmap jps jshell jstat keytool rmic rmiregistry unpack200 jar java javadoc jcmd jdb jdeps jhsdb jinfo jlink jmod jrunscript jstack jstatd pack200 rmid serialver jwebserver) else Chef::Log.fatal('Version specified does not have a default set of bin_cmds') diff --git a/libraries/certificate_helpers.rb b/libraries/certificate_helpers.rb index 3425fc76b..e24914867 100644 --- a/libraries/certificate_helpers.rb +++ b/libraries/certificate_helpers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Java module Cookbook module CertificateHelpers @@ -11,7 +13,7 @@ def default_truststore_path(version, java_home) end def keystore_argument(cacerts, truststore_path) - cacerts ? '-cacerts' : "-keystore #{truststore_path}" + cacerts ? ['-cacerts'] : ['-keystore', truststore_path] end end end diff --git a/libraries/corretto_helpers.rb b/libraries/corretto_helpers.rb index 0d6a8b38a..0e53c7cd0 100644 --- a/libraries/corretto_helpers.rb +++ b/libraries/corretto_helpers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Java module Cookbook module CorrettoHelpers diff --git a/libraries/openjdk_helpers.rb b/libraries/openjdk_helpers.rb index 1cde10593..30114df14 100644 --- a/libraries/openjdk_helpers.rb +++ b/libraries/openjdk_helpers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Java module Cookbook module OpenJdkHelpers @@ -9,7 +11,7 @@ def lts # e.g. https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.3%2B7/OpenJDK17U-jdk_aarch64_linux_hotspot_17.0.3_7.tar.gz def sub_dir(url) URI.parse(url) - url.split('/')[7].split('_')[0].gsub('%2', '-').downcase + url.split('/')[7].split('_').first.gsub('%2', '-').downcase end def default_openjdk_install_method(version) @@ -17,17 +19,35 @@ def default_openjdk_install_method(version) when 'amazon' 'source' when 'rhel' - supported = lts.delete('11') + supported = node['platform_version'].to_i >= 10 ? [] : lts supported.include?(version) ? 'package' : 'source' + when 'fedora' + 'source' when 'debian' - case node['platform_version'] - when '10', '18.04' - supported = lts - ['17'] - supported.include?(version) ? 'package' : 'source' - when '9' - %w(8).include?(version) ? 'package' : 'source' + if node['platform'] == 'debian' + case node['platform_version'].to_i + when 9 + %w(8).include?(version) ? 'package' : 'source' + when 10 + supported = lts - ['17'] + supported.include?(version) ? 'package' : 'source' + when 11 + lts.include?(version) ? 'package' : 'source' + when 12 + %w(17).include?(version) ? 'package' : 'source' + else + 'source' + end else - lts.include?(version) ? 'package' : 'source' + case node['platform_version'] + when '10', '18.04' + supported = lts - ['17'] + supported.include?(version) ? 'package' : 'source' + when '9' + %w(8).include?(version) ? 'package' : 'source' + else + lts.include?(version) ? 'package' : 'source' + end end else lts.include?(version) ? 'package' : 'source' diff --git a/libraries/temurin_helpers.rb b/libraries/temurin_helpers.rb index 87a2e210b..58285b7d2 100644 --- a/libraries/temurin_helpers.rb +++ b/libraries/temurin_helpers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Java module Cookbook module TemurinHelpers @@ -48,7 +50,3 @@ def temurin_version_available?(version) end end end - -# Ensure the helper is included in the recipe DSL -Chef::DSL::Recipe.include Java::Cookbook::TemurinHelpers -Chef::Resource.include Java::Cookbook::TemurinHelpers diff --git a/metadata.rb b/metadata.rb index b491406f6..999bf0853 100644 --- a/metadata.rb +++ b/metadata.rb @@ -8,16 +8,12 @@ chef_version '>= 16.0' version '14.0.1' -supports 'debian' -supports 'ubuntu' -supports 'centos' -supports 'redhat' -supports 'scientific' +supports 'almalinux', '>= 8.0' +supports 'amazon', '>= 2023.0' +supports 'centos_stream', '>= 9.0' +supports 'debian', '>= 12.0' supports 'fedora' -supports 'amazon' -supports 'oracle' -supports 'freebsd' -supports 'suse' -supports 'opensuseleap' - -depends 'line' +supports 'oracle', '>= 8.0' +supports 'redhat', '>= 8.0' +supports 'rocky', '>= 8.0' +supports 'ubuntu', '>= 22.04' diff --git a/resources/alternatives.rb b/resources/alternatives.rb index 06f680d7f..f67e7c442 100644 --- a/resources/alternatives.rb +++ b/resources/alternatives.rb @@ -1,3 +1,6 @@ +# frozen_string_literal: true + +provides :java_alternatives unified_mode true property :java_location, @@ -6,6 +9,11 @@ property :bin_cmds, Array, + callbacks: { + 'must contain only command names' => lambda { |cmds| + cmds.all? { |cmd| cmd.match?(/\A[A-Za-z0-9_.+-]+\z/) } + }, + }, description: 'Array of Java tool names to set or unset alternatives on' property :default, @@ -25,11 +33,9 @@ action :set do bin_cmds_to_setup = parse_java_alternatives - # Use not_if guard to make resource fully idempotent set_alternatives(bin_cmds_to_setup) do |cmd, alt_path| - # Skip if the alternative file already exists with our path alternative_exists = ::File.exist?("/var/lib/alternatives/#{cmd}") && - shell_out("#{alternatives_cmd} --display #{cmd}").stdout.include?(alt_path) + alternatives_display(cmd).stdout.include?(alt_path) Chef::Log.debug("Alternative for #{cmd} exists with correct path? #{alternative_exists}") alternative_exists end @@ -38,7 +44,7 @@ action :unset do new_resource.bin_cmds.each do |cmd| converge_by("Remove alternative for #{cmd}") do - shell_out("#{alternatives_cmd} --remove #{cmd} #{new_resource.java_location}/bin/#{cmd}") + shell_out!(alternatives_cmd, '--remove', cmd, "#{new_resource.java_location}/bin/#{cmd}") end end end @@ -48,6 +54,10 @@ def alternatives_cmd platform_family?('rhel', 'fedora', 'amazon') ? 'alternatives' : 'update-alternatives' end + def alternatives_display(cmd) + shell_out(alternatives_cmd, '--display', cmd) + end + def parse_java_alternatives bin_cmds_to_setup = [] new_resource.bin_cmds.each do |cmd| @@ -60,7 +70,6 @@ def parse_java_alternatives next end - # Add this command to the list of commands to process bin_cmds_to_setup << [cmd, bin_path, alt_path, priority] end bin_cmds_to_setup @@ -68,23 +77,17 @@ def parse_java_alternatives def set_alternatives(bin_cmds) bin_cmds.each do |cmd, bin_path, alt_path, priority| - # Use a custom not_if condition if provided as a block if block_given? && yield(cmd, alt_path) Chef::Log.debug "Skipping alternative for #{cmd} as it already exists with correct path" next end - # Get the full output of update-alternatives for this command - display_result = shell_out("#{alternatives_cmd} --display #{cmd}") + display_result = alternatives_display(cmd) cmd_output = display_result.stdout - # Check if the alternative exists at all alternative_system_exists = display_result.exitstatus == 0 && !cmd_output.empty? - - # Check if our specific path is already configured as an alternative our_alternative_exists = alternative_system_exists && cmd_output.include?(alt_path) - # Parse the priority of the existing alternative existing_priority = nil if our_alternative_exists if cmd_output =~ /#{Regexp.escape(alt_path)}.*priority\s+(\d+)/ @@ -92,57 +95,30 @@ def set_alternatives(bin_cmds) end end - # Only remove alternative if it exists with a different priority if our_alternative_exists && existing_priority && existing_priority != priority converge_by("Removing alternative for #{cmd} with old priority #{existing_priority}") do - remove_cmd = shell_out("#{alternatives_cmd} --remove #{cmd} #{alt_path}") - unless remove_cmd.exitstatus == 0 - raise(%( remove alternative failed )) - end + shell_out!(alternatives_cmd, '--remove', cmd, alt_path) end end - # Check if the alternative file exists at all alternative_file_exists = ::File.exist?("/var/lib/alternatives/#{cmd}") - # Install the alternative if needed if !our_alternative_exists || !alternative_file_exists converge_by("Add alternative for #{cmd}") do if new_resource.reset_alternatives && alternative_file_exists - shell_out("rm /var/lib/alternatives/#{cmd}") - end - install_cmd = shell_out("#{alternatives_cmd} --install #{bin_path} #{cmd} #{alt_path} #{priority}") - unless install_cmd.exitstatus == 0 - raise(%( install alternative failed )) + ::FileUtils.rm_f("/var/lib/alternatives/#{cmd}") end + shell_out!(alternatives_cmd, '--install', bin_path, cmd, alt_path, priority.to_s) end end - # set the alternative if default next unless new_resource.default - alternative_is_set = shell_out("#{alternatives_cmd} --display #{cmd} | grep \"link currently points to #{alt_path}\"").exitstatus == 0 + alternative_is_set = alternatives_display(cmd).stdout.include?("link currently points to #{alt_path}") next if alternative_is_set converge_by("Set alternative for #{cmd}") do Chef::Log.debug "Setting alternative for #{cmd}" - set_cmd = shell_out("#{alternatives_cmd} --set #{cmd} #{alt_path}") - unless set_cmd.exitstatus == 0 - raise(%( set alternative failed )) - end + shell_out!(alternatives_cmd, '--set', cmd, alt_path) end end end end - -action :unset do - new_resource.bin_cmds.each do |cmd| - converge_by("Remove alternative for #{cmd}") do - shell_out("#{alternatives_cmd} --remove #{cmd} #{new_resource.java_location}/bin/#{cmd}") - end - end -end - -action_class do - def alternatives_cmd - platform_family?('rhel', 'fedora', 'amazon') ? 'alternatives' : 'update-alternatives' - end -end diff --git a/resources/certificate.rb b/resources/certificate.rb index 620532193..c39e40162 100644 --- a/resources/certificate.rb +++ b/resources/certificate.rb @@ -1,21 +1,26 @@ +# frozen_string_literal: true + +provides :java_certificate unified_mode true include Java::Cookbook::CertificateHelpers +include Java::Cookbook::OpenJdkHelpers property :cert_alias, String, + regex: /\A[A-Za-z0-9_.-]+\z/, name_property: true, description: 'The alias of the certificate in the keystore. This defaults to the name of the resource' -property :java_home, - String, - default: lazy { node['java']['java_home'] }, - description: 'The java home directory' - property :java_version, String, - default: lazy { node['java']['jdk_version'] }, + default: '17', description: 'The major java version' +property :java_home, + String, + default: lazy { default_openjdk_pkg_java_home(java_version) }, + description: 'The java home directory' + property :cacerts, [true, false], default: true, @@ -41,6 +46,11 @@ property :ssl_endpoint, String, + callbacks: { + 'must be a host:port endpoint' => lambda { |endpoint| + endpoint.match?(/\A[A-Za-z0-9.-]+:\d+\z/) + }, + }, description: 'An SSL end-point from which to download the certificate' property :starttls, @@ -56,14 +66,14 @@ action :install do require 'openssl' - keystore_argument = keystore_argument(new_resource.cacerts, new_resource.keystore_path) + keystore_arguments = keystore_argument(new_resource.cacerts, new_resource.keystore_path) certdata = new_resource.cert_data || fetch_certdata hash = OpenSSL::Digest::SHA512.hexdigest(certdata) certfile = ::File.join(new_resource.file_cache_path, "#{new_resource.cert_alias}.cert.#{hash}") - cmd = Mixlib::ShellOut.new("#{new_resource.java_home}/bin/keytool -list #{keystore_argument} -storepass #{new_resource.keystore_passwd} -rfc -alias \"#{new_resource.cert_alias}\"") + cmd = keytool('-list', *keystore_arguments, '-storepass', new_resource.keystore_passwd, '-rfc', '-alias', new_resource.cert_alias) cmd.run_command keystore_cert = cmd.stdout.match(/^[-]+BEGIN.*END(\s|\w)+[-]+$/m).to_s @@ -72,16 +82,16 @@ if keystore_cert_digest == certfile_digest Chef::Log.debug("Certificate \"#{new_resource.cert_alias}\" in keystore \"#{new_resource.keystore_path}\" is up-to-date.") else - cmd = Mixlib::ShellOut.new("#{new_resource.java_home}/bin/keytool -list #{keystore_argument} -storepass #{new_resource.keystore_passwd} -v") + cmd = keytool('-list', *keystore_arguments, '-storepass', new_resource.keystore_passwd, '-v') cmd.run_command Chef::Log.debug(cmd.format_for_exception) Chef::Application.fatal!("Error querying keystore for existing certificate: #{cmd.exitstatus}", cmd.exitstatus) unless cmd.exitstatus == 0 - has_key = !cmd.stdout[/Alias name: \b#{new_resource.cert_alias}\s*$/i].nil? + has_key = !cmd.stdout[/Alias name: \b#{Regexp.escape(new_resource.cert_alias)}\s*$/i].nil? if has_key converge_by("delete existing certificate #{new_resource.cert_alias} from #{new_resource.keystore_path}") do - cmd = Mixlib::ShellOut.new("#{new_resource.java_home}/bin/keytool -delete -alias \"#{new_resource.cert_alias}\" #{keystore_argument} -storepass #{new_resource.keystore_passwd}") + cmd = keytool('-delete', '-alias', new_resource.cert_alias, *keystore_arguments, '-storepass', new_resource.keystore_passwd) cmd.run_command Chef::Log.debug(cmd.format_for_exception) unless cmd.exitstatus == 0 @@ -91,10 +101,11 @@ end end + ::FileUtils.mkdir_p(new_resource.file_cache_path) ::File.open(certfile, 'w', 0o644) { |f| f.write(certdata) } converge_by("add certificate #{new_resource.cert_alias} to keystore #{new_resource.keystore_path}") do - cmd = Mixlib::ShellOut.new("#{new_resource.java_home}/bin/keytool -import -trustcacerts -alias \"#{new_resource.cert_alias}\" -file #{certfile} #{keystore_argument} -storepass #{new_resource.keystore_passwd} -noprompt") + cmd = keytool('-import', '-trustcacerts', '-alias', new_resource.cert_alias, '-file', certfile, *keystore_arguments, '-storepass', new_resource.keystore_passwd, '-noprompt') cmd.run_command Chef::Log.debug(cmd.format_for_exception) @@ -107,17 +118,17 @@ end action :remove do - keystore_argument = keystore_argument(new_resource.cacerts, new_resource.keystore_path) + keystore_arguments = keystore_argument(new_resource.cacerts, new_resource.keystore_path) - cmd = Mixlib::ShellOut.new("#{new_resource.java_home}/bin/keytool -list #{keystore_argument} -storepass #{new_resource.keystore_passwd} -v | grep \"#{new_resource.cert_alias}\"") + cmd = keytool('-list', *keystore_arguments, '-storepass', new_resource.keystore_passwd, '-v') cmd.run_command - has_key = !cmd.stdout[/Alias name: #{new_resource.cert_alias}/].nil? - does_not_exist = cmd.stdout[/Alias <#{new_resource.cert_alias}> does not exist/].nil? + has_key = !cmd.stdout[/Alias name: #{Regexp.escape(new_resource.cert_alias)}/].nil? + does_not_exist = cmd.stdout[/Alias <#{Regexp.escape(new_resource.cert_alias)}> does not exist/] Chef::Application.fatal!("Error querying keystore for existing certificate: #{cmd.exitstatus}", cmd.exitstatus) unless (cmd.exitstatus == 0) || does_not_exist if has_key converge_by("remove certificate #{new_resource.cert_alias} from #{new_resource.keystore_path}") do - cmd = Mixlib::ShellOut.new("#{new_resource.java_home}/bin/keytool -delete -alias \"#{new_resource.cert_alias}\" #{keystore_argument} -storepass #{new_resource.keystore_passwd}") + cmd = keytool('-delete', '-alias', new_resource.cert_alias, *keystore_arguments, '-storepass', new_resource.keystore_passwd) cmd.run_command unless cmd.exitstatus == 0 Chef::Application.fatal!("Error deleting existing certificate \"#{new_resource.cert_alias}\" in " \ @@ -126,23 +137,28 @@ end end - FileUtils.rm_f("#{new_resource.file_cache_path}/#{new_resource.cert_alias}.cert.*") + FileUtils.rm_f(::Dir.glob(::File.join(new_resource.file_cache_path, "#{new_resource.cert_alias}.cert.*"))) end action_class do + def keytool(*args) + Mixlib::ShellOut.new(::File.join(new_resource.java_home, 'bin', 'keytool'), *args) + end + def fetch_certdata return IO.read(new_resource.cert_file) unless new_resource.cert_file.nil? certendpoint = new_resource.ssl_endpoint - starttls = new_resource.starttls.nil? ? '' : "-starttls #{new_resource.starttls}" unless certendpoint.nil? - cmd = Mixlib::ShellOut.new("echo QUIT | openssl s_client -showcerts -servername #{certendpoint.split(':').first} -connect #{certendpoint} #{starttls} 2> /dev/null | openssl x509") + host = certendpoint.split(':').first + starttls = new_resource.starttls.nil? ? [] : ['-starttls', new_resource.starttls] + cmd = Mixlib::ShellOut.new('openssl', 's_client', '-showcerts', '-servername', host, '-connect', certendpoint, *starttls, input: "QUIT\n", timeout: 30) cmd.run_command Chef::Log.debug(cmd.format_for_exception) Chef::Application.fatal!("Error returned when attempting to retrieve certificate from remote endpoint #{certendpoint}: #{cmd.exitstatus}", cmd.exitstatus) unless cmd.exitstatus == 0 - certout = cmd.stdout + certout = cmd.stdout[/-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m].to_s return certout unless certout.empty? Chef::Application.fatal!("Unable to parse certificate from openssl query of #{certendpoint}.", 999) end diff --git a/resources/corretto_install.rb b/resources/corretto_install.rb index 8b4a5ac45..0a5a53ac3 100644 --- a/resources/corretto_install.rb +++ b/resources/corretto_install.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + provides :corretto_install unified_mode true include Java::Cookbook::CorrettoHelpers @@ -49,8 +51,6 @@ destination extract_dir end - node.default['java']['java_home'] = new_resource.java_home - # Set up .jinfo file for update-java-alternatives template "/usr/lib/jvm/.java-#{new_resource.version}-corretto.jinfo" do cookbook 'java' @@ -92,4 +92,9 @@ only_if { ::File.exist?(extract_dir) } action :delete end + + file "/usr/lib/jvm/.java-#{new_resource.version}-corretto.jinfo" do + only_if { platform_family?('debian') } + action :delete + end end diff --git a/resources/jce.rb b/resources/jce.rb index ee11918bb..af69473e3 100644 --- a/resources/jce.rb +++ b/resources/jce.rb @@ -1,32 +1,44 @@ +# frozen_string_literal: true + +provides :java_jce unified_mode true property :jdk_version, String, - default: lazy { node['java']['jdk_version'].to_s }, description: 'The Java version to install into' + name_property: true, description: 'The Java version to install into' property :jce_url, String, - default: lazy { node['java']['oracle']['jce'][jdk_version]['url'] }, description: 'The URL for the JCE distribution' + required: true, description: 'The URL for the JCE distribution' property :jce_checksum, String, - default: lazy { node['java']['oracle']['jce'][jdk_version]['checksum'] }, description: 'The checksum of the JCE distribution' + required: true, description: 'The checksum of the JCE distribution' property :java_home, String, - default: lazy { node['java']['java_home'] }, description: 'The location of the Java installation' + required: true, description: 'The location of the Java installation' property :jce_home, String, - default: lazy { node['java']['oracle']['jce']['home'] }, description: 'The location where JCE files will be decompressed for installation' + default: '/usr/lib/jvm/jce', description: 'The location where JCE files will be decompressed for installation' property :jce_cookie, String, - default: lazy { node['java']['oracle']['accept_oracle_download_terms'] ? 'oraclelicense=accept-securebackup-cookie' : '' }, description: 'Indicates that you accept Oracles EULA' + default: '', description: 'Indicates that you accept Oracles EULA' property :principal, String, - default: lazy { platform_family?('windows') ? node['java']['windows']['owner'] : 'administrator' }, description: 'For Windows installations only, this determines the owner of the JCE files' + default: 'administrator', description: 'For Windows installations only, this determines the owner of the JCE files' + +property :download_path, + String, + default: Chef::Config[:file_cache_path], description: 'Path used to stage the JCE archive' + +property :install_type, + String, + equal_to: %w(jdk jre), + default: 'jdk', description: 'Whether the Java install is a jdk or jre layout' action :install do jdk_version = new_resource.jdk_version @@ -36,13 +48,20 @@ jce_home = new_resource.jce_home jce_cookie = new_resource.jce_cookie principal = new_resource.principal + download_path = new_resource.download_path + install_type = new_resource.install_type directory ::File.join(jce_home, jdk_version) do mode '0755' recursive true end - r = remote_file "#{node['java']['download_path']}/jce.zip" do + directory download_path do + mode '0755' + recursive true + end + + r = remote_file ::File.join(download_path, 'jce.zip') do source jce_url checksum jce_checksum headers( @@ -52,7 +71,7 @@ end # JRE installation does not have a jre folder - jre_path = node['java']['install_type'] == 'jdk' ? 'jre' : '' + jre_path = install_type == 'jdk' ? 'jre' : '' if platform_family?('windows') @@ -82,19 +101,23 @@ else package 'unzip' - package 'curl' - - execute 'extract jce' do - command <<-EOF - rm -rf java_jce - mkdir java_jce - cd java_jce - unzip -o ../jce.zip - find ./ -name '*.jar' | xargs -I JCE_JAR mv JCE_JAR #{jce_home}/#{jdk_version}/ - chmod -R 0644 #{jce_home}/#{jdk_version}/*.jar - EOF - cwd node['java']['download_path'] - creates ::File.join(jce_home, jdk_version, 'US_export_policy.jar') + + archive_file 'extract jce' do + path r.path + destination ::File.join(download_path, 'java_jce') + overwrite true + not_if { ::File.exist?(::File.join(jce_home, jdk_version, 'US_export_policy.jar')) } + end + + ruby_block 'stage jce policy jars' do + block do + ::Dir.glob(::File.join(download_path, 'java_jce', '**', '*.jar')).each do |jar| + destination = ::File.join(jce_home, jdk_version, ::File.basename(jar)) + ::FileUtils.mv(jar, destination) + ::FileUtils.chmod(0o644, destination) + end + end + not_if { ::File.exist?(::File.join(jce_home, jdk_version, 'US_export_policy.jar')) } end %w(local_policy.jar US_export_policy.jar).each do |jar| @@ -110,3 +133,32 @@ end end end + +action :remove do + jdk_version = new_resource.jdk_version + java_home = new_resource.java_home + jce_home = new_resource.jce_home + download_path = new_resource.download_path + jre_path = new_resource.install_type == 'jdk' ? 'jre' : '' + + %w(local_policy.jar US_export_policy.jar).each do |jar| + file ::File.join(java_home, jre_path, 'lib', 'security', jar) do + action :delete + only_if { ::File.symlink?(path) } + end + end + + directory ::File.join(jce_home, jdk_version) do + recursive true + action :delete + end + + directory ::File.join(download_path, 'java_jce') do + recursive true + action :delete + end + + file ::File.join(download_path, 'jce.zip') do + action :delete + end +end diff --git a/resources/openjdk_install.rb b/resources/openjdk_install.rb index dc9f38104..e5c9ce9ed 100644 --- a/resources/openjdk_install.rb +++ b/resources/openjdk_install.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + provides :openjdk_install unified_mode true include Java::Cookbook::OpenJdkHelpers @@ -5,7 +7,6 @@ property :install_type, String, - default: lazy { default_openjdk_install_method(version) }, equal_to: %w( package source ), description: 'Installation type' @@ -23,7 +24,6 @@ property :bin_cmds, Array, - default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version and variant' property :url, @@ -40,18 +40,21 @@ use 'partial/_openjdk' action :install do - if new_resource.install_type == 'package' + install_type = new_resource.install_type || default_openjdk_install_method(new_resource.version) + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + + if install_type == 'package' openjdk_pkg_install new_resource.version do pkg_names new_resource.pkg_names pkg_version new_resource.pkg_version java_home new_resource.java_home default new_resource.default - bin_cmds new_resource.bin_cmds + bin_cmds bin_cmds skip_alternatives new_resource.skip_alternatives alternatives_priority new_resource.alternatives_priority reset_alternatives new_resource.reset_alternatives end - elsif new_resource.install_type == 'source' + elsif install_type == 'source' openjdk_source_install new_resource.version do url new_resource.url checksum new_resource.checksum @@ -59,7 +62,7 @@ java_home_mode new_resource.java_home_mode java_home_group new_resource.java_home_group default new_resource.default - bin_cmds new_resource.bin_cmds + bin_cmds bin_cmds skip_alternatives new_resource.skip_alternatives alternatives_priority new_resource.alternatives_priority reset_alternatives new_resource.reset_alternatives @@ -70,19 +73,22 @@ end action :remove do - if new_resource.install_type == 'package' + install_type = new_resource.install_type || default_openjdk_install_method(new_resource.version) + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + + if install_type == 'package' openjdk_pkg_install new_resource.version do pkg_names new_resource.pkg_names pkg_version new_resource.pkg_version java_home new_resource.java_home default new_resource.default - bin_cmds new_resource.bin_cmds + bin_cmds bin_cmds skip_alternatives new_resource.skip_alternatives alternatives_priority new_resource.alternatives_priority reset_alternatives new_resource.reset_alternatives action :remove end - elsif new_resource.install_type == 'source' + elsif install_type == 'source' openjdk_source_install new_resource.version do url new_resource.url checksum new_resource.checksum @@ -90,7 +96,7 @@ java_home_mode new_resource.java_home_mode java_home_group new_resource.java_home_group default new_resource.default - bin_cmds new_resource.bin_cmds + bin_cmds bin_cmds skip_alternatives new_resource.skip_alternatives alternatives_priority new_resource.alternatives_priority reset_alternatives new_resource.reset_alternatives diff --git a/resources/openjdk_pkg_install.rb b/resources/openjdk_pkg_install.rb index 86449b0b4..783df2b83 100644 --- a/resources/openjdk_pkg_install.rb +++ b/resources/openjdk_pkg_install.rb @@ -1,21 +1,24 @@ +# frozen_string_literal: true + provides :openjdk_pkg_install unified_mode true include Java::Cookbook::OpenJdkHelpers include Java::Cookbook::BinCmdHelpers +use 'partial/_common' +use 'partial/_linux' +use 'partial/_openjdk' + property :pkg_names, [String, Array], - default: lazy { default_openjdk_pkg_names(version) }, description: 'List of packages to install' property :pkg_version, String, description: 'Package version to install' property :java_home, String, - default: lazy { default_openjdk_pkg_java_home(version) }, description: 'Set to override the java_home' property :bin_cmds, Array, - default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version and variant' property :alternatives_priority, Integer, @@ -25,11 +28,11 @@ property :repository_uri, String, description: 'URI for the repository mirror (e.g., "https://custom-mirror.example.com/openjdk/ubuntu")' -use 'partial/_common' -use 'partial/_linux' -use 'partial/_openjdk' - action :install do + pkg_names = new_resource.pkg_names || default_openjdk_pkg_names(new_resource.version) + java_home = new_resource.java_home || default_openjdk_pkg_java_home(new_resource.version) + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + if platform?('ubuntu') apt_repository 'openjdk-r-ppa' do uri new_resource.repository_uri || 'ppa:openjdk-r' @@ -37,21 +40,19 @@ end pkg_version = - if new_resource.pkg_version && new_resource.pkg_names.is_a?(String) - version new_resource.pkg_version - elsif new_resource.pkg_version && new_resource.pkg_names.is_a?(Array) - Array.new(new_resource.pkg_names.size, new_resource.pkg_version) + if new_resource.pkg_version && pkg_names.is_a?(String) + new_resource.pkg_version + elsif new_resource.pkg_version && pkg_names.is_a?(Array) + Array.new(pkg_names.size, new_resource.pkg_version) end - package new_resource.pkg_names do + package pkg_names do version pkg_version if pkg_version end - node.default['java']['java_home'] = new_resource.java_home - java_alternatives 'set-java-alternatives' do - java_location new_resource.java_home - bin_cmds new_resource.bin_cmds + java_location java_home + bin_cmds bin_cmds priority new_resource.alternatives_priority default new_resource.default reset_alternatives new_resource.reset_alternatives @@ -60,15 +61,19 @@ end action :remove do + pkg_names = new_resource.pkg_names || default_openjdk_pkg_names(new_resource.version) + java_home = new_resource.java_home || default_openjdk_pkg_java_home(new_resource.version) + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + java_alternatives 'unset-java-alternatives' do - java_location new_resource.java_home - bin_cmds new_resource.bin_cmds - only_if { ::File.exist?(new_resource.java_home) } + java_location java_home + bin_cmds bin_cmds + only_if { ::File.exist?(java_home) } not_if { new_resource.skip_alternatives } action :unset end - package new_resource.pkg_names do + package pkg_names do action :remove end diff --git a/resources/openjdk_source_install.rb b/resources/openjdk_source_install.rb index 5eef5e0ae..dae97036e 100644 --- a/resources/openjdk_source_install.rb +++ b/resources/openjdk_source_install.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + provides :openjdk_source_install unified_mode true include Java::Cookbook::OpenJdkHelpers @@ -8,20 +10,16 @@ description: 'Java version to install' property :url, String, - default: lazy { default_openjdk_url(version, variant) }, description: 'The URL to download from. Can be an internal mirror URL (e.g., "https://internal-mirror.example.com/java/openjdk/").' property :checksum, String, regex: /^[0-9a-f]{32}$|^[a-zA-Z0-9]{40,64}$/, - default: lazy { default_openjdk_checksum(version) }, description: 'The checksum for the downloaded file' property :java_home, String, - default: lazy { "/usr/lib/jvm/java-#{version}-openjdk/jdk-#{version}" }, description: 'Set to override the java_home' property :bin_cmds, Array, - default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version and variant' use 'partial/_common' @@ -30,9 +28,13 @@ use 'partial/_openjdk' action :install do - extract_dir = new_resource.java_home.split('/')[0..-2].join('/') - parent_dir = new_resource.java_home.split('/')[0..-3].join('/') - tarball_name = new_resource.url.split('/').last + url = new_resource.url || default_openjdk_url(new_resource.version, new_resource.variant) + checksum = new_resource.checksum || default_openjdk_checksum(new_resource.version) + java_home = new_resource.java_home || "/usr/lib/jvm/java-#{new_resource.version}-openjdk/jdk-#{new_resource.version}" + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + extract_dir = java_home.split('/')[0..-2].join('/') + parent_dir = java_home.split('/')[0..-3].join('/') + tarball_name = url.split('/').last directory parent_dir do owner new_resource.java_home_owner @@ -42,8 +44,8 @@ end remote_file "#{Chef::Config[:file_cache_path]}/#{tarball_name}" do - source new_resource.url - checksum new_resource.checksum + source url + checksum checksum retries new_resource.retries retry_delay new_resource.retry_delay mode '644' @@ -53,11 +55,9 @@ destination extract_dir end - node.default['java']['java_home'] = new_resource.java_home - java_alternatives 'set-java-alternatives' do - java_location new_resource.java_home - bin_cmds new_resource.bin_cmds + java_location java_home + bin_cmds bin_cmds priority new_resource.alternatives_priority default new_resource.default reset_alternatives new_resource.reset_alternatives @@ -65,18 +65,22 @@ action :set end - append_if_no_line 'Java Home' do - path '/etc/profile.d/java.sh' - line "export JAVA_HOME=#{new_resource.java_home}" + file '/etc/profile.d/java.sh' do + content "export JAVA_HOME=#{java_home}\n" + owner 'root' + group 'root' + mode '0644' end end action :remove do - extract_dir = new_resource.java_home.split('/')[0..-2].join('/') + java_home = new_resource.java_home || "/usr/lib/jvm/java-#{new_resource.version}-openjdk/jdk-#{new_resource.version}" + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + extract_dir = java_home.split('/')[0..-2].join('/') java_alternatives 'unset-java-alternatives' do - java_location new_resource.java_home - bin_cmds new_resource.bin_cmds + java_location java_home + bin_cmds bin_cmds only_if { ::File.exist?(extract_dir) } not_if { new_resource.skip_alternatives } action :unset @@ -88,4 +92,8 @@ only_if { ::File.exist?(extract_dir) } action :delete end + + file '/etc/profile.d/java.sh' do + action :delete + end end diff --git a/resources/partial/_common.rb b/resources/partial/_common.rb index 49c93c39e..c95d9b88e 100644 --- a/resources/partial/_common.rb +++ b/resources/partial/_common.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + property :version, String, name_property: true, description: 'Java version to install' diff --git a/resources/partial/_java_home.rb b/resources/partial/_java_home.rb index 8abdfc15f..a99ae72ae 100644 --- a/resources/partial/_java_home.rb +++ b/resources/partial/_java_home.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + property :java_home_mode, String, default: '0755', description: 'The permission for the Java home directory' diff --git a/resources/partial/_linux.rb b/resources/partial/_linux.rb index 3fcad6c00..d18532d32 100644 --- a/resources/partial/_linux.rb +++ b/resources/partial/_linux.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + property :alternatives_priority, Integer, default: 1, description: 'Alternatives priority to set for this Java' diff --git a/resources/partial/_macos.rb b/resources/partial/_macos.rb index 2e872fc38..0c2402fde 100644 --- a/resources/partial/_macos.rb +++ b/resources/partial/_macos.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + property :tap_url, String, description: 'The URL of the tap' diff --git a/resources/partial/_openjdk.rb b/resources/partial/_openjdk.rb index d51c680b0..ec7a07211 100644 --- a/resources/partial/_openjdk.rb +++ b/resources/partial/_openjdk.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + property :variant, String, equal_to: %w(openjdk temurin), default: 'openjdk', diff --git a/resources/temurin_package_install.rb b/resources/temurin_package_install.rb index 0a7b5b43b..b7308da30 100644 --- a/resources/temurin_package_install.rb +++ b/resources/temurin_package_install.rb @@ -1,63 +1,68 @@ +# frozen_string_literal: true + provides :temurin_package_install unified_mode true include Java::Cookbook::OpenJdkHelpers -include Java::Cookbook::TemurinHelpers include Java::Cookbook::BinCmdHelpers +use 'partial/_common' +use 'partial/_linux' + def default_temurin_pkg_name(version) - # Validate version against available releases - unless temurin_version_available?(version) - Chef::Log.warn("Temurin version #{version} might not be available. Available LTS versions: #{temurin_lts_versions.join(', ')}") - end "temurin-#{version}-jdk" end +def default_temurin_rpm_baseurl + return 'https://packages.adoptium.net/artifactory/rpm/amazonlinux/2/$basearch' if platform?('amazon') + + repository_platform = value_for_platform( + %w(almalinux oracle redhat rocky) => { 'default' => 'rhel' }, + 'centos' => { 'default' => 'centos' }, + 'fedora' => { 'default' => 'fedora' }, + 'default' => node['platform'] + ) + + "https://packages.adoptium.net/artifactory/rpm/#{repository_platform}/$releasever/$basearch" +end + property :pkg_name, String, - default: lazy { default_temurin_pkg_name(version) }, description: 'Package name to install' property :pkg_version, String, description: 'Package version to install' property :java_home, String, - default: lazy { "/usr/lib/jvm/temurin-#{version}-jdk" }, description: 'Set to override the java_home' property :bin_cmds, Array, - default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version' property :repository_uri, String, description: 'URI for the repository mirror (e.g., "https://custom-mirror.example.com/artifactory/deb")' -use 'partial/_common' -use 'partial/_linux' - action :install do + keyring_path = '/usr/share/keyrings/adoptium.asc' + pkg_name = new_resource.pkg_name || default_temurin_pkg_name(new_resource.version) + java_home = new_resource.java_home || "/usr/lib/jvm/temurin-#{new_resource.version}-jdk" + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + + remote_file keyring_path do + source 'https://packages.adoptium.net/artifactory/api/gpg/key/public' + mode '0644' + only_if { platform_family?('debian') } + end + apt_repository 'adoptium' do uri new_resource.repository_uri || 'https://packages.adoptium.net/artifactory/deb' components ['main'] distribution lazy { node['lsb']['codename'] || node['debian']['distribution_codename'] } - # TODO: https://github.com/chef/chef/pull/15043 - # key '843C48A565F8F04B' - # keyserver 'keyserver.ubuntu.com' - signed_by false - trusted true + signed_by keyring_path only_if { platform_family?('debian') } end yum_repository 'adoptium' do description 'Eclipse Adoptium' - baseurl new_resource.repository_uri || value_for_platform( - 'amazon' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/amazonlinux/2/$basearch' }, - 'centos' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/centos/$releasever/$basearch' }, - 'fedora' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/fedora/$releasever/$basearch' }, - 'opensuse' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/opensuse/$releasever/$basearch' }, - 'oracle' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/oraclelinux/$releasever/$basearch' }, - 'redhat' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/rhel/$releasever/$basearch' }, - 'rocky' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/rocky/8/$basearch' }, - 'suse' => { 'default' => 'https://packages.adoptium.net/artifactory/rpm/sles/$releasever/$basearch' } - ) + baseurl new_resource.repository_uri || default_temurin_rpm_baseurl enabled true gpgcheck true gpgkey 'https://packages.adoptium.net/artifactory/api/gpg/key/public' @@ -73,15 +78,13 @@ def default_temurin_pkg_name(version) only_if { platform_family?('suse') } end - package new_resource.pkg_name do + package pkg_name do version new_resource.pkg_version if new_resource.pkg_version end - node.default['java']['java_home'] = new_resource.java_home - java_alternatives 'set-java-alternatives' do - java_location new_resource.java_home - bin_cmds new_resource.bin_cmds + java_location java_home + bin_cmds bin_cmds priority new_resource.alternatives_priority default new_resource.default reset_alternatives new_resource.reset_alternatives @@ -90,15 +93,19 @@ def default_temurin_pkg_name(version) end action :remove do + pkg_name = new_resource.pkg_name || default_temurin_pkg_name(new_resource.version) + java_home = new_resource.java_home || "/usr/lib/jvm/temurin-#{new_resource.version}-jdk" + bin_cmds = new_resource.bin_cmds || default_bin_cmds(new_resource.version) + java_alternatives 'unset-java-alternatives' do - java_location new_resource.java_home - bin_cmds new_resource.bin_cmds - only_if { ::File.exist?(new_resource.java_home) } + java_location java_home + bin_cmds bin_cmds + only_if { ::File.exist?(java_home) } action :unset not_if { new_resource.skip_alternatives } end - package new_resource.pkg_name do + package pkg_name do action :remove end @@ -107,6 +114,11 @@ def default_temurin_pkg_name(version) only_if { platform_family?('debian') } end + file '/usr/share/keyrings/adoptium.asc' do + action :delete + only_if { platform_family?('debian') } + end + yum_repository 'adoptium' do action :remove only_if { platform_family?('rhel', 'fedora', 'amazon', 'rocky', 'suse', 'oraclelinux') } diff --git a/spec/libraries/bin_cmd_helpers_spec.rb b/spec/libraries/bin_cmd_helpers_spec.rb new file mode 100644 index 000000000..2217ca20b --- /dev/null +++ b/spec/libraries/bin_cmd_helpers_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Java::Cookbook::BinCmdHelpers do + subject(:helper) do + Class.new do + include Java::Cookbook::BinCmdHelpers + end.new + end + + describe '#default_bin_cmds' do + it 'returns Java command alternatives for Temurin 25' do + expect(helper.default_bin_cmds('25')).to include('java', 'javac', 'keytool', 'jwebserver') + end + + it 'logs a fatal error for unsupported versions' do + allow(Chef::Log).to receive(:fatal) + + helper.default_bin_cmds('26') + + expect(Chef::Log).to have_received(:fatal).with('Version specified does not have a default set of bin_cmds') + end + end +end diff --git a/spec/libraries/certificate_helpers_spec.rb b/spec/libraries/certificate_helpers_spec.rb index 59fd240fa..0f60f40b3 100644 --- a/spec/libraries/certificate_helpers_spec.rb +++ b/spec/libraries/certificate_helpers_spec.rb @@ -24,7 +24,7 @@ class DummyClass < Chef::Node let(:truststore_path) { '/usr/lib/jvm/corretto-9/jre/lib/security/cacerts' } it 'returns the correct argument' do - expect(subject.keystore_argument(cacerts, truststore_path)).to eq('-cacerts') + expect(subject.keystore_argument(cacerts, truststore_path)).to eq(['-cacerts']) end end @@ -33,7 +33,7 @@ class DummyClass < Chef::Node let(:truststore_path) { '/mycertstore.jks' } it 'returns the correct argument' do - expect(subject.keystore_argument(cacerts, truststore_path)).to eq('-keystore /mycertstore.jks') + expect(subject.keystore_argument(cacerts, truststore_path)).to eq(['-keystore', '/mycertstore.jks']) end end end diff --git a/spec/libraries/openjdk_helpers_spec.rb b/spec/libraries/openjdk_helpers_spec.rb index e541ffdf9..b9950f9b0 100644 --- a/spec/libraries/openjdk_helpers_spec.rb +++ b/spec/libraries/openjdk_helpers_spec.rb @@ -54,11 +54,13 @@ class DummyClass < Chef::Node before do allow(subject).to receive(:[]).with(version).and_return(version) allow(subject).to receive(:[]).with('platform_family').and_return(platform_family) + allow(subject).to receive(:[]).with('platform').and_return(platform) allow(subject).to receive(:[]).with('platform_version').and_return(platform_version) end context 'Amazon' do let(:platform_family) { 'amazon' } + let(:platform) { 'amazon' } let(:platform_version) { '2' } let(:version) { '17' } it 'should default to a source install' do @@ -66,8 +68,75 @@ class DummyClass < Chef::Node end end + context 'RHEL 9' do + let(:platform_family) { 'rhel' } + let(:platform) { 'almalinux' } + let(:platform_version) { '9.6' } + + context 'OpenJDK 11' do + let(:version) { '11' } + + it 'should default to a package install' do + expect(subject.default_openjdk_install_method(version)).to eq 'package' + end + end + + context 'OpenJDK 17' do + let(:version) { '17' } + + it 'should default to a package install' do + expect(subject.default_openjdk_install_method(version)).to eq 'package' + end + end + end + + context 'RHEL 10' do + let(:platform_family) { 'rhel' } + let(:platform) { 'almalinux' } + let(:platform_version) { '10.2' } + + context 'OpenJDK 11' do + let(:version) { '11' } + + it 'should default to a source install' do + expect(subject.default_openjdk_install_method(version)).to eq 'source' + end + end + + context 'OpenJDK 17' do + let(:version) { '17' } + + it 'should default to a source install' do + expect(subject.default_openjdk_install_method(version)).to eq 'source' + end + end + end + + context 'Fedora' do + let(:platform_family) { 'fedora' } + let(:platform) { 'fedora' } + let(:platform_version) { '44' } + + context 'OpenJDK 11' do + let(:version) { '11' } + + it 'should default to a source install' do + expect(subject.default_openjdk_install_method(version)).to eq 'source' + end + end + + context 'OpenJDK 17' do + let(:version) { '17' } + + it 'should default to a source install' do + expect(subject.default_openjdk_install_method(version)).to eq 'source' + end + end + end + context 'Debian' do let(:platform_family) { 'debian' } + let(:platform) { 'debian' } context '9' do let(:platform_version) { '9' } @@ -137,7 +206,40 @@ class DummyClass < Chef::Node end end + context '12' do + let(:platform_version) { '12' } + + context 'OpenJDK 11' do + let(:version) { '11' } + + it 'should default to a source install' do + expect(subject.default_openjdk_install_method(version)).to eq 'source' + end + end + + context 'OpenJDK 17' do + let(:version) { '17' } + + it 'should default to a package install' do + expect(subject.default_openjdk_install_method(version)).to eq 'package' + end + end + end + + context '13' do + let(:platform_version) { '13' } + + context 'OpenJDK 17' do + let(:version) { '17' } + + it 'should default to a source install' do + expect(subject.default_openjdk_install_method(version)).to eq 'source' + end + end + end + context 'Ubuntu 18.04' do + let(:platform) { 'ubuntu' } let(:platform_version) { '18.04' } context 'OpenJDK 17' do @@ -158,6 +260,7 @@ class DummyClass < Chef::Node end context 'Ubuntu 20.04' do + let(:platform) { 'ubuntu' } let(:platform_version) { '20.04' } context 'OpenJDK 17' do diff --git a/spec/resources/alternatives_spec.rb b/spec/resources/alternatives_spec.rb new file mode 100644 index 000000000..cdc5ad204 --- /dev/null +++ b/spec/resources/alternatives_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'java_alternatives' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['java_alternatives']) } + + it 'converges with an empty command list without shelling out' do + expect { runner.converge('test::alternatives_spec') }.not_to raise_error + end + + it 'supports unsetting command alternatives' do + stubs_for_provider('java_alternatives[test-unset-alternatives]') do |provider| + allow(provider).to receive_shell_out('update-alternatives', '--remove', 'java', '/opt/java/bin/java') + end + + expect { runner.converge('test::alternatives_unset_spec') }.not_to raise_error + end +end diff --git a/spec/resources/certificate_spec.rb b/spec/resources/certificate_spec.rb new file mode 100644 index 000000000..f71fd487c --- /dev/null +++ b/spec/resources/certificate_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'java_certificate' do + let(:shellout) do + instance_double(Mixlib::ShellOut, run_command: nil, stdout: '', exitstatus: 0, format_for_exception: '') + end + + before do + allow(Mixlib::ShellOut).to receive(:new).and_return(shellout) + end + + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['java_certificate']) } + + it 'steps into certificate install without invoking host keytool' do + expect { runner.converge('test::certificate_spec') }.not_to raise_error + end +end diff --git a/spec/resources/corretto_install_spec.rb b/spec/resources/corretto_install_spec.rb new file mode 100644 index 000000000..c42aaf13b --- /dev/null +++ b/spec/resources/corretto_install_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'corretto_install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['corretto_install']) } + let(:converge) { runner.converge('test::corretto_spec') } + + it 'downloads the Corretto archive' do + expect(converge).to create_remote_file(::File.join(Chef::Config[:file_cache_path], 'corretto.tar.gz')) + end + + it 'creates a Debian jinfo file' do + expect(converge).to create_template('/usr/lib/jvm/.java-17-corretto.jinfo') + end +end diff --git a/spec/resources/jce_spec.rb b/spec/resources/jce_spec.rb new file mode 100644 index 000000000..1524c614c --- /dev/null +++ b/spec/resources/jce_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'java_jce' do + context 'install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['java_jce']) } + let(:converge) { runner.converge('test::jce_spec') } + + it 'downloads the JCE archive to the explicit download path' do + expect(converge).to create_remote_file('/tmp/java/jce.zip') + end + + it 'extracts the archive without a shell execute resource' do + expect(converge).to extract_archive_file('extract jce') + expect(converge).to_not run_execute('extract jce') + end + end + + context 'remove' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['java_jce']) } + let(:converge) { runner.converge('test::jce_remove_spec') } + + it 'removes staged JCE artifacts' do + expect(converge).to delete_directory('/usr/lib/jvm/jce/17') + expect(converge).to delete_file('/tmp/java/jce.zip') + end + end +end diff --git a/spec/resources/openjdk_install_spec.rb b/spec/resources/openjdk_install_spec.rb new file mode 100644 index 000000000..6451c4fe7 --- /dev/null +++ b/spec/resources/openjdk_install_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'openjdk_install' do + context 'package install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['openjdk_install']) } + + let(:converge) do + runner.converge('test::openjdk_package_spec') + end + + it 'delegates to openjdk_pkg_install' do + expect(converge).to install_openjdk_pkg_install('17').with( + pkg_names: %w(openjdk-17-jdk openjdk-17-jre-headless), + java_home: '/usr/lib/jvm/java-17-openjdk-amd64', + bin_cmds: %w(java javac), + skip_alternatives: true + ) + end + end + + context 'source install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['openjdk_install']) } + + let(:converge) do + runner.converge('test::openjdk_source_spec') + end + + it 'delegates to openjdk_source_install' do + expect(converge).to install_openjdk_source_install('17').with( + url: 'https://example.test/openjdk.tar.gz', + checksum: 'a' * 64, + java_home: '/usr/lib/jvm/java-17-openjdk/jdk-17', + bin_cmds: %w(java javac), + skip_alternatives: true + ) + end + end +end diff --git a/spec/resources/openjdk_pkg_install_spec.rb b/spec/resources/openjdk_pkg_install_spec.rb new file mode 100644 index 000000000..e1ddb0c86 --- /dev/null +++ b/spec/resources/openjdk_pkg_install_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'openjdk_pkg_install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['openjdk_pkg_install']) } + + let(:converge) do + runner.converge('test::openjdk_pkg_spec') + end + + it 'installs the requested OpenJDK packages' do + expect(converge).to install_package(%w(openjdk-17-jdk openjdk-17-jre-headless)) + end + + it 'does not write node java_home state' do + expect(converge.node.default_attrs).not_to have_key('java') + expect(converge.node.normal_attrs).not_to have_key('java') + expect(converge.node.override_attrs).not_to have_key('java') + end +end diff --git a/spec/resources/openjdk_source_install_spec.rb b/spec/resources/openjdk_source_install_spec.rb new file mode 100644 index 000000000..ba4e723e0 --- /dev/null +++ b/spec/resources/openjdk_source_install_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'openjdk_source_install' do + context 'install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['openjdk_source_install']) } + let(:converge) { runner.converge('test::openjdk_source_direct_spec') } + + it 'downloads the source archive' do + expect(converge).to create_remote_file(::File.join(Chef::Config[:file_cache_path], 'openjdk.tar.gz')) + end + + it 'sets JAVA_HOME in the profile file' do + resource = converge.resource_collection.to_a.find do |candidate| + candidate.resource_name == :file && candidate.name == '/etc/profile.d/java.sh' + end + + expect(resource.content).to eq("export JAVA_HOME=/usr/lib/jvm/java-17-openjdk/jdk-17\n") + expect(resource.mode).to eq('0644') + end + end + + context 'remove' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['openjdk_source_install']) } + let(:converge) { runner.converge('test::openjdk_source_remove_spec') } + + it 'removes the managed JAVA_HOME line' do + resource = converge.resource_collection.to_a.find do |candidate| + candidate.resource_name == :file && candidate.name == '/etc/profile.d/java.sh' + end + + expect(resource.action).to eq([:delete]) + end + end +end diff --git a/spec/resources/temurin_package_install_spec.rb b/spec/resources/temurin_package_install_spec.rb new file mode 100644 index 000000000..4cb660fec --- /dev/null +++ b/spec/resources/temurin_package_install_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'temurin_package_install' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '24.04', step_into: ['temurin_package_install']) } + + let(:converge) do + runner.converge('test::temurin_package_spec') + end + + it 'installs the Adoptium apt keyring' do + expect(converge).to create_remote_file('/usr/share/keyrings/adoptium.asc').with( + source: 'https://packages.adoptium.net/artifactory/api/gpg/key/public', + mode: '0644' + ) + end + + it 'configures the apt repository with signed_by instead of trusted mode' do + expect(converge).to add_apt_repository('adoptium').with( + signed_by: '/usr/share/keyrings/adoptium.asc' + ) + end + + it 'installs the Temurin package' do + expect(converge).to install_package('temurin-17-jdk') + end + + context 'on AlmaLinux' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'almalinux', version: '8', step_into: ['temurin_package_install']) } + + it 'uses the RHEL-compatible Adoptium RPM repository' do + expect(converge).to create_yum_repository('adoptium').with( + baseurl: 'https://packages.adoptium.net/artifactory/rpm/rhel/$releasever/$basearch' + ) + end + end + + context 'on Amazon Linux' do + let(:runner) { ChefSpec::SoloRunner.new(platform: 'amazon', version: '2', step_into: ['temurin_package_install']) } + + it 'uses the Adoptium Amazon Linux 2 RPM repository' do + expect(converge).to create_yum_repository('adoptium').with( + baseurl: 'https://packages.adoptium.net/artifactory/rpm/amazonlinux/2/$basearch' + ) + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 317bf1fa2..b9669727e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,25 @@ require 'chefspec' -require 'chefspec/berkshelf' +require 'chefspec/policyfile' require_relative '../libraries/certificate_helpers' +require_relative '../libraries/bin_cmd_helpers' require_relative '../libraries/corretto_helpers' require_relative '../libraries/openjdk_helpers' +module PolicyfileCookbookPath + def initialize(options = {}) + if Array(options[:cookbook_path]).include?('spec/fixtures/cookbooks') + options = options.merge( + cookbook_path: Array(RSpec.configuration.cookbook_path) + [File.expand_path('fixtures/cookbooks', __dir__)] + ) + end + + super(options) + end +end + +ChefSpec::SoloRunner.prepend(PolicyfileCookbookPath) + RSpec.configure do |config| config.file_cache_path = File.join(Dir.tmpdir, 'chefspec') if config.respond_to?(:file_cache_path) config.color = true diff --git a/templates/jdk.sh.erb b/templates/jdk.sh.erb deleted file mode 100644 index 39486d3ce..000000000 --- a/templates/jdk.sh.erb +++ /dev/null @@ -1 +0,0 @@ -export JAVA_HOME=<%= node['java']['java_home']%> diff --git a/test/fixtures/cookbooks/test/recipes/alternatives_spec.rb b/test/fixtures/cookbooks/test/recipes/alternatives_spec.rb new file mode 100644 index 000000000..f4167760d --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/alternatives_spec.rb @@ -0,0 +1,4 @@ +java_alternatives 'test-alternatives' do + java_location '/opt/java' + bin_cmds [] +end diff --git a/test/fixtures/cookbooks/test/recipes/alternatives_unset_spec.rb b/test/fixtures/cookbooks/test/recipes/alternatives_unset_spec.rb new file mode 100644 index 000000000..ef7469a8d --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/alternatives_unset_spec.rb @@ -0,0 +1,5 @@ +java_alternatives 'test-unset-alternatives' do + java_location '/opt/java' + bin_cmds ['java'] + action :unset +end diff --git a/test/fixtures/cookbooks/test/recipes/certificate_spec.rb b/test/fixtures/cookbooks/test/recipes/certificate_spec.rb new file mode 100644 index 000000000..f467a8867 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/certificate_spec.rb @@ -0,0 +1,20 @@ +java_certificate 'java_certificate_test' do + cert_data <<~CERT + -----BEGIN CERTIFICATE----- + MIICjzCCAfigAwIBAgIJAOXrhcX4ZaGtMA0GCSqGSIb3DQEBBQUAMDoxCzAJBgNV + BAYTAlVTMQ0wCwYDVQQIEwRUZXN0MQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQDEwR0 + ZXN0MB4XDTE2MTAxMzAxMTkzOVoXDTM2MTAwODAxMTkzOVowOjELMAkGA1UEBhMC + VVMxDTALBgNVBAgTBFRlc3QxDTALBgNVBAoTBFRlc3QxDTALBgNVBAMTBHRlc3Qw + gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALu8/ylmItn9wUOB4qvlONEiFQpJ + DCK5bt/OkjT02Knm+aAEZS1EDTVEiZWkumM884fd2+WgaMREk02Gy6u5CraOTtEz + VjLeHdr7V9CBZpR6l5gmUY5Ujk1coHZImiqRs3STLVlWHJGjzLXMkRx10CIU8SHC + zgTr57kNG/FT+e25AgMBAAGjgZwwgZkwHQYDVR0OBBYEFP3Ox0pHbZ0u6z746Hp0 + Yk1EBTacMGoGA1UdIwRjMGGAFP3Ox0pHbZ0u6z746Hp0Yk1EBTacoT6kPDA6MQsw + CQYDVQQGEwJVUzENMAsGA1UECBMEVGVzdDENMAsGA1UEChMEVGVzdDENMAsGA1UE + AxMEdGVzdIIJAOXrhcX4ZaGtMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD + gYEAG4idDXusAZ9OrzqdWdFQ+rhQYRovZnfSgPSdF7hugWL5i/qGGlsFjZld2Kyj + X0msGzk61iW7C6kv6OfPGaGNzdNtsH8jUvIYP1IrKpf1NKTKetIWiP08ZI1XNF4H + bXmOxdtxzlHW4qukka+HkK0RBrwX35C8HYqePmInI51JnqY= + -----END CERTIFICATE----- + CERT +end diff --git a/test/fixtures/cookbooks/test/recipes/corretto.rb b/test/fixtures/cookbooks/test/recipes/corretto.rb index c79294d62..338e87fef 100644 --- a/test/fixtures/cookbooks/test/recipes/corretto.rb +++ b/test/fixtures/cookbooks/test/recipes/corretto.rb @@ -1,3 +1,12 @@ -corretto_install node['version'] +extend Java::Cookbook::CorrettoHelpers + +version = node['version'].to_s +java_home = "/usr/lib/jvm/java-#{version}-corretto/#{corretto_sub_dir(version)}" + +corretto_install version do + java_home java_home +end + +node.run_state['java_certificate_java_home'] = java_home include_recipe 'test::java_cert' diff --git a/test/fixtures/cookbooks/test/recipes/corretto_spec.rb b/test/fixtures/cookbooks/test/recipes/corretto_spec.rb new file mode 100644 index 000000000..9664c1eb4 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/corretto_spec.rb @@ -0,0 +1,7 @@ +declare_resource(:corretto_install, '17') do + url 'https://example.test/corretto.tar.gz' + checksum 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + java_home '/usr/lib/jvm/java-17-corretto/amazon-corretto-17' + bin_cmds %w(java javac) + skip_alternatives true +end diff --git a/test/fixtures/cookbooks/test/recipes/java_cert.rb b/test/fixtures/cookbooks/test/recipes/java_cert.rb index 857d18747..7931ce01b 100644 --- a/test/fixtures/cookbooks/test/recipes/java_cert.rb +++ b/test/fixtures/cookbooks/test/recipes/java_cert.rb @@ -1,4 +1,5 @@ version = node['version'].to_s +certificate_java_home = node.run_state['java_certificate_java_home'] cookbook_file '/tmp/java_certificate_test.pem' do source 'java_certificate_test.pem' @@ -7,15 +8,18 @@ java_certificate 'java_certificate_test' do cert_file '/tmp/java_certificate_test.pem' java_version version + java_home certificate_java_home if certificate_java_home end java_certificate 'java_certificate_ssl_endpoint' do ssl_endpoint 'google.com:443' java_version version + java_home certificate_java_home if certificate_java_home end java_certificate 'java_certificate_ssl_endpoint' do java_version version + java_home certificate_java_home if certificate_java_home action :remove end @@ -23,9 +27,11 @@ ssl_endpoint 'smtp.gmail.com:587' starttls 'smtp' java_version version + java_home certificate_java_home if certificate_java_home end java_certificate 'java_certificate_ssl_endpoint_starttls_smtp' do java_version version + java_home certificate_java_home if certificate_java_home action :remove end diff --git a/test/fixtures/cookbooks/test/recipes/jce_remove_spec.rb b/test/fixtures/cookbooks/test/recipes/jce_remove_spec.rb new file mode 100644 index 000000000..7e5d05e6d --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/jce_remove_spec.rb @@ -0,0 +1,9 @@ +declare_resource(:java_jce, '17') do + jce_url 'https://example.test/jce.zip' + jce_checksum 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + java_home '/usr/lib/jvm/java-17-openjdk-amd64' + jce_home '/usr/lib/jvm/jce' + download_path '/tmp/java' + install_type 'jdk' + action :remove +end diff --git a/test/fixtures/cookbooks/test/recipes/jce_spec.rb b/test/fixtures/cookbooks/test/recipes/jce_spec.rb new file mode 100644 index 000000000..51ac74273 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/jce_spec.rb @@ -0,0 +1,8 @@ +declare_resource(:java_jce, '17') do + jce_url 'https://example.test/jce.zip' + jce_checksum 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + java_home '/usr/lib/jvm/java-17-openjdk-amd64' + jce_home '/usr/lib/jvm/jce' + download_path '/tmp/java' + install_type 'jdk' +end diff --git a/test/fixtures/cookbooks/test/recipes/openjdk_package_spec.rb b/test/fixtures/cookbooks/test/recipes/openjdk_package_spec.rb new file mode 100644 index 000000000..4f4138665 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/openjdk_package_spec.rb @@ -0,0 +1,7 @@ +declare_resource(:openjdk_install, '17') do + install_type 'package' + pkg_names %w(openjdk-17-jdk openjdk-17-jre-headless) + java_home '/usr/lib/jvm/java-17-openjdk-amd64' + bin_cmds %w(java javac) + skip_alternatives true +end diff --git a/test/fixtures/cookbooks/test/recipes/openjdk_pkg_spec.rb b/test/fixtures/cookbooks/test/recipes/openjdk_pkg_spec.rb new file mode 100644 index 000000000..5bb3e045f --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/openjdk_pkg_spec.rb @@ -0,0 +1,6 @@ +declare_resource(:openjdk_pkg_install, '17') do + pkg_names %w(openjdk-17-jdk openjdk-17-jre-headless) + java_home '/usr/lib/jvm/java-17-openjdk-amd64' + bin_cmds %w(java javac) + skip_alternatives true +end diff --git a/test/fixtures/cookbooks/test/recipes/openjdk_source_direct_spec.rb b/test/fixtures/cookbooks/test/recipes/openjdk_source_direct_spec.rb new file mode 100644 index 000000000..9a2207bb8 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/openjdk_source_direct_spec.rb @@ -0,0 +1,7 @@ +declare_resource(:openjdk_source_install, '17') do + url 'https://example.test/openjdk.tar.gz' + checksum 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + java_home '/usr/lib/jvm/java-17-openjdk/jdk-17' + bin_cmds %w(java javac) + skip_alternatives true +end diff --git a/test/fixtures/cookbooks/test/recipes/openjdk_source_remove_spec.rb b/test/fixtures/cookbooks/test/recipes/openjdk_source_remove_spec.rb new file mode 100644 index 000000000..c822322c0 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/openjdk_source_remove_spec.rb @@ -0,0 +1,8 @@ +declare_resource(:openjdk_source_install, '17') do + url 'https://example.test/openjdk.tar.gz' + checksum 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + java_home '/usr/lib/jvm/java-17-openjdk/jdk-17' + bin_cmds %w(java javac) + skip_alternatives true + action :remove +end diff --git a/test/fixtures/cookbooks/test/recipes/openjdk_source_spec.rb b/test/fixtures/cookbooks/test/recipes/openjdk_source_spec.rb new file mode 100644 index 000000000..b4a6227aa --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/openjdk_source_spec.rb @@ -0,0 +1,8 @@ +declare_resource(:openjdk_install, '17') do + install_type 'source' + url 'https://example.test/openjdk.tar.gz' + checksum 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + java_home '/usr/lib/jvm/java-17-openjdk/jdk-17' + bin_cmds %w(java javac) + skip_alternatives true +end diff --git a/test/fixtures/cookbooks/test/recipes/temurin_package_spec.rb b/test/fixtures/cookbooks/test/recipes/temurin_package_spec.rb new file mode 100644 index 000000000..bc3b4eec7 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/temurin_package_spec.rb @@ -0,0 +1,4 @@ +declare_resource(:temurin_package_install, '17') do + bin_cmds %w(java javac) + skip_alternatives true +end diff --git a/test/integration/custom-package/controls/verify_home.rb b/test/integration/custom-package/controls/verify_home.rb index bad2ff4d6..9b63691d1 100644 --- a/test/integration/custom-package/controls/verify_home.rb +++ b/test/integration/custom-package/controls/verify_home.rb @@ -11,7 +11,7 @@ desc 'Verify the correct version of java is installed' describe command('java -version 2>&1') do - its('stdout') { should match /AdoptOpenJDK/ } unless java_version.to_i == 1 + its('stdout') { should match(/OpenJDK|Temurin|Corretto/) } unless java_version.to_i == 1 its('stdout') { should match Regexp.new(java_version.to_s) } end end diff --git a/test/integration/openjdk/controls/verify_openjdk.rb b/test/integration/openjdk/controls/verify_openjdk.rb index 64e62479b..cd5a75f0f 100644 --- a/test/integration/openjdk/controls/verify_openjdk.rb +++ b/test/integration/openjdk/controls/verify_openjdk.rb @@ -14,20 +14,19 @@ title 'Path Verification' desc 'Verifies that keytool and other binaries are accessible in the correct paths using update-alternatives' - # Get architecture suffix - arch_suffix = command('uname -m').stdout.strip == 'x86_64' ? 'amd64' : 'arm64' - describe command('update-alternatives --display jar') do its('stdout') { should match %r{/usr/lib/jvm/java} } end + expected_java_home = %r{/usr/lib/jvm/java-#{java_version}[^\s]*/} + describe command('update-alternatives --display java') do - its('stdout') { should match %r{/usr/lib/jvm/java-#{java_version}-openjdk-#{arch_suffix}/bin/java} } + its('stdout') { should match %r{#{expected_java_home}bin/java} } end describe command('update-alternatives --display keytool') do - its('stdout') { should match %r{link best version is /usr/lib/jvm/java-#{java_version}-openjdk-#{arch_suffix}/bin/keytool} } - its('stdout') { should match %r{link keytool is /usr/bin/keytool} } + its('stdout') { should match %r{#{expected_java_home}bin/keytool} } + its('stdout') { should match %r{link (keytool )?(is )?/usr/bin/keytool|keytool - status} } its('stdout') { should match /priority 1/ } end end