add onefuzz jobs containers delete JOB_ID (#949)

Addresses #943
This commit is contained in:
bmc-msft
2021-06-02 13:04:51 -04:00
committed by GitHub
parent a92c84d42a
commit 1822acf943
4 changed files with 103 additions and 74 deletions

View File

@ -970,6 +970,61 @@ class JobContainers(Endpoint):
results[container] = self.onefuzz.containers.files.list(container).files results[container] = self.onefuzz.containers.files.list(container).files
return results return results
def delete(
self,
job_id: UUID_EXPANSION,
*,
only_job_specific: bool = True,
dryrun: bool = False,
) -> None:
SAFE_TO_REMOVE = [
enums.ContainerType.crashes,
enums.ContainerType.setup,
enums.ContainerType.inputs,
enums.ContainerType.reports,
enums.ContainerType.unique_inputs,
enums.ContainerType.unique_reports,
enums.ContainerType.no_repro,
enums.ContainerType.analysis,
enums.ContainerType.coverage,
enums.ContainerType.readonly_inputs,
enums.ContainerType.regression_reports,
]
job = self.onefuzz.jobs.get(job_id)
containers = set()
to_delete = set()
for task in self.onefuzz.jobs.tasks.list(job_id=job.job_id):
for container in task.config.containers:
containers.add(container.name)
if container.type not in SAFE_TO_REMOVE:
continue
elif not only_job_specific:
to_delete.add(container.name)
elif only_job_specific and (
self.onefuzz.utils.build_container_name(
container_type=container.type,
project=job.config.project,
name=job.config.name,
build=job.config.build,
platform=task.os,
)
== container.name
):
to_delete.add(container.name)
to_keep = containers - to_delete
for container_name in to_keep:
self.logger.info("not removing: %s", container_name)
for container_name in to_delete:
if dryrun:
self.logger.info("container would be deleted: %s", container_name)
elif self.onefuzz.containers.delete(container_name).result:
self.logger.info("removed container: %s", container_name)
else:
self.logger.info("container already removed: %s", container_name)
class JobTasks(Endpoint): class JobTasks(Endpoint):
"""Interact with tasks within a job""" """Interact with tasks within a job"""
@ -1495,6 +1550,39 @@ class Utils(Command):
identifiers.append(platform) identifiers.append(platform)
return uuid.uuid5(ONEFUZZ_GUID_NAMESPACE, ":".join(identifiers)) return uuid.uuid5(ONEFUZZ_GUID_NAMESPACE, ":".join(identifiers))
def build_container_name(
self,
*,
container_type: enums.ContainerType,
project: str,
name: str,
build: str,
platform: enums.OS,
) -> primitives.Container:
if container_type in [enums.ContainerType.setup, enums.ContainerType.coverage]:
guid = self.namespaced_guid(
project,
name,
build=build,
platform=platform.name,
)
elif container_type == enums.ContainerType.regression_reports:
guid = self.namespaced_guid(
project,
name,
build=build,
)
else:
guid = self.namespaced_guid(project, name)
return primitives.Container(
"oft-%s-%s"
% (
container_type.name.replace("_", "-"),
guid.hex,
)
)
class Onefuzz: class Onefuzz:
def __init__( def __init__(

View File

@ -11,7 +11,6 @@ from onefuzztypes.job_templates import JobTemplateConfig, JobTemplateRequest
from onefuzztypes.models import Job, TaskContainers from onefuzztypes.models import Job, TaskContainers
from ..api import Endpoint from ..api import Endpoint
from ..templates import _build_container_name
from .job_monitor import JobMonitor from .job_monitor import JobMonitor
@ -75,13 +74,12 @@ class TemplateSubmitHandler(Endpoint):
raise TypeError raise TypeError
if not isinstance(request.user_fields["build"], str): if not isinstance(request.user_fields["build"], str):
raise TypeError raise TypeError
container_name = _build_container_name( container_name = self.onefuzz.utils.build_container_name(
self.onefuzz, container_type=container_type,
container_type, project=request.user_fields["project"],
request.user_fields["project"], name=request.user_fields["name"],
request.user_fields["name"], build=request.user_fields["build"],
request.user_fields["build"], platform=config.os,
config.os,
) )
request.containers.append( request.containers.append(
TaskContainers(name=container_name, type=container_type) TaskContainers(name=container_name, type=container_type)

View File

@ -6,8 +6,6 @@
import logging import logging
from typing import Optional from typing import Optional
from onefuzztypes.enums import ContainerType
from .api import Command, Onefuzz from .api import Command, Onefuzz
from .templates.afl import AFL from .templates.afl import AFL
from .templates.libfuzzer import Libfuzzer from .templates.libfuzzer import Libfuzzer
@ -35,19 +33,6 @@ class Template(Command):
delete_containers: bool = False, delete_containers: bool = False,
stop_notifications: bool = False, stop_notifications: bool = False,
) -> None: ) -> None:
SAFE_TO_REMOVE = [
ContainerType.crashes,
ContainerType.setup,
ContainerType.inputs,
ContainerType.reports,
ContainerType.unique_inputs,
ContainerType.unique_reports,
ContainerType.no_repro,
ContainerType.analysis,
ContainerType.coverage,
ContainerType.readonly_inputs,
]
msg = ["project:%s" % project, "name:%s" % name] msg = ["project:%s" % project, "name:%s" % name]
if build is not None: if build is not None:
msg.append("build:%s" % build) msg.append("build:%s" % build)
@ -68,23 +53,15 @@ class Template(Command):
self.logger.info("stopping job: %s", job.job_id) self.logger.info("stopping job: %s", job.job_id)
self.onefuzz.jobs.delete(job.job_id) self.onefuzz.jobs.delete(job.job_id)
if delete_containers:
self.onefuzz.jobs.containers.delete(job.job_id)
tasks = self.onefuzz.tasks.list(job_id=job.job_id) tasks = self.onefuzz.tasks.list(job_id=job.job_id)
for task in tasks: for task in tasks:
if task.state not in ["stopped"]: if task.state not in ["stopped"]:
self.logger.info("stopping task: %s", task.task_id) self.logger.info("stopping task: %s", task.task_id)
self.onefuzz.tasks.delete(task.task_id) self.onefuzz.tasks.delete(task.task_id)
if delete_containers:
to_remove = []
for container in task.config.containers:
if container.type not in SAFE_TO_REMOVE:
self.logger.info("not removing: %s", container)
continue
to_remove.append(container.name)
for container_name in to_remove:
if self.onefuzz.containers.delete(container_name).result:
self.logger.info("removed container: %s", container_name)
if stop_notifications: if stop_notifications:
notifications = self.onefuzz.notifications.list() notifications = self.onefuzz.notifications.list()
for container in task.config.containers: for container in task.config.containers:

View File

@ -25,39 +25,6 @@ class StoppedEarly(Exception):
pass pass
def _build_container_name(
onefuzz: "Onefuzz",
container_type: ContainerType,
project: str,
name: str,
build: str,
platform: OS,
) -> Container:
if container_type in [ContainerType.setup, ContainerType.coverage]:
guid = onefuzz.utils.namespaced_guid(
project,
name,
build=build,
platform=platform.name,
)
elif container_type == ContainerType.regression_reports:
guid = onefuzz.utils.namespaced_guid(
project,
name,
build=build,
)
else:
guid = onefuzz.utils.namespaced_guid(project, name)
return Container(
"oft-%s-%s"
% (
container_type.name.replace("_", "-"),
guid.hex,
)
)
class JobHelper: class JobHelper:
def __init__( def __init__(
self, self,
@ -115,13 +82,12 @@ class JobHelper:
""" """
for container_type in types: for container_type in types:
self.containers[container_type] = _build_container_name( self.containers[container_type] = self.onefuzz.utils.build_container_name(
self.onefuzz, container_type=container_type,
container_type, project=self.project,
self.project, name=self.name,
self.name, build=self.build,
self.build, platform=self.platform,
self.platform,
) )
def get_unique_container_name(self, container_type: ContainerType) -> Container: def get_unique_container_name(self, container_type: ContainerType) -> Container: