open-nomad/drivers/java/utils.go
Seth Hoenig 8f493cfa89 client/fingerprint/java: improve java version string regex matching
This PR improves the regular expression used for matching the java
version string, which varies a lot depending on the java vendor and
version.

These are the example strings we now test for:

java version "1.7.0_80"
openjdk version "11.0.1" 2018-10-16
openjdk version "11.0.1" 2018-10-16
java version "1.6.0_36"
openjdk version "1.8.0_192"
openjdk 11.0.11 2021-04-20 LTS

The last one is a new test added on behalf of #6081, which is
still broken on today's CentOS 7 default JDK package.

openjdk 11.0.11 2021-04-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.11+9-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.11+9-LTS, mixed mode, sharing)

==> Evaluation "21c6caf7" finished with status "complete" but failed to place all allocations:
    Task Group "example" (failed to place 1 allocation):
      * Constraint "${driver.java.version} >= 11.0.0": 1 nodes excluded by filter
    Evaluation "2b737d48" waiting for additional capacity to place remainder

Fixes #6081
2021-06-15 14:15:01 -05:00

78 lines
1.8 KiB
Go

package java
import (
"bytes"
"fmt"
"os/exec"
"regexp"
rt "runtime"
"strings"
)
var javaVersionCommand = []string{"java", "-version"}
var macOSJavaTestCommand = "/usr/libexec/java_home"
func checkForMacJVM() (ok bool, err error) {
// test for java differently because of the shim application
var out bytes.Buffer
cmd := exec.Command(macOSJavaTestCommand)
cmd.Stdout = &out
cmd.Stderr = &out
err = cmd.Run()
if err != nil {
err = fmt.Errorf("failed check for macOS jvm: %v, out: %v", err, strings.ReplaceAll(strings.ReplaceAll(out.String(), "\n", " "), `"`, `\"`))
return false, err
}
return true, nil
}
func javaVersionInfo() (version, runtime, vm string, err error) {
var out bytes.Buffer
if rt.GOOS == "darwin" {
_, err = checkForMacJVM()
if err != nil {
err = fmt.Errorf("failed to check java version: %v", err)
return
}
}
cmd := exec.Command(javaVersionCommand[0], javaVersionCommand[1:]...)
cmd.Stdout = &out
cmd.Stderr = &out
err = cmd.Run()
if err != nil {
err = fmt.Errorf("failed to check java version: %v", err)
return
}
version, runtime, vm = parseJavaVersionOutput(out.String())
return
}
var (
javaVersionRe = regexp.MustCompile(`([.\d_]+)`)
)
func parseJavaVersionOutput(infoString string) (version, runtime, vm string) {
infoString = strings.TrimSpace(infoString)
lines := strings.Split(infoString, "\n")
if strings.Contains(lines[0], "Picked up _JAVA_OPTIONS") {
lines = lines[1:]
}
if len(lines) < 3 {
// unexpected output format, don't attempt to parse output for version
return "", "", ""
}
versionString := strings.TrimSpace(lines[0])
if match := javaVersionRe.FindStringSubmatch(versionString); len(match) == 2 {
versionString = match[1]
}
return versionString, strings.TrimSpace(lines[1]), strings.TrimSpace(lines[2])
}