Skip to content

Commit 5053aed

Browse files
authored
Start pushing ml containers (#35595)
* Start pushing ml containers * Consolidate python version values
1 parent 9d47a01 commit 5053aed

16 files changed

Lines changed: 350 additions & 8 deletions

buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,6 +3040,10 @@ class BeamModulePlugin implements Plugin<Project> {
30403040
project.ext.pythonVersion = project.hasProperty('pythonVersion') ?
30413041
project.pythonVersion : '3.9'
30423042

3043+
// Set min/max python versions used for containers and supported versions.
3044+
project.ext.minPythonVersion = 9
3045+
project.ext.maxPythonVersion = 13
3046+
30433047
def setupVirtualenv = project.tasks.register('setupVirtualenv') {
30443048
doLast {
30453049
def virtualenvCmd = [

sdks/python/container/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818

1919
plugins { id 'org.apache.beam.module' }
2020
applyGoNature()
21+
applyPythonNature()
2122

2223
description = "Apache Beam :: SDKs :: Python :: Container"
23-
// Keep these values in sync with sdks/python/container/distroless/build.gradle.
24-
int min_python_version=9
25-
int max_python_version=12
24+
int min_python_version=project.ext.minPythonVersion
25+
int max_python_version=project.ext.maxPythonVersion
2626

2727
configurations {
2828
sdkSourceTarball
@@ -71,6 +71,7 @@ for(int i=min_python_version; i<=max_python_version; ++i) {
7171

7272
tasks.register("pushAll") {
7373
dependsOn ':sdks:python:container:distroless:pushAll'
74+
dependsOn ':sdks:python:container:ml:pushAll'
7475
for(int ver=min_python_version; ver<=max_python_version; ++ver) {
7576
if (!project.hasProperty("skip-python-3" + ver + "-images")) {
7677
dependsOn ':sdks:python:container:push3' + ver

sdks/python/container/common.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def generatePythonRequirements = tasks.register("generatePythonRequirements") {
4141
"${project.ext.pythonVersion} " +
4242
"${files(configurations.sdkSourceTarball.files).singleFile} " +
4343
"base_image_requirements.txt " +
44+
"container" +
4445
"[gcp,dataframe,test] " +
4546
"${pipExtraOptions}"
4647
}
@@ -51,6 +52,7 @@ def generatePythonRequirements = tasks.register("generatePythonRequirements") {
5152
"${project.ext.pythonVersion} " +
5253
"${files(configurations.sdkSourceTarball.files).singleFile} " +
5354
"ml_image_requirements.txt " +
55+
"container/ml" +
5456
"[gcp,dataframe,test,tensorflow,torch,transformers] " +
5557
"${pipExtraOptions}"
5658
}

sdks/python/container/distroless/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
*/
1818

1919
plugins { id 'org.apache.beam.module' }
20+
applyPythonNature()
2021

2122
description = "Apache Beam :: SDKs :: Python :: Container :: Distroless"
22-
// Keep these values in sync with sdks/python/container/build.gradle.
23-
int min_python_version=9
24-
int max_python_version=12
23+
int min_python_version=project.ext.minPythonVersion
24+
int max_python_version=project.ext.maxPythonVersion
2525

2626

2727
tasks.register("buildAll") {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* License); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an AS IS BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
plugins { id 'org.apache.beam.module' }
20+
applyPythonNature()
21+
22+
description = "Apache Beam :: SDKs :: Python :: Container :: ML"
23+
int min_python_version=project.ext.minPythonVersion
24+
int max_python_version=project.ext.maxPythonVersion
25+
26+
27+
tasks.register("buildAll") {
28+
for(int ver=min_python_version; ver<=max_python_version; ++ver) {
29+
dependsOn ':sdks:python:container:ml:py3' + ver + ':docker'
30+
}
31+
}
32+
33+
for(int i=min_python_version; i<=max_python_version; ++i) {
34+
String min_version = "3" + min_python_version
35+
String cur = "3" + i
36+
String prev = "3" + (i-1)
37+
tasks.register("push" + cur) {
38+
if (cur != min_version) {
39+
// Enforce ordering to allow the prune step to happen between runs.
40+
// This will ensure we don't use up too much space (especially in CI environments)
41+
if (!project.hasProperty("skip-python-3" + prev + "-images")) {
42+
mustRunAfter(":sdks:python:container:ml:push" + prev)
43+
}
44+
}
45+
dependsOn ':sdks:python:container:ml:py' + cur + ':docker'
46+
47+
doLast {
48+
if (project.hasProperty("prune-images")) {
49+
exec {
50+
executable("docker")
51+
args("system", "prune", "-a", "--force")
52+
}
53+
}
54+
}
55+
}
56+
}
57+
58+
tasks.register("pushAll") {
59+
for(int ver=min_python_version; ver<=max_python_version; ++ver) {
60+
if (!project.hasProperty("skip-python-3" + ver + "-images")) {
61+
dependsOn ':sdks:python:container:ml:push3' + ver
62+
}
63+
}
64+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* License); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an AS IS BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
def pythonVersionSuffix = project.ext.pythonVersion.replace('.', '')
20+
21+
description = "Apache Beam :: SDKs :: Python :: Container :: ML :: Python ${pythonVersionSuffix} Container"
22+
23+
configurations {
24+
sdkSourceTarball
25+
pythonHarnessLauncher
26+
}
27+
28+
dependencies {
29+
sdkSourceTarball project(path: ":sdks:python", configuration: "distTarBall")
30+
pythonHarnessLauncher project(path: ":sdks:python:container", configuration: "pythonHarnessLauncher")
31+
}
32+
33+
def generatePythonRequirements = tasks.register("generatePythonRequirements") {
34+
dependsOn ':sdks:python:sdist'
35+
def pipExtraOptions = project.hasProperty("testRCDependencies") ? "--pre" : ""
36+
def runScriptsPath = "${rootDir}/sdks/python/container/run_generate_requirements.sh"
37+
doLast {
38+
exec {
39+
executable 'sh'
40+
args '-c', "cd ${rootDir} && ${runScriptsPath} " +
41+
"${project.ext.pythonVersion} " +
42+
"${files(configurations.sdkSourceTarball.files).singleFile} " +
43+
"base_image_requirements.txt " +
44+
"[gcp,dataframe,test] " +
45+
"${pipExtraOptions}"
46+
}
47+
// Generate versions for ML dependencies
48+
exec {
49+
executable 'sh'
50+
args '-c', "cd ${rootDir} && ${runScriptsPath} " +
51+
"${project.ext.pythonVersion} " +
52+
"${files(configurations.sdkSourceTarball.files).singleFile} " +
53+
"ml_image_requirements.txt " +
54+
"[gcp,dataframe,test,tensorflow,torch,transformers] " +
55+
"${pipExtraOptions}"
56+
}
57+
}
58+
}
59+
60+
def copyDockerfileDependencies = tasks.register("copyDockerfileDependencies", Copy) {
61+
from configurations.sdkSourceTarball
62+
from file("base_image_requirements.txt")
63+
into "build/target"
64+
if(configurations.sdkSourceTarball.isEmpty()) {
65+
throw new StopExecutionException();
66+
}
67+
}
68+
69+
def copyLicenseScripts = tasks.register("copyLicenseScripts", Copy){
70+
from ("../license_scripts")
71+
into "build/target/license_scripts"
72+
}
73+
74+
def copyLauncherDependencies = tasks.register("copyLauncherDependencies", Copy) {
75+
from configurations.pythonHarnessLauncher
76+
into "build/target/launcher"
77+
78+
// Avoid seemingly gradle bug stated in https://github.com/apache/beam/issues/29220
79+
mustRunAfter "copyLicenses"
80+
81+
if(configurations.pythonHarnessLauncher.isEmpty()) {
82+
throw new StopExecutionException();
83+
}
84+
}
85+
86+
def pushContainers = project.rootProject.hasProperty(["isRelease"]) || project.rootProject.hasProperty("push-containers")
87+
88+
docker {
89+
name containerImageName(
90+
name: project.docker_image_default_repo_prefix + "python${project.ext.pythonVersion}_sdk_ml",
91+
root: project.rootProject.hasProperty(["docker-repository-root"]) ?
92+
project.rootProject["docker-repository-root"] :
93+
project.docker_image_default_repo_root,
94+
tag: project.rootProject.hasProperty(["docker-tag"]) ?
95+
project.rootProject["docker-tag"] : project.sdk_version)
96+
// tags used by dockerTag task
97+
tags containerImageTags()
98+
files "../../Dockerfile", "./build"
99+
buildArgs(['py_version': "${project.ext.pythonVersion}",
100+
'pull_licenses': project.rootProject.hasProperty(["docker-pull-licenses"]) ||
101+
project.rootProject.hasProperty(["isRelease"])])
102+
buildx project.useBuildx()
103+
platform(*project.containerPlatforms())
104+
load project.useBuildx() && !pushContainers
105+
push pushContainers
106+
}
107+
108+
dockerPrepare.dependsOn copyLauncherDependencies
109+
dockerPrepare.dependsOn copyDockerfileDependencies
110+
dockerPrepare.dependsOn copyLicenseScripts
111+
112+
if (project.rootProject.hasProperty("docker-pull-licenses")) {
113+
def copyGolangLicenses = tasks.register("copyGolangLicenses", Copy) {
114+
from "${project(':release:go-licenses:py').buildDir}/output"
115+
into "build/target/go-licenses"
116+
dependsOn ':release:go-licenses:py:createLicenses'
117+
}
118+
dockerPrepare.dependsOn copyGolangLicenses
119+
} else {
120+
def skipPullLicenses = tasks.register("skipPullLicenses", Exec) {
121+
executable "sh"
122+
// Touch a dummy file to ensure the directory exists.
123+
args "-c", "mkdir -p build/target/go-licenses && touch build/target/go-licenses/skip"
124+
}
125+
dockerPrepare.dependsOn skipPullLicenses
126+
}

sdks/python/container/py310/ml_image_requirements.txt renamed to sdks/python/container/ml/py310/base_image_requirements.txt

File renamed without changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* License); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an AS IS BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
plugins {
20+
id 'base'
21+
id 'org.apache.beam.module'
22+
}
23+
applyDockerNature()
24+
applyPythonNature()
25+
26+
pythonVersion = '3.10'
27+
28+
apply from: "../common.gradle"

sdks/python/container/py311/ml_image_requirements.txt renamed to sdks/python/container/ml/py311/base_image_requirements.txt

File renamed without changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* License); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an AS IS BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
plugins {
20+
id 'base'
21+
id 'org.apache.beam.module'
22+
}
23+
applyDockerNature()
24+
applyPythonNature()
25+
26+
pythonVersion = '3.11'
27+
28+
apply from: "../common.gradle"

0 commit comments

Comments
 (0)