@@ -154,9 +154,11 @@ def firestoreDb = project.findProperty('firestoreDb') ?: 'firestoredb'
154
154
155
155
def dockerImageRoot = project. findProperty(' dockerImageRoot' ) ?: " us.gcr.io/${ gcpProject.replaceAll(':', '/')} /java-postcommit-it"
156
156
def dockerJavaImageContainer = " ${ dockerImageRoot} /java"
157
+ def distrolessDockerJavaImageContainer = " ${ dockerImageRoot} /java-distroless"
157
158
def dockerPythonImageContainer = " ${ dockerImageRoot} /python"
158
159
def dockerTag = new Date (). format(' yyyyMMddHHmmss' )
159
160
ext. dockerJavaImageName = " ${ dockerJavaImageContainer} :${ dockerTag} "
161
+ ext. distrolessDockerJavaImageName = " ${ distrolessDockerJavaImageContainer} :${ dockerTag} "
160
162
ext. dockerPythonImageName = " ${ dockerPythonImageContainer} :${ dockerTag} "
161
163
162
164
def legacyPipelineOptions = [
@@ -174,12 +176,22 @@ def runnerV2PipelineOptions = [
174
176
" --project=${ gcpProject} " ,
175
177
" --region=${ gcpRegion} " ,
176
178
" --tempRoot=${ dataflowValidatesTempRoot} " ,
177
- " --sdkContainerImage=${ dockerJavaImageContainer } : ${ dockerTag } " ,
179
+ " --sdkContainerImage=${ dockerJavaImageName } " ,
178
180
" --experiments=use_unified_worker,use_runner_v2" ,
179
181
" --firestoreDb=${ firestoreDb} " ,
180
182
" --experiments=enable_lineage"
181
183
]
182
184
185
+ def runnerV2PipelineOptionsDistroless = [
186
+ " --runner=TestDataflowRunner" ,
187
+ " --project=${ gcpProject} " ,
188
+ " --region=${ gcpRegion} " ,
189
+ " --tempRoot=${ dataflowValidatesTempRoot} " ,
190
+ " --sdkContainerImage=${ distrolessDockerJavaImageName} " ,
191
+ " --experiments=use_unified_worker,use_runner_v2" ,
192
+ " --firestoreDb=${ firestoreDb} " ,
193
+ ]
194
+
183
195
def commonLegacyExcludeCategories = [
184
196
// Should be run only in a properly configured SDK harness environment
185
197
' org.apache.beam.sdk.testing.UsesSdkHarnessEnvironment' ,
@@ -279,69 +291,6 @@ def createRunnerV2ValidatesRunnerTest = { Map args ->
279
291
}
280
292
}
281
293
282
- tasks. register(' examplesJavaRunnerV2IntegrationTestDistroless' , Test . class) {
283
- group = " verification"
284
- dependsOn ' buildAndPushDistrolessContainerImage'
285
- def javaVer = project. findProperty(' testJavaVersion' )
286
- def repository = " us.gcr.io/apache-beam-testing/${ System.getenv('USER')} "
287
- def tag = project. findProperty(' dockerTag' )
288
- def imageURL = " ${ repository} /beam_${ javaVer} _sdk_distroless:${ tag} "
289
- def pipelineOptions = [
290
- " --runner=TestDataflowRunner" ,
291
- " --project=${ gcpProject} " ,
292
- " --region=${ gcpRegion} " ,
293
- " --tempRoot=${ dataflowValidatesTempRoot} " ,
294
- " --sdkContainerImage=${ imageURL} " ,
295
- " --experiments=use_unified_worker,use_runner_v2" ,
296
- " --firestoreDb=${ firestoreDb} " ,
297
- ]
298
- systemProperty " beamTestPipelineOptions" , JsonOutput . toJson(pipelineOptions)
299
-
300
- include ' **/*IT.class'
301
-
302
- maxParallelForks 4
303
- classpath = configurations. examplesJavaIntegrationTest
304
- testClassesDirs = files(project(" :examples:java" ). sourceSets. test. output. classesDirs)
305
- useJUnit { }
306
- }
307
-
308
- tasks. register(' buildAndPushDistrolessContainerImage' , Task . class) {
309
- // Only Java 17 and 21 are supported.
310
- // See https://github.com/GoogleContainerTools/distroless/tree/main/java#image-contents.
311
- def allowed = [" java17" , " java21" ]
312
- doLast {
313
- def javaVer = project. findProperty(' testJavaVersion' )
314
- if (! allowed. contains(javaVer)) {
315
- throw new GradleException (" testJavaVersion must be one of ${ allowed} , got: ${ javaVer} " )
316
- }
317
- if (! project. hasProperty(' dockerTag' )) {
318
- throw new GradleException (" dockerTag is missing but required" )
319
- }
320
- def repository = " us.gcr.io/apache-beam-testing/${ System.getenv('USER')} "
321
- def tag = project. findProperty(' dockerTag' )
322
- def imageURL = " ${ repository} /beam_${ javaVer} _sdk_distroless:${ tag} "
323
- exec {
324
- executable ' docker'
325
- workingDir rootDir
326
- args = [
327
- ' buildx' ,
328
- ' build' ,
329
- ' -t' ,
330
- imageURL,
331
- ' -f' ,
332
- ' sdks/java/container/Dockerfile-distroless' ,
333
- " --build-arg=BEAM_BASE=gcr.io/apache-beam-testing/beam-sdk/beam_${ javaVer} _sdk" ,
334
- " --build-arg=DISTROLESS_BASE=gcr.io/distroless/${ javaVer} -debian12" ,
335
- ' .'
336
- ]
337
- }
338
- exec {
339
- executable ' docker'
340
- args = [' push' , imageURL]
341
- }
342
- }
343
- }
344
-
345
294
// Push docker images to a container registry for use within tests.
346
295
// NB: Tasks which consume docker images from the registry should depend on this
347
296
// task directly ('dependsOn buildAndPushDockerJavaContainer'). This ensures the correct
@@ -383,6 +332,47 @@ def cleanUpDockerJavaImages = tasks.register("cleanUpDockerJavaImages") {
383
332
}
384
333
}
385
334
335
+ // Push docker images to a container registry for use within tests.
336
+ // NB: Tasks which consume docker images from the registry should depend on this
337
+ // task directly ('dependsOn buildAndPushDistrolessDockerJavaContainer'). This ensures the correct
338
+ // task ordering such that the registry doesn't get cleaned up prior to task completion.
339
+ def buildAndPushDistrolessDockerJavaContainer = tasks. register(" buildAndPushDistrolessDockerJavaContainer" ) {
340
+ def javaVer = getSupportedJavaVersion()
341
+ if (project. hasProperty(' testJavaVersion' )) {
342
+ javaVer = " java${ project.getProperty('testJavaVersion')} "
343
+ }
344
+ dependsOn " :sdks:java:container:distroless:${ javaVer} :docker"
345
+ def defaultDockerImageName = containerImageName(
346
+ name : " ${ project.docker_image_default_repo_prefix}${ javaVer} _sdk_distroless" ,
347
+ root : " apache" ,
348
+ tag : project. sdk_version)
349
+ doLast {
350
+ exec {
351
+ commandLine " docker" , " tag" , " ${ defaultDockerImageName} " , " ${ distrolessDockerJavaImageName} "
352
+ }
353
+ exec {
354
+ commandLine " gcloud" , " docker" , " --" , " push" , " ${ distrolessDockerJavaImageName} "
355
+ }
356
+ }
357
+ }
358
+
359
+ // Clean up built distroless Java images
360
+ def cleanUpDistrolessDockerJavaImages = tasks. register(" cleanUpDistrolessDockerJavaImages" ) {
361
+ doLast {
362
+ exec {
363
+ commandLine " docker" , " rmi" , " --force" , " ${ distrolessDockerJavaImageName} "
364
+ }
365
+ exec {
366
+ ignoreExitValue true
367
+ commandLine " gcloud" , " --quiet" , " container" , " images" , " untag" , " ${ distrolessDockerJavaImageName} "
368
+ }
369
+ exec {
370
+ ignoreExitValue true
371
+ commandLine " ./scripts/cleanup_untagged_gcr_images.sh" , " ${ distrolessDockerJavaImageContainer} "
372
+ }
373
+ }
374
+ }
375
+
386
376
// Push docker images to a container registry for use within tests.
387
377
// NB: Tasks which consume docker images from the registry should depend on this
388
378
// task directly ('dependsOn buildAndPushDockerPythonContainer'). This ensures the correct
@@ -432,6 +422,9 @@ afterEvaluate {
432
422
if (t. dependsOn. contains(buildAndPushDockerJavaContainer) && ! t. name. equalsIgnoreCase(' printRunnerV2PipelineOptions' )) {
433
423
t. finalizedBy cleanUpDockerJavaImages
434
424
}
425
+ if (t. dependsOn. contains(buildAndPushDistrolessDockerJavaContainer)) {
426
+ t. finalizedBy cleanUpDistrolessDockerJavaImages
427
+ }
435
428
if (t. dependsOn. contains(buildAndPushDockerPythonContainer)) {
436
429
t. finalizedBy cleanUpDockerPythonImages
437
430
}
@@ -505,15 +498,15 @@ createCrossLanguageValidatesRunnerTask(
505
498
" --runner=TestDataflowRunner" ,
506
499
" --project=${ gcpProject} " ,
507
500
" --region=${ gcpRegion} " ,
508
- " --sdk_harness_container_image_overrides=.*java.*,${ dockerJavaImageContainer } : ${ dockerTag } " ,
501
+ " --sdk_harness_container_image_overrides=.*java.*,${ dockerJavaImageName } " ,
509
502
],
510
503
javaPipelineOptions : [
511
504
" --runner=TestDataflowRunner" ,
512
505
" --project=${ gcpProject} " ,
513
506
" --region=${ gcpRegion} " ,
514
507
" --tempRoot=${ dataflowValidatesTempRoot} " ,
515
- " --sdkContainerImage=${ dockerJavaImageContainer } : ${ dockerTag } " ,
516
- " --sdkHarnessContainerImageOverrides=.*python.*,${ dockerPythonImageContainer } : ${ dockerTag } " ,
508
+ " --sdkContainerImage=${ dockerJavaImageName } " ,
509
+ " --sdkHarnessContainerImageOverrides=.*python.*,${ dockerPythonImageName } " ,
517
510
],
518
511
pytestOptions : [
519
512
" --capture=no" ,
@@ -527,7 +520,7 @@ createCrossLanguageValidatesRunnerTask(
527
520
" --dataflow_project ${ gcpProject} " ,
528
521
" --region ${ gcpRegion} " ,
529
522
" --tests \" ./test/integration/xlang ./test/integration/io/xlang/...\" " ,
530
- " --sdk_overrides \" .*java.*,${ dockerJavaImageContainer } : ${ dockerTag } \" " ,
523
+ " --sdk_overrides \" .*java.*,${ dockerJavaImageName } \" " ,
531
524
],
532
525
)
533
526
@@ -750,6 +743,36 @@ task examplesJavaRunnerV2IntegrationTest(type: Test) {
750
743
useJUnit { }
751
744
}
752
745
746
+ task examplesJavaDistrolessRunnerV2PreCommit (type : Test ) {
747
+ group = " Verification"
748
+ dependsOn buildAndPushDistrolessDockerJavaContainer
749
+ systemProperty " beamTestPipelineOptions" , JsonOutput . toJson(runnerV2PipelineOptionsDistroless)
750
+ include ' **/WordCountIT.class'
751
+ include ' **/WindowedWordCountIT.class'
752
+
753
+ maxParallelForks 4
754
+ classpath = configurations. examplesJavaIntegrationTest
755
+ testClassesDirs = files(project(" :examples:java" ). sourceSets. test. output. classesDirs)
756
+ useJUnit { }
757
+ }
758
+
759
+ task examplesJavaRunnerV2IntegrationTestDistroless (type : Test ) {
760
+ group = " Verification"
761
+ dependsOn buildAndPushDistrolessDockerJavaContainer
762
+ if (project. hasProperty(" testJavaVersion" )) {
763
+ dependsOn " :sdks:java:testing:test-utils:verifyJavaVersion${ project.property("testJavaVersion")} "
764
+ }
765
+
766
+ systemProperty " beamTestPipelineOptions" , JsonOutput . toJson(runnerV2PipelineOptionsDistroless)
767
+
768
+ include ' **/*IT.class'
769
+
770
+ maxParallelForks 4
771
+ classpath = configurations. examplesJavaIntegrationTest
772
+ testClassesDirs = files(project(" :examples:java" ). sourceSets. test. output. classesDirs)
773
+ useJUnit { }
774
+ }
775
+
753
776
task coreSDKJavaLegacyWorkerIntegrationTest (type : Test ) {
754
777
group = " Verification"
755
778
dependsOn " :runners:google-cloud-dataflow-java:worker:shadowJar"
@@ -838,36 +861,3 @@ task GCSUpload(type: JavaExec) {
838
861
args " --stagingLocation=${ dataflowUploadTemp} /staging" ,
839
862
" --filesToStage=${ testFilesToStage} "
840
863
}
841
-
842
- def buildAndPushDistrolessDockerJavaContainer = tasks. register(" buildAndPushDistrolessDockerJavaContainer" ) {
843
- def javaVer = getSupportedJavaVersion()
844
- if (project. hasProperty(' testJavaVersion' )) {
845
- javaVer = " java${ project.getProperty('testJavaVersion')} "
846
- }
847
- dependsOn " :sdks:java:container:distroless:${ javaVer} :docker"
848
- def defaultDockerImageName = containerImageName(
849
- name : " ${ project.docker_image_default_repo_prefix}${ javaVer} _sdk_distroless" ,
850
- root : " apache" ,
851
- tag : project. sdk_version)
852
- doLast {
853
- exec {
854
- commandLine " docker" , " tag" , " ${ defaultDockerImageName} " , " ${ dockerJavaImageName} "
855
- }
856
- exec {
857
- commandLine " gcloud" , " docker" , " --" , " push" , " ${ dockerJavaImageName} "
858
- }
859
- }
860
- }
861
-
862
- task examplesJavaDistrolessRunnerV2PreCommit (type : Test ) {
863
- group = " Verification"
864
- dependsOn buildAndPushDistrolessDockerJavaContainer
865
- systemProperty " beamTestPipelineOptions" , JsonOutput . toJson(runnerV2PipelineOptions)
866
- include ' **/WordCountIT.class'
867
- include ' **/WindowedWordCountIT.class'
868
-
869
- maxParallelForks 4
870
- classpath = configurations. examplesJavaIntegrationTest
871
- testClassesDirs = files(project(" :examples:java" ). sourceSets. test. output. classesDirs)
872
- useJUnit { }
873
- }
0 commit comments