Jenkins Agent
- Jenkins CI Charmers
Channel | Revision | Published | Runs on |
---|---|---|---|
latest/stable | 5 | 10 May 2021 |
juju deploy jenkins-ci-charmers-jenkins-agent
Deploy Kubernetes operators easily with Juju, the Universal Operator Lifecycle Manager. Need a Kubernetes cluster? Install MicroK8s to create a full CNCF-certified Kubernetes system in under 60 seconds.
Platform:
Charm architecture
At its core, Jenkins agents are Java applications executing the jobs on behalf of Jenkins itself.
The charm design leverages the sidecar pattern to allow multiple containers in each pod with Pebble running as the workload container’s entrypoint.
Pebble is a lightweight, API-driven process supervisor that is responsible for configuring processes to run in a container and controlling those processes throughout the workload lifecycle.
Pebble services
are configured through layers, and the following containers represent each one a layer forming the effective Pebble configuration, or plan
:
- An Jenkins agent container, which manages the CI jobs.
As a result, if you run a kubectl get pods
on a namespace named for the Juju model you’ve deployed the Jenkins agent k8s charm into, you’ll see something like the following:
NAME READY STATUS RESTARTS AGE
jenkins-agent-k8s-0 2/2 Running 0 2m2s
This shows there are 2 containers - the Jenkins agent one and container for the charm code itself.
If you run kubectl describe pod jenkins-agent-k8s-0
, all the containers will have /charm/bin/pebble
as the entrypoint command. That’s because Pebble is responsible for the processes startup as explained above.
OCI images
We use Rockcraft to build the OCI Image for the Jenkins agent. The image is defined in the Jenkins agent k8s ROCK. They are published to Charmhub, the official repository of charms. This is done by publishing a resource to Charmhub as described in the Juju SDK How-to guides.
Containers
Configuration files for the containers can be found in the respective directories that define the ROCKs. See the section above.
Jenkins agent k8s
This container manages the task execution on behalf of the Jenkins controller by using executors. It contains an agent, a small Java client process that connects to a Jenkins controller and is assumed to be unreliable. Any tools required for building and testing get installed on this container, where the agent runs.
The workload that this container is running is defined in the Jenkins agent k8s ROCK.
Integrations
Jenkins
The Jenkins controller, a CI server for which this agent charm will run tasks.
Juju events
According to the Juju SDK: “an event is a data structure that encapsulates part of the execution context of a charm”.
For this charm, the following events are observed:
- jenkins_agent_k8s_pebble_ready: fired on Kubernetes charms when the requested container is ready. Action: wait for the integrations and configuration, download the JAR, configure the container and replan the service.
- config_changed: usually fired in response to a configuration change using the CLI. Action: wait for the integrations and configuration, download the JAR, configure the container and replan the service.
- upgrade_charm: fired when a charm upgrade is triggered. Action: wait for the integrations and configuration, download the JAR, configure the container and replan the service.
- agent_relation_joined: emitted when a unit joins the relation. Action: download the JAR, configure the container and replan the service.
- agent_relation_changed: triggered when another unit involved in the relation changed the data in the relation databag. Action: download the JAR, configure the container and replan the service.
- agent_relation_departed: fired when a unit departs the relation. Action: stop the service.
Charm code overview
The src/charm.py
is the default entry point for a charm and has the JenkinsAgentCharm Python class which inherits from CharmBase.
CharmBase is the base class from which all Charms are formed, defined by Ops (Python framework for developing charms).
See more information in Charm.
The __init__
method guarantees that the charm observes all events relevant to its operation and handles them.
Take, for example, when a configuration is changed by using the CLI.
- User runs the command
juju config jenkins_agent_name=agent-one
- A
config-changed
event is emitted - In the
__init__
method is defined how to handle this event like this:
self.framework.observe(self.on.config_changed, self._on_config_changed)
- The method
_on_config_changed
, for its turn, will take the necessary actions such as waiting for all the relations to be ready and then configuring the containers.