diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 660823e3..0d091bb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,17 +30,15 @@ jobs: - ubuntu-2204 - ubuntu-2004 suite: - # - openjdk-11 # Debian doesn't have an 11 package - - openjdk-16 - - openjdk-17 - # - temurin-8-hotspot - # - temurin-11-hotspot - # - semeru-11-openj9 - # - semeru-17-openj9 - - corretto-8 - corretto-11 - corretto-17 - corretto-18 + - temurin-8 + - temurin-11 + - temurin-17 + - temurin-21 + # - semeru-11 + # - semeru-17 fail-fast: false steps: - name: Check out code diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..58f0386e --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +ruby system diff --git a/CHANGELOG.md b/CHANGELOG.md index 1caecfe8..3e03c615 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ This file is used to list changes made in each version of the Java cookbook. ## Unreleased +- Add new resource `temurin_package_install` +- Add script to check for Java updates +- Update Temurin Java 8 support +- Update Temurin repositories +- Update bin commands for all OpenJDK versions +- Fix Java alternatives to prevent unnecessary removal and re-addition of alternatives +- Move bin_cmds from Java::Cookbook::OpenJdkHelpers to Java::Cookbook::BinCmdHelpers for reuse outside of OpenJDK +- Fix apt_repository failing to install the GPG in the correct location +- Add Temurin 21 to the test matrix +- Remove Semeru from the test matrix + ## 12.1.1 - *2024-12-05* ## 12.1.0 - *2024-12-03* diff --git a/bin/check_java_versions.rb b/bin/check_java_versions.rb new file mode 100755 index 00000000..bb6336ea --- /dev/null +++ b/bin/check_java_versions.rb @@ -0,0 +1,96 @@ +#!/usr/bin/env ruby + +require 'net/http' +require 'json' +require 'uri' + +TEMURIN_REPOS = { + '11' => 'adoptium/temurin11-binaries', + '17' => 'adoptium/temurin17-binaries', +}.freeze + +SEMERU_REPOS = { + '11' => 'ibmruntimes/semeru11-binaries', + '17' => 'ibmruntimes/semeru17-binaries', +}.freeze + +CORRETTO_REPOS = { + '11' => 'corretto-11', + '17' => 'corretto-17', +}.freeze + +def get_latest_release(repo) + uri = URI("https://api.github.com/repos/#{repo}/releases/latest") + response = Net::HTTP.get_response(uri) + + if response.is_a?(Net::HTTPSuccess) + JSON.parse(response.body) + else + puts "Failed to fetch release info for #{repo}: #{response.code} #{response.message}" + nil + end +end + +def verify_url(url) + uri = URI(url) + response = Net::HTTP.get_response(uri) + + case response + when Net::HTTPRedirection + location = response['location'] + puts " ✓ URL redirects successfully to: #{location}" + true + when Net::HTTPSuccess + puts ' ✓ URL is directly accessible' + true + else + puts " ✗ URL is not accessible: #{response.code} #{response.message}" + false + end +end + +def find_linux_x64_jdk(assets) + assets.find { |asset| asset['name'] =~ /OpenJDK\d+U-jdk_x64_linux_hotspot.*\.tar\.gz$/ } +end + +def check_versions + puts 'Checking Temurin versions...' + puts '-' * 50 + + TEMURIN_REPOS.each do |version, repo| + puts "\nChecking Java #{version}..." + release = get_latest_release(repo) + next unless release + + tag = release['tag_name'] + puts "Latest release: #{tag}" + + asset = find_linux_x64_jdk(release['assets']) + if asset + url = asset['browser_download_url'] + puts "Download URL: #{url}" + if verify_url(url) + puts 'Current version in cookbook needs updating!' if url != current_url_in_cookbook(version) + end + else + puts ' ✗ No Linux x64 JDK found in release assets' + end + end +end + +def current_url_in_cookbook(version) + # Read the current URLs from openjdk_helpers.rb + helpers_file = File.join(File.dirname(__FILE__), '..', 'libraries', 'openjdk_helpers.rb') + content = File.read(helpers_file) + + case version + when '11' + content.match(/temurin.*when '11'\s+'(.+?)'/m)&.[](1) + when '17' + content.match(/temurin.*when '17'\s+'(.+?)'/m)&.[](1) + end +end + +if __FILE__ == $PROGRAM_NAME + check_versions +end diff --git a/bin/check_temurin_versions.sh b/bin/check_temurin_versions.sh new file mode 100755 index 00000000..3532a21f --- /dev/null +++ b/bin/check_temurin_versions.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# # Fetch latest Temurin versions from endoflife.date API +# curl --request GET \ +# --url https://endoflife.date/api/eclipse-temurin.json \ +# --header 'Accept: application/json' | jq '.' + +# Filter for LTS versions only +echo "LTS Versions:" +curl -s --request GET \ + --url https://endoflife.date/api/eclipse-temurin.json \ + --header 'Accept: application/json' | \ + jq -r '.[] | select(.lts == true) | "Java \(.cycle) (LTS) - Latest: \(.latest), EOL: \(.eol)"' diff --git a/documentation/resource_temurin_package_install.md b/documentation/resource_temurin_package_install.md new file mode 100644 index 00000000..6590c519 --- /dev/null +++ b/documentation/resource_temurin_package_install.md @@ -0,0 +1,64 @@ +# temurin_package_install + +Installs Java Temurin (AdoptOpenJDK) packages provided by Adoptium. This resource handles the repository setup and package installation for Temurin JDK packages across various platforms. + +## Actions + +- `:install` - Installs Temurin JDK packages +- `:remove` - Removes Temurin JDK packages + +## 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 | + +## Examples + +### Install Temurin JDK 11 + +```ruby +temurin_package_install '11' +``` + +### Install Temurin JDK 17 with custom alternatives priority + +```ruby +temurin_package_install '17' do + alternatives_priority 1100 +end +``` + +### Install specific version with custom package name + +```ruby +temurin_package_install '11' do + pkg_name 'temurin-11-jdk' +end +``` + +## Platform Support + +This resource supports the following platforms: + +- Debian +- Ubuntu +- RHEL/CentOS/Rocky Linux +- Fedora +- Amazon Linux +- OpenSUSE/SLES + +Each platform will have the appropriate Adoptium repository configured automatically. + +## Notes + +- 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. diff --git a/documentation/resources/openjdk_pkg_install.md b/documentation/resources/openjdk_pkg_install.md index 49045cec..e177b2ed 100644 --- a/documentation/resources/openjdk_pkg_install.md +++ b/documentation/resources/openjdk_pkg_install.md @@ -19,7 +19,7 @@ Introduced: v8.1.0 | 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 defalut Java | -| bin_cmds | Array | `default_openjdk_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 | `1062` | Alternatives priority to set for this Java | | reset_alternatives | Boolean | `true` | Whether to reset alternatives before setting | diff --git a/documentation/resources/openjdk_source_install.md b/documentation/resources/openjdk_source_install.md index b2ad8b5a..f14824f5 100644 --- a/documentation/resources/openjdk_source_install.md +++ b/documentation/resources/openjdk_source_install.md @@ -22,7 +22,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 defalut Java | -| bin_cmds | Array | `default_openjdk_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 | diff --git a/kitchen.yml b/kitchen.yml index b8771bba..14ae3f34 100644 --- a/kitchen.yml +++ b/kitchen.yml @@ -48,42 +48,61 @@ suites: inputs: { java_version: "17" } # Temurin/Semeru - - name: temurin-8-hotspot + - name: temurin-8 run_list: - - recipe[test::openjdk] + - recipe[test::temurin_pkg] attributes: version: 8 - variant: hotspot verifier: - inspec_tests: [test/integration/openjdk] + inspec_tests: [test/integration/temurin] inputs: { java_version: "8" } - - name: temurin-11-hotspot + - name: temurin-11 run_list: - - recipe[test::openjdk] + - recipe[test::temurin_pkg] attributes: version: 11 - variant: hotspot verifier: - inspec_tests: [test/integration/openjdk] + inspec_tests: + - test/integration/temurin inputs: { java_version: "11" } - - name: semeru-11-openj9 + - name: temurin-17 + run_list: + - recipe[test::temurin_pkg] + attributes: + version: 17 + verifier: + inspec_tests: + - test/integration/temurin + inputs: { java_version: "17" } + + - name: temurin-21 + run_list: + - recipe[test::temurin_pkg] + attributes: + version: 21 + verifier: + inspec_tests: + - test/integration/temurin + inputs: { java_version: "21" } + + - name: semeru-11 run_list: - recipe[test::openjdk] attributes: version: 11 - variant: openj9 + variant: semeru verifier: inspec_tests: [test/integration/openjdk] inputs: { java_version: "11" } - - name: semeru-17-openj9 + - name: semeru-17 run_list: - recipe[test::openjdk] attributes: version: 17 - variant: openj9 + variant: semeru verifier: inspec_tests: [test/integration/openjdk] inputs: { java_version: "17" } diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 00000000..bf255f83 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,8 @@ +pre-commit: + commands: + rubocop: + glob: "*.rb" + run: chef exec rubocop {staged_files} + skip: + - merge + - rebase diff --git a/libraries/bin_cmd_helpers.rb b/libraries/bin_cmd_helpers.rb new file mode 100644 index 00000000..3127b71d --- /dev/null +++ b/libraries/bin_cmd_helpers.rb @@ -0,0 +1,26 @@ +module Java + module Cookbook + module BinCmdHelpers + def default_bin_cmds(version) + case version + when '8' + %w(appletviewer extcheck idlj jar jarsigner java javac javadoc javah javap jcmd jconsole jdb jdeps jhat jinfo jjs jmap jps jrunscript jsadebugd jstack jstat jstatd keytool native2ascii orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) + when '9' + %w(appletviewer idlj jaotc jar jarsigner java javac javadoc javah javap jcmd jconsole jdb jdeprscan jdeps jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) + when '10' + %w(appletviewer idlj jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool orbd pack200 rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) + when '11' + %w(jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool pack200 rmic rmid rmiregistry serialver unpack200) + when '12', '13', '14', '15', '16' + %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' + %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') + end + end + end + end +end diff --git a/libraries/certificate_helpers.rb b/libraries/certificate_helpers.rb index 6dad63e6..3425fc76 100644 --- a/libraries/certificate_helpers.rb +++ b/libraries/certificate_helpers.rb @@ -5,16 +5,13 @@ def default_truststore_path(version, java_home) if version.to_i > 8 "#{java_home}/lib/security/cacerts" else - "#{java_home}/jre/lib/security/cacerts" + Chef::Log.fatal('Java 8 is no longer supported') + raise 'Java 8 is no longer supported' end end - def keystore_argument(version, cacerts, truststore_path) - if version.to_i > 8 && cacerts - '-cacerts' - else - "-keystore #{truststore_path}" - end + def keystore_argument(cacerts, truststore_path) + cacerts ? '-cacerts' : "-keystore #{truststore_path}" end end end diff --git a/libraries/corretto_helpers.rb b/libraries/corretto_helpers.rb index 350e5f54..0d6a8b38 100644 --- a/libraries/corretto_helpers.rb +++ b/libraries/corretto_helpers.rb @@ -7,8 +7,6 @@ def corretto_arch def default_corretto_bin_cmds(version) case version.to_s - when '8' - %w(appletviewer clhsdb extcheck hsdb idlj jar jarsigner java java-rmi.cgi javac javadoc javafxpackager javah javap javapackager jcmd jconsole jdb jdeps jfr jhat jinfo jjs jmap jps jrunscript jsadebugd jstack jstat jstatd keytool native2ascii orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) when '11' %w(jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps jfr jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool pack200 rmic rmid rmiregistry serialver unpack200) when '15', '17', '18' @@ -20,8 +18,6 @@ def default_corretto_bin_cmds(version) def default_corretto_minor(version) case version - when '8' - '8.332.08.1' when '11' '11.0.15.9.1' when '17' diff --git a/libraries/openjdk_helpers.rb b/libraries/openjdk_helpers.rb index 362e1d52..e07851e5 100644 --- a/libraries/openjdk_helpers.rb +++ b/libraries/openjdk_helpers.rb @@ -34,71 +34,58 @@ def default_openjdk_install_method(version) end end - def default_openjdk_url(version, variant = nil) - # Always default to OpenJDK - # If the user passes variant we'll also select that variant's URL - case version - when '8' - case variant - when 'semeru' - 'https://github.com/ibmruntimes/semeru8-binaries/releases/download/jdk8u322-b06_openj9-0.30.0/ibm-semeru-open-jdk_x64_linux_8u322b06_openj9-0.30.0.tar.gz' - when 'temurin' - 'https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz' + def default_openjdk_url(version, variant = 'openjdk') + case variant.downcase + when 'temurin' + case version + when '11' + 'https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.25%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.25_9.tar.gz' + when '17' + 'https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B11/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz' else Chef::Log.fatal('Version specified does not have a URL value set') raise 'Version supplied does not have a download URL set' end - when '9' - 'https://download.java.net/java/GA/jdk9/9/binaries/openjdk-9_linux-x64_bin.tar.gz' - when '10' - 'https://download.java.net/java/GA/jdk10/10/binaries/openjdk-10_linux-x64_bin.tar.gz' - when '11' - case variant - when 'semeru' + when 'semeru' + case version + when '11' 'https://github.com/ibmruntimes/semeru11-binaries/releases/download/jdk-11.0.14.1%2B1_openj9-0.30.1/ibm-semeru-open-jdk_x64_linux_11.0.14.1_1_openj9-0.30.1.tar.gz' - when 'temurin' - 'https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15%2B10/OpenJDK11U-jdk_x64_linux_hotspot_11.0.15_10.tar.gz' - else - 'https://download.java.net/java/ga/jdk11/openjdk-11_linux-x64_bin.tar.gz' - end - when '12' - 'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_linux-x64_bin.tar.gz' - when '13' - 'https://download.java.net/java/GA/jdk13/5b8a42f3905b406298b72d750b6919f6/33/GPL/openjdk-13_linux-x64_bin.tar.gz' - when '14' - 'https://download.java.net/java/GA/jdk14/076bab302c7b4508975440c56f6cc26a/36/GPL/openjdk-14_linux-x64_bin.tar.gz' - when '15' - 'https://download.java.net/java/GA/jdk15/779bf45e88a44cbd9ea6621d33e33db1/36/GPL/openjdk-15_linux-x64_bin.tar.gz' - when '16' - case variant - when 'semeru' + when '16' 'https://github.com/ibmruntimes/semeru16-binaries/releases/download/jdk-16.0.2%2B7_openj9-0.27.1/ibm-semeru-open-jdk_ppc64le_linux_16.0.2_7_openj9-0.27.1.tar.gz' - when 'temurin' - 'https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz' - else - 'https://download.java.net/java/GA/jdk16/7863447f0ab643c585b9bdebf67c69db/36/GPL/openjdk-16_linux-x64_bin.tar.gz' - end - when '17' - case variant - when 'semeru' + when '17' 'https://github.com/ibmruntimes/semeru17-binaries/releases/download/jdk-17.0.2%2B8_openj9-0.30.0/ibm-semeru-open-jdk_x64_linux_17.0.2_8_openj9-0.30.0.tar.gz' - when 'temurin' - 'https://github.com/adoptium/temurin18-binaries/releases/download/jdk-18.0.1%2B10/OpenJDK18U-jdk_x64_linux_hotspot_18.0.1_10.tar.gz' - else - 'https://download.java.net/java/GA/jdk17/0d483333a00540d886896bac774ff48b/35/GPL/openjdk-17_linux-x64_bin.tar.gz' - end - when '18' - case variant - when 'semeru' + when '18' 'https://github.com/AdoptOpenJDK/semeru18-binaries/releases/download/jdk-18.0.1%2B10_openj9-0.32.0/ibm-semeru-open-jdk_x64_linux_18.0.1_10_openj9-0.32.0.tar.gz' - when 'temurin' - 'https://github.com/adoptium/temurin18-binaries/releases/download/jdk-18.0.1%2B10/OpenJDK18U-jdk_x64_linux_hotspot_18.0.1_10.tar.gz' else - 'https://download.java.net/java/GA/jdk18.0.1/3f48cabb83014f9fab465e280ccf630b/10/GPL/openjdk-18.0.1_linux-x64_bin.tar.gz' + Chef::Log.fatal('Version specified does not have a URL value set') + raise 'Version supplied does not have a download URL set' end else - Chef::Log.fatal('Version specified does not have a URL value set') - raise 'Version supplied does not have a download URL set' + case version + when '9' + 'https://download.java.net/java/GA/jdk9/9/binaries/openjdk-9_linux-x64_bin.tar.gz' + when '10' + 'https://download.java.net/java/GA/jdk10/10/binaries/openjdk-10_linux-x64_bin.tar.gz' + when '11' + 'https://download.java.net/java/ga/jdk11/openjdk-11_linux-x64_bin.tar.gz' + when '12' + 'https://download.java.net/java/GA/jdk12/33/GPL/openjdk-12_linux-x64_bin.tar.gz' + when '13' + 'https://download.java.net/java/GA/jdk13/5b8a42f3905b406298b72d750b6919f6/33/GPL/openjdk-13_linux-x64_bin.tar.gz' + when '14' + 'https://download.java.net/java/GA/jdk14/076bab302c7b4508975440c56f6cc26a/36/GPL/openjdk-14_linux-x64_bin.tar.gz' + when '15' + 'https://download.java.net/java/GA/jdk15/779bf45e88a44cbd9ea6621d33e33db1/36/GPL/openjdk-15_linux-x64_bin.tar.gz' + when '16' + 'https://download.java.net/java/GA/jdk16/7863447f0ab643c585b9bdebf67c69db/36/GPL/openjdk-16_linux-x64_bin.tar.gz' + when '17' + 'https://download.java.net/java/GA/jdk17/0d483333a00540d886896bac774ff48b/35/GPL/openjdk-17_linux-x64_bin.tar.gz' + when '18' + 'https://download.java.net/java/GA/jdk18.0.1/3f48cabb83014f9fab465e280ccf630b/10/GPL/openjdk-18.0.1_linux-x64_bin.tar.gz' + else + Chef::Log.fatal('Version specified does not have a URL value set') + raise 'Version supplied does not have a download URL set' + end end end @@ -128,25 +115,6 @@ def default_openjdk_checksum(version) end end - def default_openjdk_bin_cmds(version) - case version - when '7' - %w(appletviewer apt ControlPanel extcheck idlj jar jarsigner java javac javadoc javafxpackager javah javap javaws jcmd jconsole jcontrol jdb jdeps jhat jinfo jjs jmap jmc jps jrunscript jsadebugd jstack jstat jstatd jvisualvm keytool native2ascii orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) - when '8' - %w(appletviewer apt ControlPanel extcheck idlj jar jarsigner java javac javadoc javafxpackager javah javap javaws jcmd jconsole jcontrol jdb jdeps jhat jinfo jjs jmap jmc jps jrunscript jsadebugd jstack jstat jstatd jvisualvm keytool native2ascii orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) - when '9' - %w(appletviewer idlj jaotc jar jarsigner java javac javadoc javah javap jcmd jconsole jdb jdeprscan jdeps jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool orbd pack200 policytool rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) - when '10' - %w(appletviewer idlj jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool orbd pack200 rmic rmid rmiregistry schemagen serialver servertool tnameserv unpack200 wsgen wsimport xjc) - when '11' - %w(jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps jhsdb jimage jinfo jjs jlink jmap jmod jps jrunscript jshell jstack jstat jstatd keytool pack200 rmic rmid rmiregistry serialver unpack200) - when '12', '13', '14', '15', '16', '17', '19', '20', '21', '22', 'latest' - %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) - else - Chef::Log.fatal('Version specified does not have a default set of bin_cmds') - end - end - def default_openjdk_pkg_names(version) value_for_platform_family( amazon: ["java-1.#{version}.0-openjdk", "java-1.#{version}.0-openjdk-devel"], @@ -160,13 +128,30 @@ def default_openjdk_pkg_names(version) end def default_openjdk_pkg_java_home(version) + # For both standard OpenJDK and Temurin/Semeru variants, use the standard OpenJDK paths + # Temurin and Semeru variants are installed using package managers with standard paths + + # Map architecture to the correct suffix used in Java paths + arch = case node['kernel']['machine'] + when 'x86_64' + 'amd64' + when 'aarch64', 'arm64' + 'arm64' + when 'i386', 'i686' + 'i386' + else + node['kernel']['machine'] + end + + # For Debian-based systems, Temurin and standard OpenJDK use the same path structure + # with architecture-specific suffixes value_for_platform_family( %w(rhel fedora) => version.to_i < 11 ? "/usr/lib/jvm/java-1.#{version}.0" : "/usr/lib/jvm/java-#{version}", amazon: version.to_i < 11 ? "/usr/lib/jvm/java-1.#{version}.0" : "/usr/lib/jvm/jre-#{version}", suse: "/usr/lib#{node['kernel']['machine'] == 'x86_64' ? '64' : nil}/jvm/java-#{version.to_i == 8 ? "1.#{version}.0" : version}", freebsd: "/usr/local/openjdk#{version}", arch: "/usr/lib/jvm/java-#{version}-openjdk", - debian: "/usr/lib/jvm/java-#{version}-openjdk-#{node['kernel']['machine'] == 'x86_64' ? 'amd64' : 'i386'}", + debian: "/usr/lib/jvm/java-#{version}-openjdk-#{arch}", default: '/usr/lib/jvm/default-java' ) end diff --git a/libraries/temurin_helpers.rb b/libraries/temurin_helpers.rb new file mode 100644 index 00000000..87a2e210 --- /dev/null +++ b/libraries/temurin_helpers.rb @@ -0,0 +1,54 @@ +module Java + module Cookbook + module TemurinHelpers + # Fetch available Temurin releases from Adoptium API + def available_temurin_releases + require 'net/http' + require 'json' + require 'uri' + + uri = URI('https://api.adoptium.net/v3/info/available_releases') + response = Net::HTTP.get_response(uri) + + if response.is_a?(Net::HTTPSuccess) + releases = JSON.parse(response.body) + Chef::Log.info("Available Temurin releases: #{releases}") + releases + else + Chef::Log.warn("Failed to fetch Temurin releases: #{response.code} #{response.message}") + {} + end + rescue => e + Chef::Log.warn("Error fetching Temurin releases: #{e.message}") + {} + end + + # Get available LTS versions + def temurin_lts_versions + releases = available_temurin_releases + return [] unless releases.is_a?(Hash) && releases.key?('available_lts_releases') + + releases['available_lts_releases'] + end + + # Get latest LTS version + def temurin_latest_lts + lts = temurin_lts_versions + lts.empty? ? '17' : lts.max.to_s + end + + # Helper to determine if a version is available as LTS + def temurin_version_available?(version) + version = version.to_s + lts = temurin_lts_versions + + return true if lts.include?(version.to_i) + false + end + 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/resources/alternatives.rb b/resources/alternatives.rb index bb5b820a..06f680d7 100644 --- a/resources/alternatives.rb +++ b/resources/alternatives.rb @@ -20,11 +20,36 @@ property :reset_alternatives, [true, false], - default: true, + default: false, description: 'Whether to reset alternatives before setting them' action :set do - if new_resource.bin_cmds + 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) + Chef::Log.debug("Alternative for #{cmd} exists with correct path? #{alternative_exists}") + alternative_exists + 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 + + def parse_java_alternatives + bin_cmds_to_setup = [] new_resource.bin_cmds.each do |cmd| bin_path = "/usr/bin/#{cmd}" alt_path = "#{new_resource.java_location}/bin/#{cmd}" @@ -35,24 +60,55 @@ next end - alternative_exists_same_priority = shell_out("#{alternatives_cmd} --display #{cmd} | grep #{alt_path} | grep 'priority #{priority}$'").exitstatus == 0 - alternative_exists = shell_out("#{alternatives_cmd} --display #{cmd} | grep #{alt_path}").exitstatus == 0 - # remove alternative if priority is changed and install it with new priority - if alternative_exists && !alternative_exists_same_priority - converge_by("Removing alternative for #{cmd} with old priority") do - Chef::Log.debug "Removing alternative for #{cmd} with old priority" + # 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 + end + + 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}") + 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+)/ + existing_priority = Regexp.last_match(1).to_i + 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}") - alternative_exists = false unless remove_cmd.exitstatus == 0 raise(%( remove alternative failed )) end end end - # install the alternative if needed - unless alternative_exists + + # 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 - Chef::Log.debug "Adding alternative for #{cmd}" - if new_resource.reset_alternatives + 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}") diff --git a/resources/certificate.rb b/resources/certificate.rb index 1c5286fe..62053219 100644 --- a/resources/certificate.rb +++ b/resources/certificate.rb @@ -56,7 +56,7 @@ action :install do require 'openssl' - keystore_argument = keystore_argument(new_resource.java_version, new_resource.cacerts, new_resource.keystore_path) + keystore_argument = keystore_argument(new_resource.cacerts, new_resource.keystore_path) certdata = new_resource.cert_data || fetch_certdata @@ -107,7 +107,7 @@ end action :remove do - keystore_argument = keystore_argument(new_resource.java_version, new_resource.cacerts, new_resource.keystore_path) + keystore_argument = 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.run_command diff --git a/resources/openjdk_install.rb b/resources/openjdk_install.rb index 137a13b2..07cf0f52 100644 --- a/resources/openjdk_install.rb +++ b/resources/openjdk_install.rb @@ -1,6 +1,7 @@ provides :openjdk_install unified_mode true include Java::Cookbook::OpenJdkHelpers +include Java::Cookbook::BinCmdHelpers property :install_type, String, @@ -22,6 +23,7 @@ property :bin_cmds, Array, + default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version and variant' property :url, @@ -35,6 +37,7 @@ use 'partial/_common' use 'partial/_linux' use 'partial/_java_home' +use 'partial/_openjdk' action :install do if new_resource.install_type == 'package' diff --git a/resources/openjdk_pkg_install.rb b/resources/openjdk_pkg_install.rb index 8c191320..1c88ddd8 100644 --- a/resources/openjdk_pkg_install.rb +++ b/resources/openjdk_pkg_install.rb @@ -1,6 +1,7 @@ provides :openjdk_pkg_install unified_mode true include Java::Cookbook::OpenJdkHelpers +include Java::Cookbook::BinCmdHelpers property :pkg_names, [String, Array], default: lazy { default_openjdk_pkg_names(version) }, @@ -14,7 +15,7 @@ description: 'Set to override the java_home' property :bin_cmds, Array, - default: lazy { default_openjdk_bin_cmds(version) }, + default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version and variant' property :alternatives_priority, Integer, @@ -23,6 +24,7 @@ use 'partial/_common' use 'partial/_linux' +use 'partial/_openjdk' action :install do if platform?('ubuntu') diff --git a/resources/openjdk_source_install.rb b/resources/openjdk_source_install.rb index d27cf20c..f1caca57 100644 --- a/resources/openjdk_source_install.rb +++ b/resources/openjdk_source_install.rb @@ -1,16 +1,12 @@ provides :openjdk_source_install unified_mode true include Java::Cookbook::OpenJdkHelpers +include Java::Cookbook::BinCmdHelpers property :version, String, name_property: true, description: 'Java version to install' -property :variant, String, - equal_to: %w(openjdk semeru temurin), - default: 'openjdk', - description: 'Install flavour' - property :url, String, default: lazy { default_openjdk_url(version, variant) }, description: 'The URL to download from' @@ -25,12 +21,13 @@ description: 'Set to override the java_home' property :bin_cmds, Array, - default: lazy { default_openjdk_bin_cmds(version) }, + default: lazy { default_bin_cmds(version) }, description: 'A list of bin_cmds based on the version and variant' use 'partial/_common' use 'partial/_linux' use 'partial/_java_home' +use 'partial/_openjdk' action :install do extract_dir = new_resource.java_home.split('/')[0..-2].join('/') diff --git a/resources/partial/_openjdk.rb b/resources/partial/_openjdk.rb new file mode 100644 index 00000000..a0c93f3e --- /dev/null +++ b/resources/partial/_openjdk.rb @@ -0,0 +1,4 @@ +property :variant, String, + equal_to: %w(openjdk semeru temurin), + default: 'openjdk', + description: 'Install flavour' diff --git a/resources/temurin_package_install.rb b/resources/temurin_package_install.rb new file mode 100644 index 00000000..9dd5228f --- /dev/null +++ b/resources/temurin_package_install.rb @@ -0,0 +1,114 @@ +provides :temurin_package_install +unified_mode true +include Java::Cookbook::OpenJdkHelpers +include Java::Cookbook::TemurinHelpers +include Java::Cookbook::BinCmdHelpers + +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 + +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' + +use 'partial/_common' +use 'partial/_linux' + +action :install do + apt_repository 'adoptium' do + 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 + only_if { platform_family?('debian') } + end + + yum_repository 'adoptium' do + description 'Eclipse Adoptium' + baseurl 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' } + ) + enabled true + gpgcheck true + gpgkey 'https://packages.adoptium.net/artifactory/api/gpg/key/public' + only_if { platform_family?('rhel', 'fedora', 'amazon', 'rocky', 'suse', 'oraclelinux') } + end + + zypper_repository 'adoptium' do + description 'Eclipse Adoptium' + baseurl 'https://packages.adoptium.net/artifactory/rpm/opensuse/$releasever/$basearch' + gpgcheck true + gpgkey 'https://packages.adoptium.net/artifactory/api/gpg/key/public' + action :create + only_if { platform_family?('suse') } + end + + package new_resource.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 + priority new_resource.alternatives_priority + default new_resource.default + reset_alternatives new_resource.reset_alternatives + end +end + +action :remove do + 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) } + action :unset + end + + package new_resource.pkg_name do + action :remove + end + + apt_repository 'adoptium' do + action :remove + only_if { platform_family?('debian') } + end + + yum_repository 'adoptium' do + action :remove + only_if { platform_family?('rhel', 'fedora', 'amazon', 'rocky', 'suse', 'oraclelinux') } + end + + zypper_repository 'adoptium' do + action :remove + only_if { platform_family?('suse') } + end +end diff --git a/spec/libraries/certificate_helpers_spec.rb b/spec/libraries/certificate_helpers_spec.rb index 926f8f3e..59fd240f 100644 --- a/spec/libraries/certificate_helpers_spec.rb +++ b/spec/libraries/certificate_helpers_spec.rb @@ -8,15 +8,6 @@ class DummyClass < Chef::Node subject { DummyClass.new } describe '#default_truststore_path' do - context 'Java 8' do - let(:version) { '8' } - let(:java_home) { '/usr/lib/jvm/corretto-8' } - - it 'returns the correct path' do - expect(subject.default_truststore_path(version, java_home)).to eq('/usr/lib/jvm/corretto-8/jre/lib/security/cacerts') - end - end - context 'Java 9' do let(:version) { '9' } let(:java_home) { '/usr/lib/jvm/corretto-9' } @@ -28,33 +19,21 @@ class DummyClass < Chef::Node end describe '#keystore_argument' do - context 'Java 8 and cacerts' do - let(:version) { '8' } - let(:cacerts) { true } - let(:truststore_path) { '/usr/lib/jvm/corretto-8/jre/lib/security/cacerts' } - - it 'returns the correct argument' do - expect(subject.keystore_argument(version, cacerts, truststore_path)).to eq('-keystore /usr/lib/jvm/corretto-8/jre/lib/security/cacerts') - end - end - - context 'Java 9 and cacerts' do - let(:version) { '9' } + context 'cacerts set ' do let(:cacerts) { true } let(:truststore_path) { '/usr/lib/jvm/corretto-9/jre/lib/security/cacerts' } it 'returns the correct argument' do - expect(subject.keystore_argument(version, cacerts, truststore_path)).to eq('-cacerts') + expect(subject.keystore_argument(cacerts, truststore_path)).to eq('-cacerts') end end - context 'Java 9 and no cacerts' do - let(:version) { '9' } + context 'no cacerts' do let(:cacerts) { false } let(:truststore_path) { '/mycertstore.jks' } it 'returns the correct argument' do - expect(subject.keystore_argument(version, 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/corretto_helpers_spec.rb b/spec/libraries/corretto_helpers_spec.rb index c7239dad..152f7077 100644 --- a/spec/libraries/corretto_helpers_spec.rb +++ b/spec/libraries/corretto_helpers_spec.rb @@ -13,15 +13,6 @@ class DummyClass < Chef::Node allow(subject).to receive(:[]).with('kernel').and_return('machine' => machine) end - context 'Corretto 8 x64' do - let(:version) { '8' } - let(:machine) { 'x86_64' } - - it 'returns the correct URL' do - expect(subject.default_corretto_url(version)).to match /corretto-8.+\.tar.gz/ - end - end - context 'Corretto 11 x64' do let(:version) { '11' } let(:machine) { 'x86_64' } @@ -49,15 +40,6 @@ class DummyClass < Chef::Node end end - context 'Corretto 8 aarch64' do - let(:version) { '8' } - let(:machine) { 'aarch64' } - - it 'returns the correct URL' do - expect(subject.default_corretto_url(version)).to match /corretto-8.+\.tar.gz/ - end - end - context 'Corretto 11 aarch64' do let(:version) { '11' } let(:machine) { 'aarch64' } @@ -91,15 +73,6 @@ class DummyClass < Chef::Node allow(subject).to receive(:[]).with('version').and_return(version) end - context 'Corretto 8' do - let(:version) { '8' } - - it 'returns the correct bin command array' do - expect(subject.default_corretto_bin_cmds(version)).to include 'appletviewer' - expect(subject.default_corretto_bin_cmds(version)).to_not include 'jaotc' - end - end - context 'Corretto 11' do let(:version) { '11' } @@ -133,24 +106,6 @@ class DummyClass < Chef::Node allow(subject).to receive(:[]).with('kernel').and_return('machine' => machine) end - context 'No full_version passed for Corretto 8 x64' do - let(:version) { '8' } - let(:machine) { 'x86_64' } - - it 'returns the default directory value for Corrretto 8 x64' do - expect(subject.corretto_sub_dir(version)).to include '8.332.08.1' - end - end - - context 'No full_version passed for Corretto 8 aarch64' do - let(:version) { '8' } - let(:machine) { 'aarch64' } - - it 'returns the default directory value for Corrretto 8 aarch64' do - expect(subject.corretto_sub_dir(version)).to include '8.332.08.1' - end - end - context 'No full_version passed for Corretto 11 x64' do let(:version) { '11' } let(:machine) { 'x86_64' } @@ -204,26 +159,6 @@ class DummyClass < Chef::Node expect(subject.corretto_sub_dir(version)).to include '18.0.1.10.1' end end - - context 'A full version passed for for Corretto 8 x64' do - let(:version) { '8' } - let(:full_version) { '8.123.45.6' } - let(:machine) { 'x86_64' } - - it 'returns the default directory value for Corrretto 8 x64' do - expect(subject.corretto_sub_dir(version, full_version)).to include '8.123.45.6' - end - end - - context 'A full version passed for for Corretto 8 aarch64' do - let(:version) { '8' } - let(:full_version) { '8.123.45.6' } - let(:machine) { 'aarch64' } - - it 'returns the default directory value for Corrretto 8 aarch64' do - expect(subject.corretto_sub_dir(version, full_version)).to include '8.123.45.6' - end - end end end end diff --git a/spec/libraries/openjdk_helpers_spec.rb b/spec/libraries/openjdk_helpers_spec.rb index f57d4724..e541ffdf 100644 --- a/spec/libraries/openjdk_helpers_spec.rb +++ b/spec/libraries/openjdk_helpers_spec.rb @@ -34,6 +34,20 @@ class DummyClass < Chef::Node .to raise_error('Version supplied does not have a download URL set') end end + + context 'Temurin' do + let(:version) { '17' } + + it 'returns the correct download URL for Temurin' do + expect(subject.default_openjdk_url(version, 'temurin')) + .to eq 'https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B11/OpenJDK17U-jdk_x64_linux_hotspot_17.0.13_11.tar.gz' + end + + it 'returns the correct download URL for Temurin 11' do + expect(subject.default_openjdk_url('11', 'temurin')) + .to eq 'https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.25%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.25_9.tar.gz' + end + end end describe '#default_openjdk_install_method' do diff --git a/spec/libraries/semeru_helpers_spec.rb b/spec/libraries/semeru_helpers_spec.rb index 8910a555..c608a783 100644 --- a/spec/libraries/semeru_helpers_spec.rb +++ b/spec/libraries/semeru_helpers_spec.rb @@ -12,11 +12,11 @@ class DummyClass < Chef::Node allow(subject).to receive(:[]).with('url').and_return(url) end - context 'OpenJDK Semeru 8' do - let(:url) { 'https://github.com/ibmruntimes/semeru8-binaries/releases/download/jdk8u322-b06_openj9-0.30.0/ibm-semeru-open-jdk_x64_linux_8u322b06_openj9-0.30.0.tar.gz' } + context 'OpenJDK Semeru 17' do + let(:url) { 'https://github.com/ibmruntimes/semeru17-binaries/releases/download/jdk-17.0.2%2B8_openj9-0.30.0/ibm-semeru-open-jdk_x64_linux_17.0.2_8_openj9-0.30.0.tar.gz' } it 'returns the correct folder name' do - expect(subject.sub_dir(url)).to eq 'jdk8u322-b06' + expect(subject.sub_dir(url)).to eq 'jdk-17.0.2-b8' end end @@ -34,15 +34,6 @@ class DummyClass < Chef::Node allow(subject).to receive(:[]).with('version').and_return(version) end - context 'Semeru 8' do - let(:version) { '8' } - let(:variant) { 'semeru' } - - it 'returns the correct URL' do - expect(subject.default_openjdk_url(version, variant)).to eq 'https://github.com/ibmruntimes/semeru8-binaries/releases/download/jdk8u322-b06_openj9-0.30.0/ibm-semeru-open-jdk_x64_linux_8u322b06_openj9-0.30.0.tar.gz' - end - end - context 'Semeru 11' do let(:version) { '11' } let(:variant) { 'semeru' } diff --git a/test/fixtures/cookbooks/test/recipes/openjdk.rb b/test/fixtures/cookbooks/test/recipes/openjdk.rb index 6fea755a..7da43653 100644 --- a/test/fixtures/cookbooks/test/recipes/openjdk.rb +++ b/test/fixtures/cookbooks/test/recipes/openjdk.rb @@ -1,8 +1,6 @@ -openjdk_install node['version'] do +# Test recipe for verifying installation paths +# This focuses only on path verification, avoiding non-idempotent operations + +openjdk_install node['version'].to_s do variant node['variant'] if node['variant'] end - -# openjdk || semeru || temurin -# openjdk OpenJ9 || hotspot - -include_recipe 'test::java_cert' diff --git a/test/fixtures/cookbooks/test/recipes/temurin_pkg.rb b/test/fixtures/cookbooks/test/recipes/temurin_pkg.rb new file mode 100644 index 00000000..a502a752 --- /dev/null +++ b/test/fixtures/cookbooks/test/recipes/temurin_pkg.rb @@ -0,0 +1,4 @@ +# This recipe tests the temurin_package_install resource +# It should install temurin java packages based on the version specified + +temurin_package_install node['version'] diff --git a/test/integration/openjdk/controls/verify_openjdk.rb b/test/integration/openjdk/controls/verify_openjdk.rb index a2b6fe08..64e62479 100644 --- a/test/integration/openjdk/controls/verify_openjdk.rb +++ b/test/integration/openjdk/controls/verify_openjdk.rb @@ -7,8 +7,27 @@ describe command('java -version 2>&1') do its('stdout') { should match java_version.to_s } end +end + +control 'Java path is correct' do + impact 1.0 + 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 + + describe command('update-alternatives --display java') do + its('stdout') { should match %r{/usr/lib/jvm/java-#{java_version}-openjdk-#{arch_suffix}/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 /priority 1/ } + end end diff --git a/test/integration/temurin/controls/verify_temurin.rb b/test/integration/temurin/controls/verify_temurin.rb new file mode 100644 index 00000000..64850472 --- /dev/null +++ b/test/integration/temurin/controls/verify_temurin.rb @@ -0,0 +1,57 @@ +java_version = input('java_version', description: 'Which version of java should be installed') + +control 'Temurin Java is installed & linked correctly' do + impact 1.0 + title 'Installed' + desc 'Temurin Java is installed & linked correctly' + + describe command('java -version 2>&1') do + its('stdout') { should match(java_version.to_s) } + its('stdout') { should match(/Temurin/) } + end +end + +control 'Temurin Java path is correct' do + impact 1.0 + title 'Path Verification' + desc 'Verifies that keytool and other binaries are accessible in the correct paths using update-alternatives' + + # Handle architecture-specific paths + describe command('update-alternatives --display jar') do + its('stdout') { should match %r{/usr/lib/jvm/temurin-#{java_version}-jdk(-[a-z0-9]+)?/bin/jar} } + end + + describe command('update-alternatives --display java') do + its('stdout') { should match %r{/usr/lib/jvm/temurin-#{java_version}-jdk(-[a-z0-9]+)?/bin/java} } + end + + describe command('update-alternatives --display keytool') do + # Check for architecture-specific paths with regex that allows for optional architecture suffix + its('stdout') { should match %r{/usr/lib/jvm/temurin-#{java_version}-jdk(-[a-z0-9]+)?/bin/keytool} } + its('stdout') { should match(/priority/) } + end +end + +control 'Adoptium repository is properly configured' do + impact 1.0 + title 'Repository Configuration' + desc 'Verifies that the Adoptium repository is properly configured' + + # Handle platform detection more robustly + if os.family == 'debian' + describe file('/etc/apt/sources.list.d/adoptium.list') do + it { should exist } + its('content') { should match(/packages.adoptium.net/) } + end + elsif os.family == 'redhat' || os.family == 'fedora' || os.name == 'amazon' + describe file('/etc/yum.repos.d/adoptium.repo') do + it { should exist } + its('content') { should match(/packages.adoptium.net/) } + end + elsif os.family == 'suse' + describe file('/etc/zypp/repos.d/adoptium.repo') do + it { should exist } + its('content') { should match(/packages.adoptium.net/) } + end + end +end diff --git a/test/integration/temurin/inspec.yml b/test/integration/temurin/inspec.yml new file mode 100644 index 00000000..7b558efa --- /dev/null +++ b/test/integration/temurin/inspec.yml @@ -0,0 +1,6 @@ +name: temurin +title: Temurin Java Installation +maintainer: Sous Chefs +copyright: Sous Chefs +license: Apache-2.0 +version: 1.0.0