Skip to content

Commit 1cdcf32

Browse files
Get batch ready for OSS-Fuzz (#4387)
This should not be landed before the corresponding internal config change. 1. Fix utask-main scheduling for oss-fuzz. 2. Fix configuration of subnet, network, and gce region 3. Only test using skia for now. 4. Add tests for this functionality.
1 parent 56f7d9e commit 1cdcf32

File tree

8 files changed

+64
-34
lines changed

8 files changed

+64
-34
lines changed

configs/test/batch/batch.yaml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ mapping:
2121
disk_type: pd-standard
2222
service_account_email: test-clusterfuzz-service-account-email
2323
subnetwork: null
24+
gce_region: 'gce-region'
2425
gce_zone: 'gce-zone'
26+
network: 'projects/google.com:clusterfuzz/global/networks/networkname'
27+
subnetwork: 'projects/google.com:clusterfuzz/regions/gce-region/subnetworks/subnetworkname'
2528
preemptible: false
2629
machine_type: n1-standard-1
2730
LINUX-NONPREEMPTIBLE-UNPRIVILEGED:
@@ -31,8 +34,10 @@ mapping:
3134
disk_size_gb: 110
3235
disk_type: pd-standard
3336
service_account_email: test-unpriv-clusterfuzz-service-account-email
34-
subnetwork: null
37+
gce_region: 'gce-region'
3538
gce_zone: 'gce-zone'
39+
network: 'projects/google.com:clusterfuzz/global/networks/networkname'
40+
subnetwork: 'projects/google.com:clusterfuzz/regions/gce-region/subnetworks/subnetworkname'
3641
preemptible: false
3742
machine_type: n1-standard-1
3843
LINUX-PREEMPTIBLE:
@@ -42,8 +47,10 @@ mapping:
4247
disk_size_gb: 75
4348
disk_type: pd-standard
4449
service_account_email: test-clusterfuzz-service-account-email
45-
subnetwork: null
50+
gce_region: 'gce-region'
4651
gce_zone: 'gce-zone'
52+
network: 'projects/google.com:clusterfuzz/global/networks/networkname'
53+
subnetwork: 'projects/google.com:clusterfuzz/regions/gce-region/subnetworks/subnetworkname'
4754
preemptible: true
4855
machine_type: n1-standard-1
4956
LINUX-PREEMPTIBLE-UNPRIVILEGED:
@@ -53,8 +60,10 @@ mapping:
5360
disk_size_gb: 75
5461
disk_type: pd-standard
5562
service_account_email: test-unpriv-clusterfuzz-service-account-email
56-
subnetwork: null
63+
gce_region: 'gce-region'
5764
gce_zone: 'gce-zone'
65+
network: 'projects/google.com:clusterfuzz/global/networks/networkname'
66+
subnetwork: 'projects/google.com:clusterfuzz/regions/gce-region/subnetworks/subnetworkname'
5867
preemptible: true
5968
machine_type: n1-standard-1
6069
project: 'test-clusterfuzz'

src/clusterfuzz/_internal/base/tasks/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,6 @@ def get_task_from_message(message) -> Optional[PubSubTask]:
497497
def get_utask_mains() -> List[PubSubTask]:
498498
"""Returns a list of tasks for preprocessing many utasks on this bot and then
499499
running the uworker_mains in the same batch job."""
500-
if not task_utils.is_remotely_executing_utasks():
501-
return None
502500
pubsub_puller = PubSubPuller(UTASK_MAINS_QUEUE)
503501
messages = pubsub_puller.get_messages_time_limited(MAX_UTASKS,
504502
UTASK_QUEUE_PULL_SECONDS)

src/clusterfuzz/_internal/base/tasks/task_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ def is_remotely_executing_utasks(task=None) -> bool:
4040
def is_task_opted_into_uworker_execution(task):
4141
# TODO(metzman): Remove this after OSS-Fuzz and Chrome are at parity.
4242
uworker_tasks = local_config.ProjectConfig().get('uworker_tasks', [])
43+
if 'skia' not in environment.get_value('JOB_NAME', ''):
44+
# This is just for testing OSS-Fuzz.
45+
return False
4346
return task in uworker_tasks
4447

4548

src/clusterfuzz/_internal/google_cloud_utils/batch.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,9 @@
4646
MAX_CONCURRENT_VMS_PER_JOB = 1000
4747

4848
BatchWorkloadSpec = collections.namedtuple('BatchWorkloadSpec', [
49-
'clusterfuzz_release',
50-
'disk_size_gb',
51-
'disk_type',
52-
'docker_image',
53-
'user_data',
54-
'service_account_email',
55-
'subnetwork',
56-
'preemptible',
57-
'project',
58-
'gce_zone',
59-
'machine_type',
49+
'clusterfuzz_release', 'disk_size_gb', 'disk_type', 'docker_image',
50+
'user_data', 'service_account_email', 'subnetwork', 'preemptible',
51+
'project', 'gce_zone', 'machine_type', 'network', 'gce_region'
6052
])
6153

6254

@@ -166,7 +158,6 @@ def _get_task_spec(batch_workload_spec):
166158
task_spec = batch.TaskSpec()
167159
task_spec.runnables = [runnable]
168160
task_spec.max_retry_count = RETRY_COUNT
169-
# TODO(metzman): Change this for production.
170161
task_spec.max_run_duration = MAX_DURATION
171162
return task_spec
172163

@@ -187,12 +178,8 @@ def _get_allocation_policy(spec):
187178
# unnecessary.
188179
network_interface = batch.AllocationPolicy.NetworkInterface()
189180
network_interface.no_external_ip_address = True
190-
# TODO(metzman): Make configurable.
191-
network_interface.network = (
192-
'projects/google.com:clusterfuzz/global/networks/batch')
193-
network_interface.subnetwork = (
194-
'projects/google.com:clusterfuzz/regions/us-west1/subnetworks/us-west1a')
195-
181+
network_interface.network = spec.network
182+
network_interface.subnetwork = spec.subnetwork
196183
network_interfaces = [network_interface]
197184
network_policy = batch.AllocationPolicy.NetworkPolicy()
198185
network_policy.network_interfaces = network_interfaces
@@ -231,8 +218,9 @@ def _create_job(spec, input_urls):
231218
job_name = get_job_name()
232219
create_request.job_id = job_name
233220
# The job's parent is the region in which the job will run
234-
project_id = 'google.com:clusterfuzz'
235-
create_request.parent = f'projects/{project_id}/locations/us-west1'
221+
project_id = spec.project
222+
create_request.parent = (
223+
f'projects/{project_id}/locations/{spec.gce_region}')
236224
job_result = _send_create_job_request(create_request)
237225
logs.info(f'Created batch job id={job_name}.', spec=spec)
238226
return job_result
@@ -269,14 +257,26 @@ def is_remote_task(command, job_name):
269257
return False
270258

271259

272-
def _get_spec_from_config(command, job_name):
273-
"""Gets the configured specifications for a batch workload."""
260+
def _get_config_name(command, job_name):
261+
"""Returns the name of the config for |command| and |job_name|."""
274262
job = _get_job(job_name)
275-
config_name = job.platform
263+
# As of this writing, batch only supports LINUX.
264+
if utils.is_oss_fuzz():
265+
# TODO(b/377885331): In OSS-Fuzz, the platform can't be used because, as of
266+
# it includes the project name.
267+
config_name = 'LINUX'
268+
else:
269+
config_name = job.platform
276270
if command == 'fuzz':
277271
config_name += '-PREEMPTIBLE-UNPRIVILEGED'
278272
else:
279273
config_name += '-NONPREEMPTIBLE-UNPRIVILEGED'
274+
return config_name
275+
276+
277+
def _get_spec_from_config(command, job_name):
278+
"""Gets the configured specifications for a batch workload."""
279+
config_name = _get_config_name(command, job_name)
280280
batch_config = _get_batch_config()
281281
instance_spec = batch_config.get('mapping').get(config_name, None)
282282
if instance_spec is None:
@@ -285,18 +285,18 @@ def _get_spec_from_config(command, job_name):
285285
docker_image = instance_spec['docker_image']
286286
user_data = instance_spec['user_data']
287287
clusterfuzz_release = instance_spec.get('clusterfuzz_release', 'prod')
288-
# TODO(https://github.com/google/clusterfuzz/issues/3008): Make this use a
289-
# low-privilege account.
290288
spec = BatchWorkloadSpec(
291289
clusterfuzz_release=clusterfuzz_release,
292290
docker_image=docker_image,
293291
user_data=user_data,
294292
disk_size_gb=instance_spec['disk_size_gb'],
295293
disk_type=instance_spec['disk_type'],
296294
service_account_email=instance_spec['service_account_email'],
297-
subnetwork=instance_spec['subnetwork'],
298295
gce_zone=instance_spec['gce_zone'],
296+
gce_region=instance_spec['gce_region'],
299297
project=project_name,
298+
network=instance_spec['network'],
299+
subnetwork=instance_spec['subnetwork'],
300300
preemptible=instance_spec['preemptible'],
301301
machine_type=instance_spec['machine_type'])
302302
return spec

src/clusterfuzz/_internal/system/shell.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ def clear_temp_directory(clear_user_profile_directories=True):
176176
@environment.local_noop
177177
def clear_system_temp_directory():
178178
"""Clear system specific temp directory."""
179+
if environment.get_value('DEBUG_TASK'):
180+
return
179181

180182
def _delete_object(path, delete_func):
181183
"""Delete a object with its delete function, ignoring any error."""

src/clusterfuzz/_internal/tests/core/base/tasks/task_utils_test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
"""Tests for task_utils."""
15+
import os
1516
import unittest
1617

1718
from clusterfuzz._internal.base.tasks import task_utils
1819
from clusterfuzz._internal.bot.tasks import commands
20+
from clusterfuzz._internal.tests.test_libs import helpers
1921

2022

2123
class GetCommandFromModuleTest(unittest.TestCase):
@@ -36,9 +38,20 @@ def test_get_command_from_module(self):
3638

3739

3840
class IsTaskOptedIntoUworkerExecution(unittest.TestCase):
41+
"""Tests that is_task_opted_into_uworker_execution only returns True for the
42+
tasks we are testing in oss-fuzz."""
43+
44+
def setUp(self):
45+
helpers.patch_environ(self)
3946

4047
def test_opt_in(self):
48+
os.environ['JOB_NAME'] = 'libfuzzer_asan_skia'
4149
self.assertTrue(task_utils.is_task_opted_into_uworker_execution('analyze'))
4250

51+
def test_wrong_job(self):
52+
os.environ['JOB_NAME'] = 'libfuzzer_asan_systemd'
53+
self.assertFalse(task_utils.is_task_opted_into_uworker_execution('analyze'))
54+
4355
def test_no_opt_in(self):
56+
os.environ['JOB_NAME'] = 'libfuzzer_asan_skia'
4457
self.assertFalse(task_utils.is_task_opted_into_uworker_execution('fuzz'))

src/clusterfuzz/_internal/tests/core/google_cloud_utils/batch_test.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ def test_nonpreemptible_get_spec_from_config(self):
4040
disk_size_gb=110,
4141
disk_type='pd-standard',
4242
service_account_email='test-unpriv-clusterfuzz-service-account-email',
43-
subnetwork=None,
43+
subnetwork=
44+
'projects/google.com:clusterfuzz/regions/gce-region/subnetworks/subnetworkname',
45+
network='projects/google.com:clusterfuzz/global/networks/networkname',
46+
gce_region='gce-region',
4447
gce_zone='gce-zone',
4548
project='test-clusterfuzz',
4649
preemptible=False,
@@ -60,8 +63,11 @@ def test_preemptible_get_spec_from_config(self):
6063
disk_size_gb=75,
6164
disk_type='pd-standard',
6265
service_account_email='test-unpriv-clusterfuzz-service-account-email',
63-
subnetwork=None,
66+
subnetwork=
67+
'projects/google.com:clusterfuzz/regions/gce-region/subnetworks/subnetworkname',
68+
network='projects/google.com:clusterfuzz/global/networks/networkname',
6469
gce_zone='gce-zone',
70+
gce_region='gce-region',
6571
project='test-clusterfuzz',
6672
preemptible=True,
6773
machine_type='n1-standard-1')

src/python/bot/startup/run_bot.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ def schedule_utask_mains():
9696

9797
logs.info(f'Combining {len(utask_mains)} batch tasks.')
9898

99-
batch_tasks = []
10099
with lease_all_tasks(utask_mains):
101100
batch_tasks = [
102101
batch.BatchTask(task.command, task.job, task.argument)

0 commit comments

Comments
 (0)