mirror of
https://gitlab.com/itsulu-odoo/runboat.git
synced 2026-05-30 23:41:27 +00:00
Add start and stop deployment modes
Apply patches before start and after stop. This is useful to bring up / tear down additional resources.
This commit is contained in:
parent
d2b90e5368
commit
4412618307
3 changed files with 49 additions and 11 deletions
16
README.md
16
README.md
|
|
@ -104,15 +104,21 @@ kubernetes cluster, or even a different one, depending on your taste.
|
||||||
|
|
||||||
All resources to be deployed in kubernetes for a build are in
|
All resources to be deployed in kubernetes for a build are in
|
||||||
[src/runboat/kubefiles](./src/runboat/kubefiles). They are gathered together from a
|
[src/runboat/kubefiles](./src/runboat/kubefiles). They are gathered together from a
|
||||||
`kustomization.yaml` jinja template that leads to three possible resource groups
|
`kustomization.yaml` jinja template that leads to 5 possible resource groups
|
||||||
depending on a `mode` variable in the jinja rendering context:
|
depending on a `mode` variable in the jinja rendering context:
|
||||||
|
|
||||||
- `deployment` creates a kubernetes deployment with its associated resources (pvc,
|
- `deployment` creates a kubernetes deployment with its associated resources (pvc,
|
||||||
service, ingress, ...);
|
service, ingress, ...).
|
||||||
- `initialization` creates a job that creates the database;
|
- `initialization` creates a job that performs installation and initializes the database;
|
||||||
- `cleanup` creates a job that drops the database;
|
- `start` updates the resources before scaling up the deployment to 1. This can be
|
||||||
|
useful to scale up other resources that must only be present while the main
|
||||||
|
deployment is running.
|
||||||
|
- `stop` updates the resources after initialization and before scaling down the
|
||||||
|
deployment to 0. This can be useful to scale down other resources that must
|
||||||
|
only be present while the main deployment is running.
|
||||||
|
- `cleanup` creates a job that perform cleanup before tearing down all resources.
|
||||||
|
|
||||||
Besides the three modes, the controller has limited knowledge of what the kubefiles
|
Besides the 5 modes, the controller has limited knowledge of what the kubefiles
|
||||||
actually deploy. It expects the following to hold true:
|
actually deploy. It expects the following to hold true:
|
||||||
|
|
||||||
- the `runboat/build` label is set on all resources, with the unique build name as
|
- the `runboat/build` label is set on all resources, with the unique build name as
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,8 @@ class DeploymentMode(str, Enum):
|
||||||
deployment = "deployment"
|
deployment = "deployment"
|
||||||
initialize = "initialize"
|
initialize = "initialize"
|
||||||
cleanup = "cleanup"
|
cleanup = "cleanup"
|
||||||
|
start = "start"
|
||||||
|
stop = "stop"
|
||||||
|
|
||||||
|
|
||||||
class DeploymentVars(BaseModel):
|
class DeploymentVars(BaseModel):
|
||||||
|
|
|
||||||
|
|
@ -195,12 +195,6 @@ class Build(BaseModel):
|
||||||
build_settings,
|
build_settings,
|
||||||
)
|
)
|
||||||
await k8s.deploy(kubefiles_path, deployment_vars)
|
await k8s.deploy(kubefiles_path, deployment_vars)
|
||||||
await github.notify_status(
|
|
||||||
commit_info.repo,
|
|
||||||
commit_info.git_commit,
|
|
||||||
GitHubStatusState.pending,
|
|
||||||
target_url=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def deploy(cls, commit_info: CommitInfo) -> None:
|
async def deploy(cls, commit_info: CommitInfo) -> None:
|
||||||
|
|
@ -211,6 +205,12 @@ class Build(BaseModel):
|
||||||
await cls._deploy(
|
await cls._deploy(
|
||||||
commit_info, name, slug, job_kind=k8s.DeploymentMode.deployment
|
commit_info, name, slug, job_kind=k8s.DeploymentMode.deployment
|
||||||
)
|
)
|
||||||
|
await github.notify_status(
|
||||||
|
commit_info.repo,
|
||||||
|
commit_info.git_commit,
|
||||||
|
GitHubStatusState.pending,
|
||||||
|
target_url=None,
|
||||||
|
)
|
||||||
|
|
||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
"""Start build if init succeeded, or reinitialize if failed."""
|
"""Start build if init succeeded, or reinitialize if failed."""
|
||||||
|
|
@ -218,6 +218,12 @@ class Build(BaseModel):
|
||||||
_logger.info(f"Ignoring start command for {self} that is {self.status}.")
|
_logger.info(f"Ignoring start command for {self} that is {self.status}.")
|
||||||
return
|
return
|
||||||
_logger.info(f"Starting {self} that was last scaled on {self.last_scaled}.")
|
_logger.info(f"Starting {self} that was last scaled on {self.last_scaled}.")
|
||||||
|
await self._deploy(
|
||||||
|
self.commit_info,
|
||||||
|
self.name,
|
||||||
|
self.slug,
|
||||||
|
job_kind=k8s.DeploymentMode.start,
|
||||||
|
)
|
||||||
await self._patch(desired_replicas=1)
|
await self._patch(desired_replicas=1)
|
||||||
|
|
||||||
async def stop(self) -> None:
|
async def stop(self) -> None:
|
||||||
|
|
@ -226,6 +232,12 @@ class Build(BaseModel):
|
||||||
return
|
return
|
||||||
_logger.info(f"Stopping {self} that was last scaled on {self.last_scaled}.")
|
_logger.info(f"Stopping {self} that was last scaled on {self.last_scaled}.")
|
||||||
await self._patch(desired_replicas=0)
|
await self._patch(desired_replicas=0)
|
||||||
|
await self._deploy(
|
||||||
|
self.commit_info,
|
||||||
|
self.name,
|
||||||
|
self.slug,
|
||||||
|
job_kind=k8s.DeploymentMode.stop,
|
||||||
|
)
|
||||||
|
|
||||||
async def undeploy(self) -> None:
|
async def undeploy(self) -> None:
|
||||||
# To undeploy, we delete the deployment. Due to the finalizer, the deletion
|
# To undeploy, we delete the deployment. Due to the finalizer, the deletion
|
||||||
|
|
@ -246,6 +258,12 @@ class Build(BaseModel):
|
||||||
self.slug,
|
self.slug,
|
||||||
job_kind=k8s.DeploymentMode.deployment,
|
job_kind=k8s.DeploymentMode.deployment,
|
||||||
)
|
)
|
||||||
|
await github.notify_status(
|
||||||
|
self.commit_info.repo,
|
||||||
|
self.commit_info.git_commit,
|
||||||
|
GitHubStatusState.pending,
|
||||||
|
target_url=None,
|
||||||
|
)
|
||||||
|
|
||||||
async def initialize(self) -> None:
|
async def initialize(self) -> None:
|
||||||
"""Launch the initialization job."""
|
"""Launch the initialization job."""
|
||||||
|
|
@ -300,6 +318,12 @@ class Build(BaseModel):
|
||||||
# is restarting, and is notified of existing initialization jobs.
|
# is restarting, and is notified of existing initialization jobs.
|
||||||
return
|
return
|
||||||
_logger.info(f"Initialization job succeded for {self}, ready to start.")
|
_logger.info(f"Initialization job succeded for {self}, ready to start.")
|
||||||
|
await self._deploy(
|
||||||
|
self.commit_info,
|
||||||
|
self.name,
|
||||||
|
self.slug,
|
||||||
|
job_kind=k8s.DeploymentMode.stop,
|
||||||
|
)
|
||||||
if await self._patch(init_status=BuildInitStatus.succeeded):
|
if await self._patch(init_status=BuildInitStatus.succeeded):
|
||||||
await github.notify_status(
|
await github.notify_status(
|
||||||
self.commit_info.repo,
|
self.commit_info.repo,
|
||||||
|
|
@ -314,6 +338,12 @@ class Build(BaseModel):
|
||||||
# restarting, and is notified of existing initialization jobs.
|
# restarting, and is notified of existing initialization jobs.
|
||||||
return
|
return
|
||||||
_logger.info(f"Initialization job failed for {self}.")
|
_logger.info(f"Initialization job failed for {self}.")
|
||||||
|
await self._deploy(
|
||||||
|
self.commit_info,
|
||||||
|
self.name,
|
||||||
|
self.slug,
|
||||||
|
job_kind=k8s.DeploymentMode.stop,
|
||||||
|
)
|
||||||
if await self._patch(init_status=BuildInitStatus.failed, desired_replicas=0):
|
if await self._patch(init_status=BuildInitStatus.failed, desired_replicas=0):
|
||||||
await github.notify_status(
|
await github.notify_status(
|
||||||
self.commit_info.repo,
|
self.commit_info.repo,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue