Skip to content

Commit 66a86e7

Browse files
SNOW-2117067 Fix prober Dockerfile (#2223)
1 parent 692d0cd commit 66a86e7

File tree

3 files changed

+50
-31
lines changed

3 files changed

+50
-31
lines changed

prober/Dockerfile

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM ubuntu:24.04
1+
FROM ubuntu:25.10
22

33
# boilerplate labels required by validation when pushing to ACR, ECR & GCR
44
LABEL org.opencontainers.image.source="https://github.com/snowflakedb/snowflake-jdbc"
@@ -21,7 +21,7 @@ RUN apt-get update && \
2121
ca-certificates \
2222
&& rm -rf /var/lib/apt/lists/*
2323

24-
ENV SDKMAN_DIR="/root/.sdkman"
24+
ENV SDKMAN_DIR="/app/.sdkman"
2525

2626
RUN curl -s "https://get.sdkman.io?rcupdate=false&ci=false" | bash
2727

@@ -44,9 +44,6 @@ RUN \
4444

4545
WORKDIR /app
4646

47-
# Create the package directory structure for the Prober
48-
RUN mkdir -p com/snowflake/client/jdbc/prober
49-
5047
# Copy the Prober.java source code into the correct package structure
5148
COPY /src/main/java/com/snowflake/client/jdbc/prober/Prober.java com/snowflake/client/jdbc/prober/Prober.java
5249

@@ -67,8 +64,6 @@ RUN \
6764
bash -c "${COMPILE_COMMAND}"
6865

6966
# Copy the entrypoint script into the image and make it executable
70-
COPY entrypoint.sh /entrypoint.sh
71-
RUN chmod +x /entrypoint.sh
72-
73-
# Set the entrypoint script to be executed when the container starts
74-
ENTRYPOINT ["/entrypoint.sh"]
67+
COPY entrypoint.sh entrypoint.sh
68+
RUN chmod +x entrypoint.sh
69+
RUN chmod +x /app/.sdkman/bin/sdkman-init.sh

prober/entrypoint.sh

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
# Exit immediately if a command exits with a non-zero status
44
set -e
55

6-
# Assign arguments to variables for clarity
76
JAVA_VERSION_ID=""
87
JDBC_VERSION=""
98

@@ -17,23 +16,25 @@ else
1716
exit 1
1817
fi
1918

19+
PROBER_ARGS=("${@}")
20+
2021
# Define key directories
21-
SDKMAN_DIR="/root/.sdkman"
22+
SDKMAN_DIR="/app/.sdkman"
2223
DRIVERS_DIR="/opt/jdbc_drivers"
2324
PROBER_APP_DIR="/app"
2425

25-
# Get all arguments starting from the third one to pass to the Java application
26-
PROBER_ARGS=("${@}")
26+
source "${SDKMAN_DIR}/bin/sdkman-init.sh" >/dev/null 2>&1
27+
sdk use java "${JAVA_VERSION_ID}" >/dev/null 2>&1
2728

2829
JDBC_DRIVER_JAR_PATH="${DRIVERS_DIR}/snowflake-jdbc-${JDBC_VERSION}.jar"
2930
CURRENT_CLASSPATH="${PROBER_APP_DIR}:${JDBC_DRIVER_JAR_PATH}"
3031

31-
# Construct the command to run the pre-compiled Prober application
32-
RUN_PROBER_COMMAND="source \"${SDKMAN_DIR}/bin/sdkman-init.sh\" >/dev/null 2>&1 && \
33-
sdk use java \"${JAVA_VERSION_ID}\" >/dev/null 2>&1 && \
34-
java -cp \"${CURRENT_CLASSPATH}\" --add-opens=java.base/java.nio=ALL-UNNAMED com.snowflake.client.jdbc.prober.Prober \$@"
35-
36-
# Execute the Prober
37-
bash -c "${RUN_PROBER_COMMAND}" _ "${PROBER_ARGS[@]}"
32+
exec java -cp "${CURRENT_CLASSPATH}" \
33+
--add-opens=java.base/java.nio=ALL-UNNAMED \
34+
com.snowflake.client.jdbc.prober.Prober \
35+
"${PROBER_ARGS[@]}"
3836

39-
exit 0
37+
# This line will not be reached because 'exec' replaces the process.
38+
# It would only be reached if 'exec java' itself failed to start the Java process.
39+
echo "Error: Java application failed to start."
40+
exit 1 # Exit with an error if Java failed to start

prober/src/main/java/com/snowflake/client/jdbc/prober/Prober.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,20 @@
88
import java.io.InputStream;
99
import java.io.InputStreamReader;
1010
import java.nio.charset.StandardCharsets;
11+
import java.nio.file.Files;
12+
import java.nio.file.Paths;
13+
import java.security.KeyFactory;
14+
import java.security.NoSuchAlgorithmException;
15+
import java.security.interfaces.RSAPrivateCrtKey;
16+
import java.security.spec.InvalidKeySpecException;
17+
import java.security.spec.PKCS8EncodedKeySpec;
1118
import java.sql.Connection;
1219
import java.sql.DriverManager;
1320
import java.sql.ResultSet;
1421
import java.sql.SQLException;
1522
import java.sql.Statement;
1623
import java.util.ArrayList;
24+
import java.util.Base64;
1725
import java.util.HashMap;
1826
import java.util.List;
1927
import java.util.Map;
@@ -52,20 +60,21 @@ enum Scope {
5260
PUT_FETCH_GET
5361
}
5462

55-
public static void main(String[] args) throws IOException, SQLException {
56-
disableLogging();
63+
public static void main(String[] args) throws Exception {
5764
Map<String, String> arguments = parseArguments(args);
5865

59-
String url = "jdbc:snowflake://" + arguments.get("account") + "." + arguments.get("host");
66+
String url = "jdbc:snowflake://" + arguments.get("host");
6067
Properties props = new Properties();
6168
for (Map.Entry<String, String> entry : arguments.entrySet()) {
6269
props.setProperty(entry.getKey(), entry.getValue());
6370
}
71+
setPrivateKey(props);
72+
setupLogging(props);
6473

6574
javaVersion = props.getProperty("java_version");
6675
driverVersion = props.getProperty("driver_version");
6776

68-
if (Scope.LOGIN.name().toLowerCase().equals(props.getProperty("scope"))){
77+
if (Scope.LOGIN.name().toLowerCase().equals(props.getProperty("scope"))) {
6978
testLogin(url, props);
7079
}
7180
if (Scope.PUT_FETCH_GET.name().toLowerCase().equals(props.getProperty("scope"))) {
@@ -84,10 +93,10 @@ private static void testLogin(String url, Properties properties) {
8493
} catch (SQLException e) {
8594
success = false;
8695
System.err.println(e.getMessage());
87-
logMetric("cloudprober_driver_jdbc_perform_login", Status.FAILURE);
96+
logMetric("cloudprober_driver_java_perform_login", Status.FAILURE);
8897
System.exit(1);
8998
}
90-
logMetric("cloudprober_driver_jdbc_perform_login", success ? Status.SUCCESS : Status.FAILURE);
99+
logMetric("cloudprober_driver_java_perform_login", success ? Status.SUCCESS : Status.FAILURE);
91100
}
92101

93102
private static void testPutFetchGet(String url, Properties properties) {
@@ -271,8 +280,9 @@ private static void createDataStage(Statement statement) throws SQLException {
271280
}
272281
}
273282

274-
private static void disableLogging() throws IOException {
275-
String loggingPropertiesString = ".level=OFF";
283+
private static void setupLogging(Properties properties) throws IOException {
284+
String loggingPropertiesString = "handlers=java.util.logging.ConsoleHandler\n.level=" + properties.getProperty("log_level");
285+
properties.put("JAVA_LOGGING_CONSOLE_STD_OUT", "false");
276286
try (InputStream propertiesStream = new ByteArrayInputStream(
277287
loggingPropertiesString.getBytes(StandardCharsets.UTF_8)
278288
)) {
@@ -281,7 +291,7 @@ private static void disableLogging() throws IOException {
281291
}
282292

283293
private static void logMetric(String metricName, Status status) {
284-
System.out.println(metricName + "{{java_version=" + javaVersion + ", driver_version=" + driverVersion + "} " + status.getCode() + "}");
294+
System.out.println(metricName + "{java_version=\"" + javaVersion + "\", driver_version=\"" + driverVersion + "\"} " + status.getCode());
285295
}
286296

287297
private static Map<String, String> parseArguments(String[] args) {
@@ -341,4 +351,17 @@ private static String generateRandomString(int length) {
341351
builder.setCharAt(0, Character.toUpperCase(builder.charAt(0)));
342352
return builder.toString();
343353
}
354+
355+
private static void setPrivateKey(Properties props) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
356+
String keyStr = new String(Files.readAllBytes(Paths.get(props.getProperty("private_key_file"))), StandardCharsets.UTF_8).trim();
357+
byte[] keyBytes = Base64.getUrlDecoder().decode(keyStr);
358+
359+
// Convert the DER bytes to a private key object
360+
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
361+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
362+
RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec);
363+
props.put("privateKey", privateKey);
364+
// Remove the path from properties so the driver does not try to read it
365+
props.remove("private_key_file");
366+
}
344367
}

0 commit comments

Comments
 (0)