mirror of
https://github.com/quay/quay.git
synced 2026-01-26 06:21:37 +03:00
Make sure the build token doesn't expire before the builder instance does. Set the expiration to the builder instances' max expiration.
95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
from abc import ABC, abstractmethod
|
|
|
|
from data.database import BUILD_PHASE
|
|
|
|
|
|
class BuildJobError(Exception):
|
|
"""Base error for build jobs."""
|
|
|
|
|
|
class BuildJobAlreadyExistsError(BuildJobError):
|
|
"""Raised when trying to create a job that already exists."""
|
|
|
|
|
|
class BuildJobDoesNotExistsError(BuildJobError):
|
|
"""Raised when trying to delete a job that does not exists."""
|
|
|
|
|
|
class BuildJobExpiredError(BuildJobError):
|
|
"""Raised when trying to update a job that has already expired."""
|
|
|
|
|
|
class BuildJobResult(object):
|
|
"""
|
|
Build job result enum.
|
|
"""
|
|
|
|
ERROR = "error"
|
|
EXPIRED = "expired"
|
|
COMPLETE = "complete"
|
|
INCOMPLETE = "incomplete"
|
|
CANCELLED = "cancelled"
|
|
|
|
|
|
RESULT_PHASES = {
|
|
BuildJobResult.ERROR: BUILD_PHASE.ERROR,
|
|
BuildJobResult.EXPIRED: BUILD_PHASE.INTERNAL_ERROR,
|
|
BuildJobResult.COMPLETE: BUILD_PHASE.COMPLETE,
|
|
BuildJobResult.INCOMPLETE: BUILD_PHASE.INTERNAL_ERROR,
|
|
BuildJobResult.CANCELLED: BUILD_PHASE.CANCELLED,
|
|
}
|
|
|
|
|
|
class BuildStateInterface(ABC):
|
|
@abstractmethod
|
|
def create_job(self, build_id, build_metadata):
|
|
"""Creates a new job for a build. Raises an error if the job already exists.
|
|
Otherwise, returns a job_id. The job should get expired if the job is not scheduled within
|
|
a time frame.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def job_scheduled(self, job_id, execution_id, max_startup_time):
|
|
"""Mark the job as scheduled with execution_id. If the job is not started after
|
|
max_startup_time, the job should get expired.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def job_unschedulable(self, job_id):
|
|
"""Delete job from state tracking. Called when unable to schedule the job.
|
|
Raises BuildJobError if already called when the job has been successfully scheduled.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def on_job_complete(self, build_job, job_result, executor_name, execution_id):
|
|
"""Invoke the callback to clean up the build execution:
|
|
- Update the build phase
|
|
- Set the final build job state: complete, cancelled, user_error, internal_error, cancelled
|
|
- Clean up any resources used to execute the build: ec2 instances, k8s jobs, ...
|
|
Returns False if there is an error, and should be tried again.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def start_job(self, job_id):
|
|
"""Mark a job as started.
|
|
Returns False if the job does not exists, or has already started.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def update_job_phase(self, job_id, phase):
|
|
"""Update the given job phase.
|
|
Returns False if the given job does not exists or the job has been cancelled.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def job_heartbeat(self, job_id):
|
|
"""Sends a heartbeat to a job, extending its expiration time.
|
|
Returns True if the given job exists and its expiration was updated, False otherwise.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def cancel_build(self, build_id):
|
|
"""
|
|
Cancels the given build.
|
|
"""
|