1#!/usr/bin/env python
2# Copyright 2016 gRPC authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15"""Definition of targets to build distribution packages."""
16
17import os.path
18import sys
19
20sys.path.insert(0, os.path.abspath('..'))
21import python_utils.jobset as jobset
22
23
24def create_docker_jobspec(name,
25                          dockerfile_dir,
26                          shell_command,
27                          environ={},
28                          flake_retries=0,
29                          timeout_retries=0):
30    """Creates jobspec for a task running under docker."""
31    environ = environ.copy()
32    environ['RUN_COMMAND'] = shell_command
33
34    docker_args = []
35    for k, v in environ.items():
36        docker_args += ['-e', '%s=%s' % (k, v)]
37    docker_env = {
38        'DOCKERFILE_DIR': dockerfile_dir,
39        'DOCKER_RUN_SCRIPT': 'tools/run_tests/dockerize/docker_run.sh',
40        'OUTPUT_DIR': 'artifacts'
41    }
42    jobspec = jobset.JobSpec(
43        cmdline=['tools/run_tests/dockerize/build_and_run_docker.sh'] +
44        docker_args,
45        environ=docker_env,
46        shortname='build_package.%s' % (name),
47        timeout_seconds=30 * 60,
48        flake_retries=flake_retries,
49        timeout_retries=timeout_retries)
50    return jobspec
51
52
53def create_jobspec(name,
54                   cmdline,
55                   environ=None,
56                   cwd=None,
57                   shell=False,
58                   flake_retries=0,
59                   timeout_retries=0,
60                   cpu_cost=1.0):
61    """Creates jobspec."""
62    jobspec = jobset.JobSpec(
63        cmdline=cmdline,
64        environ=environ,
65        cwd=cwd,
66        shortname='build_package.%s' % (name),
67        timeout_seconds=10 * 60,
68        flake_retries=flake_retries,
69        timeout_retries=timeout_retries,
70        cpu_cost=cpu_cost,
71        shell=shell)
72    return jobspec
73
74
75class CSharpPackage:
76    """Builds C# packages."""
77
78    def __init__(self, unity=False):
79        self.unity = unity
80        self.labels = ['package', 'csharp', 'windows']
81        if unity:
82            self.name = 'csharp_package_unity_windows'
83            self.labels += ['unity']
84        else:
85            self.name = 'csharp_package_nuget_windows'
86            self.labels += ['nuget']
87
88    def pre_build_jobspecs(self):
89        return []
90
91    def build_jobspec(self):
92        if self.unity:
93            # use very high CPU cost to avoid running nuget package build
94            # and unity build concurrently
95            return create_jobspec(
96                self.name, ['build_unitypackage.bat'],
97                cwd='src\\csharp',
98                cpu_cost=1e6,
99                shell=True)
100        else:
101            return create_jobspec(
102                self.name, ['build_packages_dotnetcli.bat'],
103                cwd='src\\csharp',
104                shell=True)
105
106    def __str__(self):
107        return self.name
108
109
110class RubyPackage:
111    """Collects ruby gems created in the artifact phase"""
112
113    def __init__(self):
114        self.name = 'ruby_package'
115        self.labels = ['package', 'ruby', 'linux']
116
117    def pre_build_jobspecs(self):
118        return []
119
120    def build_jobspec(self):
121        return create_docker_jobspec(
122            self.name, 'tools/dockerfile/grpc_artifact_linux_x64',
123            'tools/run_tests/artifacts/build_package_ruby.sh')
124
125
126class PythonPackage:
127    """Collects python eggs and wheels created in the artifact phase"""
128
129    def __init__(self):
130        self.name = 'python_package'
131        self.labels = ['package', 'python', 'linux']
132
133    def pre_build_jobspecs(self):
134        return []
135
136    def build_jobspec(self):
137        return create_docker_jobspec(
138            self.name, 'tools/dockerfile/grpc_artifact_linux_x64',
139            'tools/run_tests/artifacts/build_package_python.sh')
140
141
142class PHPPackage:
143    """Copy PHP PECL package artifact"""
144
145    def __init__(self):
146        self.name = 'php_package'
147        self.labels = ['package', 'php', 'linux']
148
149    def pre_build_jobspecs(self):
150        return []
151
152    def build_jobspec(self):
153        return create_docker_jobspec(
154            self.name, 'tools/dockerfile/grpc_artifact_linux_x64',
155            'tools/run_tests/artifacts/build_package_php.sh')
156
157
158def targets():
159    """Gets list of supported targets"""
160    return [
161        CSharpPackage(),
162        CSharpPackage(unity=True),
163        RubyPackage(),
164        PythonPackage(),
165        PHPPackage()
166    ]
167