Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e6df1be
feat: Implement Kubernetes job client and service
javanlacerda Dec 24, 2025
e8046ed
pipenv lock
javanlacerda Dec 24, 2025
d3f651b
use utask main test
javanlacerda Dec 26, 2025
124209c
decrease max utasks
javanlacerda Dec 26, 2025
7bc7ba7
install kubernetes
javanlacerda Dec 27, 2025
0969aa3
enable kubernetes
javanlacerda Dec 27, 2025
27463b4
refresh
javanlacerda Dec 27, 2025
fcabf0d
fix k8s auth
javanlacerda Dec 27, 2025
d7ef00e
fix
javanlacerda Dec 28, 2025
1d79ead
raise max_utasks
javanlacerda Dec 28, 2025
371966a
moving fuzz to remote task
javanlacerda Dec 29, 2025
3983041
Make utask remote
javanlacerda Dec 29, 2025
e38e476
set fuzz as Utask
javanlacerda Dec 29, 2025
1b7bd74
utask_main
javanlacerda Dec 29, 2025
945e9e7
fix is k8s
javanlacerda Dec 29, 2025
14a163a
raise k8s
javanlacerda Dec 30, 2025
760391d
set k8s as 50%
javanlacerda Dec 30, 2025
20f4d4c
fix k8s log
javanlacerda Dec 30, 2025
1fed463
k8s job limit
javanlacerda Dec 31, 2025
3aea82a
job limiter
javanlacerda Dec 31, 2025
3885ad3
update web tests false
javanlacerda Jan 1, 2026
9b3f5f4
pending pods instead jobs
javanlacerda Jan 1, 2026
bd4e9d9
create service account
javanlacerda Jan 1, 2026
da1ca94
100% k8s
javanlacerda Jan 1, 2026
09764d0
set active deadline
javanlacerda Jan 2, 2026
7dd0b7e
50% batch 50% k8s
javanlacerda Jan 2, 2026
0f55b8b
raise pending
javanlacerda Jan 2, 2026
902c0a8
emit runtime for crashes
javanlacerda Jan 5, 2026
8ba8817
feature flag
javanlacerda Jan 8, 2026
2b3d10c
fix enabled feature glag
javanlacerda Jan 8, 2026
153e33f
get rid per job aggregation
javanlacerda Jan 8, 2026
842f3e5
set k8s as 0 by default
javanlacerda Jan 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/kubernetes-e2e-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Run Kubernetes e2e tests
on: [pull_request]

permissions: read-all

jobs:
build:
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v3
- run: | # Needed for git diff to work.
git fetch origin master --depth 1
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/master

- name: Setup python environment
uses: actions/setup-python@b55428b1882923874294fa556849718a1d7f2ca5
with:
python-version: 3.11

- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'

- name: Run Kubernetes e2e tests
run: ./local/tests/kubernetes_e2e_test.bash
13 changes: 13 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ future = "==0.17.1"
protobuf = "==4.23.4"
psutil = "==5.9.4"
google-cloud-ndb = "==2.3.4"
kubernetes = "==34.1.0"
google-api-python-client = "==2.93.0"
aiohttp = "==3.10.5"
google-cloud-storage = "==2.10.0"
google-cloud-secret-manager = "==2.17.0"
google-cloud-logging = "==3.6.0"
google-cloud-monitoring = "==2.15.1"
google-cloud-datastore = "==2.16.1"
oauth2client = "==4.1.3"
requests = "==2.21.0"
PyYAML = "==6.0"
httplib2 = "==0.19.0"
google-auth-oauthlib = "==0.4.1"

[dev-packages]
Fabric = "==1.14.1"
Expand Down
1,985 changes: 1,449 additions & 536 deletions Pipfile.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions butler.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@ def main():
parser_clean_indexes.add_argument(
'-c', '--config-dir', required=True, help='Path to application config.')

