Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 1822acf

Browse files
authored
add onefuzz jobs containers delete JOB_ID (#949)
Addresses #943
1 parent a92c84d commit 1822acf

File tree

4 files changed

+103
-74
lines changed

4 files changed

+103
-74
lines changed

src/cli/onefuzz/api.py

+88
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,61 @@ def list(
970970
results[container] = self.onefuzz.containers.files.list(container).files
971971
return results
972972

973+
def delete(
974+
self,
975+
job_id: UUID_EXPANSION,
976+
*,
977+
only_job_specific: bool = True,
978+
dryrun: bool = False,
979+
) -> None:
980+
SAFE_TO_REMOVE = [
981+
enums.ContainerType.crashes,
982+
enums.ContainerType.setup,
983+
enums.ContainerType.inputs,
984+
enums.ContainerType.reports,
985+
enums.ContainerType.unique_inputs,
986+
enums.ContainerType.unique_reports,
987+
enums.ContainerType.no_repro,
988+
enums.ContainerType.analysis,
989+
enums.ContainerType.coverage,
990+
enums.ContainerType.readonly_inputs,
991+
enums.ContainerType.regression_reports,
992+
]
993+
994+
job = self.onefuzz.jobs.get(job_id)
995+
containers = set()
996+
to_delete = set()
997+
for task in self.onefuzz.jobs.tasks.list(job_id=job.job_id):
998+
for container in task.config.containers:
999+
containers.add(container.name)
1000+
if container.type not in SAFE_TO_REMOVE:
1001+
continue
1002+
elif not only_job_specific:
1003+
to_delete.add(container.name)
1004+
elif only_job_specific and (
1005+
self.onefuzz.utils.build_container_name(
1006+
container_type=container.type,
1007+
project=job.config.project,
1008+
name=job.config.name,
1009+
build=job.config.build,
1010+
platform=task.os,
1011+
)
1012+
== container.name
1013+
):
1014+
to_delete.add(container.name)
1015+
1016+
to_keep = containers - to_delete
1017+
for container_name in to_keep:
1018+
self.logger.info("not removing: %s", container_name)
1019+
1020+
for container_name in to_delete:
1021+
if dryrun:
1022+
self.logger.info("container would be deleted: %s", container_name)
1023+
elif self.onefuzz.containers.delete(container_name).result:
1024+
self.logger.info("removed container: %s", container_name)
1025+
else:
1026+
self.logger.info("container already removed: %s", container_name)
1027+
9731028

9741029
class JobTasks(Endpoint):
9751030
"""Interact with tasks within a job"""
@@ -1495,6 +1550,39 @@ def namespaced_guid(
14951550
identifiers.append(platform)
14961551
return uuid.uuid5(ONEFUZZ_GUID_NAMESPACE, ":".join(identifiers))
14971552

1553+
def build_container_name(
1554+
self,
1555+
*,
1556+
container_type: enums.ContainerType,
1557+
project: str,
1558+
name: str,
1559+
build: str,
1560+
platform: enums.OS,
1561+
) -> primitives.Container:
1562+
if container_type in [enums.ContainerType.setup, enums.ContainerType.coverage]:
1563+
guid = self.namespaced_guid(
1564+
project,
1565+
name,
1566+
build=build,
1567+
platform=platform.name,
1568+
)
1569+
elif container_type == enums.ContainerType.regression_reports:
1570+
guid = self.namespaced_guid(
1571+
project,
1572+
name,
1573+
build=build,
1574+
)
1575+
else:
1576+
guid = self.namespaced_guid(project, name)
1577+
1578+
return primitives.Container(
1579+
"oft-%s-%s"
1580+
% (
1581+
container_type.name.replace("_", "-"),
1582+
guid.hex,
1583+
)
1584+
)
1585+
14981586

14991587
class Onefuzz:
15001588
def __init__(

src/cli/onefuzz/job_templates/handlers.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from onefuzztypes.models import Job, TaskContainers
1212

1313
from ..api import Endpoint
14-
from ..templates import _build_container_name
1514
from .job_monitor import JobMonitor
1615

1716

@@ -75,13 +74,12 @@ def _define_missing_containers(
7574
raise TypeError
7675
if not isinstance(request.user_fields["build"], str):
7776
raise TypeError
78-
container_name = _build_container_name(
79-
self.onefuzz,
80-
container_type,
81-
request.user_fields["project"],
82-
request.user_fields["name"],
83-
request.user_fields["build"],
84-
config.os,
77+
container_name = self.onefuzz.utils.build_container_name(
78+
container_type=container_type,
79+
project=request.user_fields["project"],
80+
name=request.user_fields["name"],
81+
build=request.user_fields["build"],
82+
platform=config.os,
8583
)
8684
request.containers.append(
8785
TaskContainers(name=container_name, type=container_type)

src/cli/onefuzz/template.py

+3-26
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
import logging
77
from typing import Optional
88

9-
from onefuzztypes.enums import ContainerType
10-
119
from .api import Command, Onefuzz
1210
from .templates.afl import AFL
1311
from .templates.libfuzzer import Libfuzzer
@@ -35,19 +33,6 @@ def stop(
3533
delete_containers: bool = False,
3634
stop_notifications: bool = False,
3735
) -> None:
38-
SAFE_TO_REMOVE = [
39-
ContainerType.crashes,
40-
ContainerType.setup,
41-
ContainerType.inputs,
42-
ContainerType.reports,
43-
ContainerType.unique_inputs,
44-
ContainerType.unique_reports,
45-
ContainerType.no_repro,
46-
ContainerType.analysis,
47-
ContainerType.coverage,
48-
ContainerType.readonly_inputs,
49-
]
50-
5136
msg = ["project:%s" % project, "name:%s" % name]
5237
if build is not None:
5338
msg.append("build:%s" % build)
@@ -68,23 +53,15 @@ def stop(
6853
self.logger.info("stopping job: %s", job.job_id)
6954
self.onefuzz.jobs.delete(job.job_id)
7055

56+
if delete_containers:
57+
self.onefuzz.jobs.containers.delete(job.job_id)
58+
7159
tasks = self.onefuzz.tasks.list(job_id=job.job_id)
7260
for task in tasks:
7361
if task.state not in ["stopped"]:
7462
self.logger.info("stopping task: %s", task.task_id)
7563
self.onefuzz.tasks.delete(task.task_id)
7664

77-
if delete_containers:
78-
to_remove = []
79-
for container in task.config.containers:
80-
if container.type not in SAFE_TO_REMOVE:
81-
self.logger.info("not removing: %s", container)
82-
continue
83-
to_remove.append(container.name)
84-
for container_name in to_remove:
85-
if self.onefuzz.containers.delete(container_name).result:
86-
self.logger.info("removed container: %s", container_name)
87-
8865
if stop_notifications:
8966
notifications = self.onefuzz.notifications.list()
9067
for container in task.config.containers:

src/cli/onefuzz/templates/__init__.py

+6-40
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,6 @@ class StoppedEarly(Exception):
2525
pass
2626

2727

28-
def _build_container_name(
29-
onefuzz: "Onefuzz",
30-
container_type: ContainerType,
31-
project: str,
32-
name: str,
33-
build: str,
34-
platform: OS,
35-
) -> Container:
36-
if container_type in [ContainerType.setup, ContainerType.coverage]:
37-
guid = onefuzz.utils.namespaced_guid(
38-
project,
39-
name,
40-
build=build,
41-
platform=platform.name,
42-
)
43-
elif container_type == ContainerType.regression_reports:
44-
guid = onefuzz.utils.namespaced_guid(
45-
project,
46-
name,
47-
build=build,
48-
)
49-
else:
50-
guid = onefuzz.utils.namespaced_guid(project, name)
51-
52-
return Container(
53-
"oft-%s-%s"
54-
% (
55-
container_type.name.replace("_", "-"),
56-
guid.hex,
57-
)
58-
)
59-
60-
6128
class JobHelper:
6229
def __init__(
6330
self,
@@ -115,13 +82,12 @@ def define_containers(self, *types: ContainerType) -> None:
11582
"""
11683

11784
for container_type in types:
118-
self.containers[container_type] = _build_container_name(
119-
self.onefuzz,
120-
container_type,
121-
self.project,
122-
self.name,
123-
self.build,
124-
self.platform,
85+
self.containers[container_type] = self.onefuzz.utils.build_container_name(
86+
container_type=container_type,
87+
project=self.project,
88+
name=self.name,
89+
build=self.build,
90+
platform=self.platform,
12591
)
12692

12793
def get_unique_container_name(self, container_type: ContainerType) -> Container:

0 commit comments

Comments
 (0)