Skip to content

Commit

Permalink
feat: label config (#244)
Browse files Browse the repository at this point in the history
* feat: label config

* docs: add charmhub documentation

* fix: typo

* fix: flush runners on label config change

* fix: integration test

* chore: log labels on runenrs

* test: fix label find

* docs: update description

* docs: update examples for labels
  • Loading branch information
yanksyoon authored Mar 19, 2024
1 parent b4df77f commit 2608045
Show file tree
Hide file tree
Showing 20 changed files with 218 additions and 58 deletions.
8 changes: 8 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ options:
description: |
The organization runner group to register the self-hosted runner under. This has no effect on
runners under a repository.
labels:
type: string
default: ""
description: |
Additional comma separated labels to attach to self-hosted runners. By default, the labels
"self-hosted", application name (default: "github-runner"),
architecture (i.e. "x64", "arm64"), os (i.e. "linux"), os-flavor (i.e. "jammy") are set.
Any labels provided via this configuration will be appended to the default values.
path:
type: string
default: ""
Expand Down
15 changes: 15 additions & 0 deletions docs/how-to/add-custom-labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# How to add custom labels

This charm supports adding custom labels to the runners.

By using [`juju config`](https://juju.is/docs/juju/juju-config) to change the
[charm configuration labels](https://charmhub.io/github-runner/configure#labels), additional
custom labels can be attached to the self-hosted runners.

```shell
juju config <APP_NAME> labels=<COMMA_SEPARATED_LABELS>
```

An example of a COMMA_SEPARATED_LABELS value would be "large,gpu", "small,arm64".
Accepted values are alphanumeric values with underscores (_), whitespaces before and after the the
word will be automatically trimmed.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Thinking about using the GitHub runner charm for your next project? [Get in touc
1. [ARM64](explanation/arm64.md)
1. [Charm architecture](explanation/charm-architecture.md)
1. [How To](how-to)
1. [How to add custom labels](how-to/add-custom-labels.md)
1. [How to change repository or organization](how-to/change-path.md)
1. [How to change GitHub personal access token](how-to/change-token.md)
1. [How to comply with security requirements](how-to/comply-security.md)
Expand Down
7 changes: 4 additions & 3 deletions src-docs/charm.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ Charm for creating and managing GitHub self-hosted runner instances.
**Global Variables**
---------------
- **DEBUG_SSH_INTEGRATION_NAME**
- **LABELS_CONFIG_NAME**
- **RECONCILE_RUNNERS_EVENT**

---

<a href="../src/charm.py#L77"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm.py#L78"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>function</kbd> `catch_charm_errors`

Expand All @@ -38,7 +39,7 @@ Catch common errors in charm.

---

<a href="../src/charm.py#L112"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm.py#L113"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>function</kbd> `catch_action_errors`

Expand Down Expand Up @@ -67,7 +68,7 @@ Catch common errors in actions.
## <kbd>class</kbd> `GithubRunnerCharm`
Charm for managing GitHub self-hosted runners.

<a href="../src/charm.py#L157"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm.py#L158"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

Expand Down
34 changes: 18 additions & 16 deletions src-docs/charm_state.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ State of the Charm.
- **ARCHITECTURES_ARM64**
- **ARCHITECTURES_X86**
- **OPENSTACK_CLOUDS_YAML_CONFIG_NAME**
- **LABELS_CONFIG_NAME**
- **COS_AGENT_INTEGRATION_NAME**
- **DEBUG_SSH_INTEGRATION_NAME**

---

<a href="../src/charm_state.py#L85"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L87"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

## <kbd>function</kbd> `parse_github_path`

Expand Down Expand Up @@ -56,19 +57,20 @@ Some charm configurations are grouped into other configuration models.

**Attributes:**

- <b>`path`</b>: GitHub repository path in the format '<owner>/<repo>', or the GitHub organization name.
- <b>`token`</b>: GitHub personal access token for GitHub API.
- <b>`reconcile_interval`</b>: Time between each reconciliation of runners.
- <b>`denylist`</b>: List of IPv4 to block the runners from accessing.
- <b>`dockerhub_mirror`</b>: Private docker registry as dockerhub mirror for the runners to use.
- <b>`labels`</b>: Additional runner labels to append to default (i.e. os, flavor, architecture).
- <b>`openstack_clouds_yaml`</b>: The openstack clouds.yaml configuration.
- <b>`path`</b>: GitHub repository path in the format '<owner>/<repo>', or the GitHub organization name.
- <b>`reconcile_interval`</b>: Time between each reconciliation of runners.
- <b>`token`</b>: GitHub personal access token for GitHub API.




---

<a href="../src/charm_state.py#L280"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L321"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `check_fields`

Expand All @@ -91,7 +93,7 @@ Validate the general charm configuration.

---

<a href="../src/charm_state.py#L220"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L255"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_charm`

Expand Down Expand Up @@ -124,7 +126,7 @@ Raised when charm config is invalid.

- <b>`msg`</b>: Explanation of the error.

<a href="../src/charm_state.py#L144"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L146"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

Expand Down Expand Up @@ -164,7 +166,7 @@ The charm state.

---

<a href="../src/charm_state.py#L573"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L614"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_charm`

Expand Down Expand Up @@ -203,7 +205,7 @@ Represent GitHub organization.

---

<a href="../src/charm_state.py#L73"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L75"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `path`

Expand Down Expand Up @@ -236,7 +238,7 @@ Represent GitHub repository.

---

<a href="../src/charm_state.py#L52"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L54"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `path`

Expand Down Expand Up @@ -277,7 +279,7 @@ Return the aproxy address.

---

<a href="../src/charm_state.py#L440"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L481"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `check_fields`

Expand All @@ -300,7 +302,7 @@ Validate the proxy configuration.

---

<a href="../src/charm_state.py#L402"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L443"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_charm`

Expand Down Expand Up @@ -340,7 +342,7 @@ Runner configurations for the charm.

---

<a href="../src/charm_state.py#L354"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L395"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `check_fields`

Expand All @@ -363,7 +365,7 @@ Validate the runner configuration.

---

<a href="../src/charm_state.py#L317"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L358"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_charm`

Expand Down Expand Up @@ -413,7 +415,7 @@ SSH connection information for debug workflow.

---

<a href="../src/charm_state.py#L520"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L561"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_charm`

Expand Down Expand Up @@ -441,7 +443,7 @@ Raised when given machine charm architecture is unsupported.

- <b>`arch`</b>: The current machine architecture.

<a href="../src/charm_state.py#L477"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm_state.py#L518"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

Expand Down
2 changes: 1 addition & 1 deletion src-docs/runner.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Create the runner instance on LXD and register it on GitHub.

---

<a href="../src/runner.py#L161"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/runner.py#L162"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `remove`

Expand Down
8 changes: 4 additions & 4 deletions src-docs/runner_manager.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Construct RunnerManager object for creating and managing runners.

---

<a href="../src/runner_manager.py#L743"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/runner_manager.py#L744"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `build_runner_image`

Expand Down Expand Up @@ -80,7 +80,7 @@ Check if runner binary exists.

---

<a href="../src/runner_manager.py#L581"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/runner_manager.py#L582"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `flush`

Expand Down Expand Up @@ -145,7 +145,7 @@ The runner binary URL changes when a new version is available.

---

<a href="../src/runner_manager.py#L476"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/runner_manager.py#L477"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `reconcile`

Expand All @@ -169,7 +169,7 @@ Bring runners in line with target.

---

<a href="../src/runner_manager.py#L753"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/runner_manager.py#L754"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `schedule_build_runner_image`

Expand Down
9 changes: 4 additions & 5 deletions src-docs/runner_manager_type.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,12 @@ Configuration of runner manager.

**Attributes:**

- <b>`path`</b>: GitHub repository path in the format '<owner>/<repo>', or the GitHub organization name.
- <b>`token`</b>: GitHub personal access token to register runner to the repository or organization.
- <b>`charm_state`</b>: The state of the charm.
- <b>`image`</b>: Name of the image for creating LXD instance.
- <b>`service_token`</b>: Token for accessing local service.
- <b>`lxd_storage_path`</b>: Path to be used as LXD storage.
- <b>`proxy_config`</b>: Proxy configuration.
- <b>`charm_state`</b>: The state of the charm.
- <b>`path`</b>: GitHub repository path in the format '<owner>/<repo>', or the GitHub organization name.
- <b>`service_token`</b>: Token for accessing local service.
- <b>`token`</b>: GitHub personal access token to register runner to the repository or organization.
- <b>`dockerhub_mirror`</b>: URL of dockerhub mirror to use.


Expand Down
1 change: 1 addition & 0 deletions src-docs/runner_type.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Configuration for runner.

- <b>`app_name`</b>: Application name of the charm.
- <b>`issue_metrics`</b>: Whether to issue metrics.
- <b>`labels`</b>: Custom runner labels.
- <b>`lxd_storage_path`</b>: Path to be used as LXD storage.
- <b>`name`</b>: Name of the runner.
- <b>`path`</b>: GitHub repository path in the format '<owner>/<repo>', or the GitHub organization name.
Expand Down
18 changes: 12 additions & 6 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import openstack_manager
from charm_state import (
DEBUG_SSH_INTEGRATION_NAME,
LABELS_CONFIG_NAME,
CharmConfigInvalidError,
CharmState,
GithubPath,
Expand Down Expand Up @@ -176,6 +177,7 @@ def __init__(self, *args, **kargs) -> None:
self._stored.set_default(
path=self.config["path"], # for detecting changes
token=self.config["token"], # for detecting changes
labels=self.config[LABELS_CONFIG_NAME], # for detecting changes
runner_bin_url=None,
)

Expand Down Expand Up @@ -325,13 +327,13 @@ def _get_runner_manager(
app_name,
unit,
RunnerManagerConfig(
path=path,
token=token,
image="jammy",
service_token=self.service_token,
lxd_storage_path=lxd_storage_path,
charm_state=state,
dockerhub_mirror=state.charm_config.dockerhub_mirror,
image="jammy",
lxd_storage_path=lxd_storage_path,
path=path,
service_token=self.service_token,
token=token,
),
)

Expand Down Expand Up @@ -500,6 +502,7 @@ def _on_config_changed(self, _event: ConfigChangedEvent) -> None:
self._set_reconcile_timer()

prev_config_for_flush: dict[str, str] = {}
should_flush_runners = False
if state.charm_config.token != self._stored.token:
prev_config_for_flush["token"] = str(self._stored.token)
self._start_services(state.charm_config.token, state.proxy_config)
Expand All @@ -509,7 +512,10 @@ def _on_config_changed(self, _event: ConfigChangedEvent) -> None:
self._stored.path, self.config["group"]
)
self._stored.path = self.config["path"]
if prev_config_for_flush:
if self.config[LABELS_CONFIG_NAME] != self._stored.labels:
should_flush_runners = True
self._stored.labels = self.config[LABELS_CONFIG_NAME]
if prev_config_for_flush or should_flush_runners:
prev_runner_manager = self._get_runner_manager(state=state, **prev_config_for_flush)
if prev_runner_manager:
self.unit.status = MaintenanceStatus("Removing runners due to config change")
Expand Down
Loading

0 comments on commit 2608045

Please sign in to comment.