Skip to content

Commit 69d746a

Browse files
committed
feat: harmonise OpenLineage jar name via a stable image symlink
1 parent 6c5a3cb commit 69d746a

4 files changed

Lines changed: 17 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
88

99
- BREAKING: Add required CLI argument and env var to set the image repository used to construct final product image names: `IMAGE_REPOSITORY` (`--image-repository`), eg. `oci.example.org/my/namespace` ([#684]).
1010
- Support for Spark `4.1.2` ([#708])
11-
- Add `spec.openLineage` to enable OpenLineage lineage emission: injects the OpenLineage Spark listener, HTTP transport (endpoint resolved from a discovery ConfigMap) and a stable job name. The Scala build of the listener jar and the `--add-opens java.base/java.security` JVM flag are selected by the Spark version: the `--add-opens` flag is emitted only on Spark 4.x (it is unnecessary on the Spark 3.5.x images and must not be set there) ([#XXXX]).
11+
- Add `spec.openLineage` to enable OpenLineage lineage emission: injects the OpenLineage Spark listener, HTTP transport (endpoint resolved from a discovery ConfigMap) and a stable job name. The listener jar is referenced through a stable, version- and Scala-independent symlink maintained by the Spark image, so the operator tracks neither. The `--add-opens java.base/java.security` JVM flag is emitted only on Spark 4.x (it is unnecessary on the Spark 3.5.x images and must not be set there) ([#XXXX]).
1212

1313
### Fixed
1414

docs/modules/spark-k8s/pages/usage-guide/openlineage.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The Spark operator can automatically emit lineage events for a `SparkApplication
66
When enabled, the operator injects everything required to make the https://openlineage.io/docs/integrations/spark/[OpenLineage Spark listener] work:
77

88
* the OpenLineage Spark listener (appended to `spark.extraListeners`, so any listener you configure yourself is preserved),
9-
* the OpenLineage jar baked into the Spark image, referenced via `spark.jars` so it shares the same classloader as connectors pulled in through xref:usage-guide/job-dependencies.adoc[`deps.packages`] (for example Apache Iceberg). The operator selects the jar built for the image's Scala version automatically (Scala 2.13 for Spark 4.x, Scala 2.12 for Spark 3.5.x),
9+
* the OpenLineage jar baked into the Spark image, referenced via `spark.jars` so it shares the same classloader as connectors pulled in through xref:usage-guide/job-dependencies.adoc[`deps.packages`] (for example Apache Iceberg). The operator references a stable symlink maintained by the image, which points at the correct build for that image's Spark version (Scala 2.13 for Spark 4.x, Scala 2.12 for Spark 3.5.x), so neither the jar version nor its Scala suffix has to be tracked in the operator,
1010
* an HTTP transport pointing at the backend endpoint,
1111
* a stable lineage namespace and job name (see <<job-name>>), and
1212
* on Spark 4.x only, the `--add-opens java.base/java.security=ALL-UNNAMED` JVM flag the listener requires on the driver and executors. This flag is not added on the Spark 3.5.x images, where it is unnecessary (and, on their JVM, potentially harmful).

rust/operator-binary/src/crd/constants.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,25 +108,17 @@ pub const DEFAULT_SUBMIT_JOB_RETRY_ON_FAILURE_COUNT: u16 = 0;
108108
/// The OpenLineage Spark listener, appended to `spark.extraListeners` when OpenLineage is enabled.
109109
pub const OPENLINEAGE_LISTENER_CLASS: &str = "io.openlineage.spark.agent.OpenLineageSparkListener";
110110

111-
/// Version of the OpenLineage Spark listener jar baked into the Spark images.
112-
///
113-
/// IMPORTANT: MUST stay in sync with the `openlineage-spark-version` build-argument in
114-
/// `docker-images/spark-k8s/boil-config.toml` (the image is what places the jar on disk).
115-
pub const OPENLINEAGE_SPARK_JAR_VERSION: &str = "1.51.0";
116-
117111
/// `local://` URI of the OpenLineage jar baked into the Spark image, referenced via `spark.jars` so
118112
/// it shares the (child) classloader with `--packages` connectors. Delivering it this way — rather
119113
/// than on `extraClassPath` (system classloader) — is what lets OpenLineage's connector probes
120114
/// succeed; see the classpath discussion in the OpenLineage usage guide.
121115
///
122-
/// The jar's Scala suffix depends on the Spark image: Stackable ships Spark 4.x as Scala 2.13 and
123-
/// Spark 3.5.x as Scala 2.12, so the operator selects the matching jar by Spark major version.
124-
/// `scala_binary_version` is e.g. `"2.13"` or `"2.12"`.
125-
pub fn openlineage_jar_local_uri(scala_binary_version: &str) -> String {
126-
format!(
127-
"local:///stackable/spark/openlineage/openlineage-spark_{scala_binary_version}-{OPENLINEAGE_SPARK_JAR_VERSION}.jar"
128-
)
129-
}
116+
/// This is a stable, version- and Scala-independent symlink the image maintains (mirroring the
117+
/// `jmx_prometheus_javaagent.jar` pattern): the image bakes the correct `openlineage-spark_<scala>-<version>.jar`
118+
/// for its Spark build and symlinks it here. Referencing the symlink decouples the operator from the
119+
/// jar's version and Scala suffix, so bumping either only touches `docker-images/spark-k8s`.
120+
pub const OPENLINEAGE_JAR_LOCAL_URI: &str =
121+
"local:///stackable/spark/openlineage/openlineage-spark.jar";
130122

131123
/// The key the OpenLineage discovery ConfigMap must hold, carrying the backend base URL. Mirrors the
132124
/// `ADDRESS` contract of the existing `vectorAggregatorConfigMapName` discovery ConfigMap.

rust/operator-binary/src/crd/mod.rs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -892,20 +892,9 @@ impl v1alpha1::SparkApplication {
892892
"spark.extraListeners",
893893
OPENLINEAGE_LISTENER_CLASS,
894894
);
895-
// Select the jar built for the image's Scala version: Stackable ships Spark 4.x as
896-
// Scala 2.13 and Spark 3.5.x as Scala 2.12. Referencing the wrong build would leave a
897-
// non-existent path in `spark.jars`, which Spark ignores silently (no listener, no
898-
// events), so this must track the actual image.
899-
let scala_binary_version = if spark_major_version(product_version)? >= 4 {
900-
"2.13"
901-
} else {
902-
"2.12"
903-
};
904-
append_conf_csv(
905-
&mut submit_conf,
906-
"spark.jars",
907-
&openlineage_jar_local_uri(scala_binary_version),
908-
);
895+
// Reference the stable symlink the image maintains; it points at the correct
896+
// Scala/version build for this image, so the operator needs to know neither.
897+
append_conf_csv(&mut submit_conf, "spark.jars", OPENLINEAGE_JAR_LOCAL_URI);
909898
}
910899

911900
// ...before being added to the command collection
@@ -1836,10 +1825,9 @@ spec:
18361825
assert!(command.contains(&format!(
18371826
r#"--conf "spark.extraListeners={OPENLINEAGE_LISTENER_CLASS}""#
18381827
)));
1839-
// Spark 4.x is Scala 2.13, so the 2.13 build of the jar is referenced.
1828+
// The jar is referenced via the stable, Scala/version-independent image symlink.
18401829
assert!(command.contains(&format!(
1841-
r#"--conf "spark.jars={}""#,
1842-
openlineage_jar_local_uri("2.13")
1830+
r#"--conf "spark.jars={OPENLINEAGE_JAR_LOCAL_URI}""#
18431831
)));
18441832
// --add-opens reaches both driver and executor on Spark 4.x.
18451833
assert_eq!(
@@ -1850,18 +1838,17 @@ spec:
18501838
}
18511839

18521840
#[test]
1853-
fn test_openlineage_selects_scala_2_12_jar_and_no_add_opens_on_spark_3() {
1854-
// On the Scala 2.12 / JDK 17 Spark 3.5.x images, the operator must reference the 2.12 build
1855-
// of the jar (the 2.13 path would not exist in the image) and must NOT emit `--add-opens`.
1841+
fn test_openlineage_stable_jar_uri_and_no_add_opens_on_spark_3() {
1842+
// On the JDK 17 Spark 3.5.x images the operator references the same stable jar symlink (the
1843+
// image points it at the Scala 2.12 build) and must NOT emit `--add-opens`.
18561844
let command = build_command_with_openlineage(
18571845
OPENLINEAGE_ENABLED_APP,
18581846
"3.5.8",
18591847
Some("http://marquez:5000"),
18601848
);
18611849

18621850
assert!(command.contains(&format!(
1863-
r#"--conf "spark.jars={}""#,
1864-
openlineage_jar_local_uri("2.12")
1851+
r#"--conf "spark.jars={OPENLINEAGE_JAR_LOCAL_URI}""#
18651852
)));
18661853
assert!(
18671854
!command.contains(OPENLINEAGE_ADD_OPENS),

0 commit comments

Comments
 (0)