parser_clean_jobs = subparsers.add_parser(
'clean_jobs', help='Clean up pending kubernetes jobs.')
parser_clean_jobs.add_argument(
'-c', '--config-dir', required=True, help='Path to application config.')

parser_create_config = subparsers.add_parser(
'create_config', help='Create a new deployment config.')
parser_create_config.add_argument(
Expand Down
24 changes: 13 additions & 11 deletions ...clusterfuzz/_internal/batch/kubernetes.py → local/tests/kubernetes_e2e_test.bash
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/bash -ex
#
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -11,17 +13,17 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Kubernetes batch client."""
from clusterfuzz._internal.remote_task import RemoteTaskInterface

# This script is for running the Kubernetes end-to-end test in CI.

pip install pipenv

# Install dependencies.
pipenv --python 3.11
pipenv install

class KubernetesJobClient(RemoteTaskInterface):
"""A remote task execution client for Kubernetes.

This class is a placeholder for a future implementation of a remote task
execution client that uses Kubernetes. It is not yet implemented.
"""
./local/install_deps.bash

def create_job(self, spec, input_urls):
"""Creates a Kubernetes job."""
raise NotImplementedError('Kubernetes batch client is not implemented yet.')
# Run the test.
export K8S_E2E=1
pipenv run python butler.py py_unittest -t core -p k8s_service_e2e_test.py
7 changes: 7 additions & 0 deletions out.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Running in dry-run mode, no datastore writes are committed. For permanent modifications, re-run with --non-dry-run.
Attempting to combine batch tasks.
Combining 2901 batch tasks.
K8s result: ['libfuzzer-chrome-asan-debug-7ca9c46f']

Please remember to run the migration individually on all projects.

3 changes: 2 additions & 1 deletion src/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ google-crc32c = "==1.5.0"
grpcio = "==1.62.2"
httplib2 = "==0.19.0"
jira = "==2.0.0"
kubernetes = "==34.1.0"
mozprocess = "==1.3.1"
oauth2client = "==4.1.3"
psutil = "==5.9.4"
protobuf = "==4.23.4"
pygithub = "==1.55"
pyOpenSSL = "==22.0.0"
python-dateutil = "==2.8.1"
PyYAML = "==6.0"
PyYAML = "==6.0.1"
pytz = "==2023.3"
redis = "==4.6.0"
requests = "==2.21.0"
Expand Down
1,624 changes: 951 additions & 673 deletions src/Pipfile.lock

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions src/clusterfuzz/_internal/base/tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@
'regression': 24 * 60 * 60,
}


def get_task_duration(command):
"""Gets the duration of a task."""
return TASK_LEASE_SECONDS_BY_COMMAND.get(command, TASK_LEASE_SECONDS)


TASK_QUEUE_DISPLAY_NAMES = {
'LINUX': 'Linux',
'LINUX_WITH_GPU': 'Linux (with GPU)',
Expand Down Expand Up @@ -503,6 +509,7 @@ def __init__(self, pubsub_message):
}

self.eta = datetime.datetime.utcfromtimestamp(float(self.attribute('eta')))
self.do_not_ack = False

def attribute(self, key):
"""Return attribute value."""
Expand Down Expand Up @@ -550,7 +557,8 @@ def lease(self, _event=None): # pylint: disable=arguments-differ
leaser_thread.join()

# If we get here the task succeeded in running. Acknowledge the message.
self._pubsub_message.ack()
if not self.do_not_ack:
self._pubsub_message.ack()
track_task_end()

def dont_retry(self):
Expand Down Expand Up @@ -587,7 +595,8 @@ def lease(self, _event=None): # pylint: disable=arguments-differ
leaser_thread.join()

# If we get here the task succeeded in running. Acknowledge the message.
self._pubsub_message.ack()
if not self.do_not_ack:
self._pubsub_message.ack()
track_task_end()


Expand Down
50 changes: 0 additions & 50 deletions src/clusterfuzz/_internal/batch/data_structures.py

This file was deleted.

Loading
Loading