Merge pull request #398 from gabriel-samfira/add-docker-compose-example
Add examples for setting up GARM with Gitea
This commit is contained in:
commit
65aa92f517
2 changed files with 370 additions and 3 deletions
12
README.md
12
README.md
|
|
@ -22,12 +22,10 @@
|
|||
|
||||
Welcome to GARM!
|
||||
|
||||
GARM enables you to create and automatically maintain pools of [self-hosted GitHub runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners), with auto-scaling that can be used inside your github workflow runs.
|
||||
GARM enables you to create and automatically maintain pools of self-hosted runners in both [Github](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) and [Gitea](https://github.com/go-gitea/gitea/) with auto-scaling that can be used inside your workflow runs.
|
||||
|
||||
The goal of ```GARM``` is to be simple to set up, simple to configure and simple to use. The server itself is a single binary that can run on any GNU/Linux machine without any other requirements other than the providers you want to enable in your setup. It is intended to be easy to deploy in any environment and can create runners in virtually any system you can write a provider for (if one does not alreay exist). There is no complicated setup process and no extremely complex concepts to understand. Once set up, it's meant to stay out of your way.
|
||||
|
||||
GARM supports creating pools and scale sets in either GitHub itself or in your own deployment of [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.10/admin/overview/about-github-enterprise-server). For instructions on how to use ```GARM``` with GHE, see the [credentials](/doc/github_credentials.md) section of the documentation.
|
||||
|
||||
Through the use of providers, `GARM` can create runners in a variety of environments using the same `GARM` instance. Whether you want to create runners in your OpenStack cloud, your Azure cloud or your Kubernetes cluster, that is easily achieved by installing the appropriate providers, configuring them in `GARM` and creating pools that use them. You can create zero-runner pools for instances with high costs (large VMs, GPU enabled instances, etc) and have them spin up on demand, or you can create large pools of eagerly created k8s backed runners that can be used for your CI/CD pipelines at a moment's notice. You can mix them up and create pools in any combination of providers or resource allocations you want.
|
||||
|
||||
GARM supports two modes of operation:
|
||||
|
|
@ -62,6 +60,14 @@ Check out the [quickstart](/doc/quickstart.md) document for instructions on how
|
|||
|
||||
Thanks to the efforts of the amazing folks at [@mercedes-benz](https://github.com/mercedes-benz/), GARM can now be integrated into k8s via their operator. Check out the [GARM operator](https://github.com/mercedes-benz/garm-operator/) for more details.
|
||||
|
||||
## Configuring GARM for GHES
|
||||
|
||||
GARM supports creating pools and scale sets in either GitHub itself or in your own deployment of [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.10/admin/overview/about-github-enterprise-server). For instructions on how to use ```GARM``` with GHE, see the [credentials](/doc/github_credentials.md) section of the documentation.
|
||||
|
||||
## Configuring GARM for Gitea
|
||||
|
||||
GARM now has support for Gitea (>=1.24.0). For information on getting started with Gitea, see the [Gitea quickstart](/doc/gitea.md) document.
|
||||
|
||||
## Using GARM
|
||||
|
||||
GARM is designed with simplicity in mind. At least we try to keep it as simple as possible. We're aware that adding a new tool in your workflow can be painful, especially when you already have to deal with so many. The cognitive load for OPS has reached a level where it feels overwhelming at times to even wrap your head around a new tool. As such, we believe that tools should be simple, should take no more than a few hours to understand and set up and if you absolutely need to interact with the tool, it should be as intuitive as possible. Although we try our best to make this happen, we're aware that GARM has some rough edges, especially for new users. If you encounter issues or feel like the setup process was too complicated, please let us know. We're always looking to improve the user experience.
|
||||
|
|
|
|||
361
doc/gitea.md
Normal file
361
doc/gitea.md
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
# Using GARM with Gitea
|
||||
|
||||
Starting with Gitea 1.24 and the latest version of GARM (upcomming v0.2.0 - currently `main`), GARM supports Gitea as a forge, side by side with GitHub/GHES. A new endpoint type has been added to represent Gitea instances, which you can configure and use along side your GitHub runners.
|
||||
|
||||
You can essentially create runners for both GitHub and Gitea using the same GARM instance, using the same CLI and the same API. It's simply a matter of adding an endpoint and credentials. The rest is the same as for github.
|
||||
|
||||
## Quickstart
|
||||
|
||||
This is for testing purposes only. We'll assume you're running on an Ubuntu 24.04 VM or server. You can use anything you'd like, but this quickstart is tailored to get you up and running with the LXD provider. So we'll:
|
||||
|
||||
* Initialize LXD
|
||||
* Create a docker compose yaml
|
||||
* Deploy Gitea and GARM
|
||||
* Configure GARM to use Gitea
|
||||
|
||||
You will have to install Docker-CE yourself.
|
||||
|
||||
### Initialize LXD
|
||||
|
||||
If you already have LXD initialized, you can skip this step. Otherwise, simply run:
|
||||
|
||||
```bash
|
||||
sudo lxd init --auto
|
||||
```
|
||||
|
||||
This should set up LXD with default settings that should work on any system.
|
||||
|
||||
LXD and Docker sometimes have issues with networking due to some conflicting iptables rules. In most cases, if you have docker installed and notice that you don't have access to the outside world from the containers, run the following command:
|
||||
|
||||
```bash
|
||||
sudo iptables -I DOCKER-USER -j ACCEPT
|
||||
```
|
||||
|
||||
### Create the docker compose
|
||||
|
||||
Create a docker compose file in `$HOME/compose.yaml`. This docker compose will deploy both gitea and GARM. If you already have a Gitea >=1.24.0, you can edit this docker compose to only deploy GARM.
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
|
||||
networks:
|
||||
default:
|
||||
external: false
|
||||
|
||||
services:
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:1.24.0-rc0
|
||||
container_name: gitea
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
restart: always
|
||||
networks:
|
||||
- default
|
||||
volumes:
|
||||
- /etc/gitea/gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "80:80"
|
||||
- "22:22"
|
||||
garm:
|
||||
image: ghcr.io/cloudbase/garm:${GARM_VERSION:-nightly}
|
||||
container_name: garm
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
restart: always
|
||||
networks:
|
||||
- default
|
||||
volumes:
|
||||
- /etc/garm:/etc/garm
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
# Give GARM access to the LXD socker. We need this later in the LXD provider.
|
||||
- /var/snap/lxd/common/lxd/unix.socket:/var/snap/lxd/common/lxd/unix.socket
|
||||
ports:
|
||||
- "9997:9997"
|
||||
```
|
||||
|
||||
Create the folders for Gitea and GARM:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /etc/gitea /etc/garm
|
||||
sudo chown 1000:1000 /etc/gitea /etc/garm
|
||||
```
|
||||
|
||||
Create the GARM configuration file:
|
||||
|
||||
```bash
|
||||
|
||||
sudo tee /etc/garm/config.toml <<EOF
|
||||
[default]
|
||||
enable_webhook_management = true
|
||||
|
||||
[logging]
|
||||
# If using nginx, you'll need to configure connection upgrade headers
|
||||
# for the /api/v1/ws location. See the sample config in the testdata
|
||||
# folder.
|
||||
enable_log_streamer = true
|
||||
# Set this to "json" if you want to consume these logs in something like
|
||||
# Loki or ELK.
|
||||
log_format = "text"
|
||||
log_level = "info"
|
||||
log_source = false
|
||||
|
||||
[metrics]
|
||||
enable = true
|
||||
disable_auth = false
|
||||
|
||||
[jwt_auth]
|
||||
# Obviously, this needs to be changed :).
|
||||
secret = "&n~@^QV;&fiTTljy#pWq0>_YE+$%d+O;BMDqnaB)`U4_*iF8snEpEszPyg4N*lI&"
|
||||
time_to_live = "8760h"
|
||||
|
||||
[apiserver]
|
||||
bind = "0.0.0.0"
|
||||
port = 9997
|
||||
use_tls = false
|
||||
|
||||
[database]
|
||||
backend = "sqlite3"
|
||||
# This needs to be changed.
|
||||
passphrase = "OsawnUlubmuHontamedOdVurwetEymni"
|
||||
[database.sqlite3]
|
||||
db_file = "/etc/garm/garm.db"
|
||||
|
||||
# This enables the LXD provider. There are other providers available in the image
|
||||
# in /opt/garm/providers.d. Feel free to use them as well.
|
||||
[[provider]]
|
||||
name = "lxd_local"
|
||||
provider_type = "external"
|
||||
description = "Local LXD installation"
|
||||
[provider.external]
|
||||
provider_executable = "/opt/garm/providers.d/garm-provider-lxd"
|
||||
config_file = "/etc/garm/garm-provider-lxd.toml"
|
||||
EOF
|
||||
```
|
||||
|
||||
Create the LXD provider config file:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/garm/garm-provider-lxd.toml <<EOF
|
||||
# the path to the unix socket that LXD is listening on. This works if garm and LXD
|
||||
# are on the same system, and this option takes precedence over the "url" option,
|
||||
# which connects over the network.
|
||||
unix_socket_path = "/var/snap/lxd/common/lxd/unix.socket"
|
||||
# When defining a pool for a repository or an organization, you have an option to
|
||||
# specify a "flavor". In LXD terms, this translates to "profiles". Profiles allow
|
||||
# you to customize your instances (memory, cpu, disks, nics, etc).
|
||||
# This option allows you to inject the "default" profile along with the profile selected
|
||||
# by the flavor.
|
||||
include_default_profile = false
|
||||
# instance_type defines the type of instances this provider will create.
|
||||
#
|
||||
# Options are:
|
||||
#
|
||||
# * virtual-machine (default)
|
||||
# * container
|
||||
#
|
||||
instance_type = "container"
|
||||
# enable/disable secure boot. If the image you select for the pool does not have a
|
||||
# signed bootloader, set this to false, otherwise your instances won't boot.
|
||||
secure_boot = false
|
||||
# Project name to use. You can create a separate project in LXD for runners.
|
||||
project_name = "default"
|
||||
# URL is the address on which LXD listens for connections (ex: https://example.com:8443)
|
||||
url = ""
|
||||
# garm supports certificate authentication for LXD remote connections. The easiest way
|
||||
# to get the needed certificates, is to install the lxc client and add a remote. The
|
||||
# client_certificate, client_key and tls_server_certificate can be then fetched from
|
||||
# $HOME/snap/lxd/common/config.
|
||||
client_certificate = ""
|
||||
client_key = ""
|
||||
tls_server_certificate = ""
|
||||
[image_remotes]
|
||||
# Image remotes are important. These are the default remotes used by lxc. The names
|
||||
# of these remotes are important. When specifying an "image" for the pool, that image
|
||||
# can be a hash of an existing image on your local LXD installation or it can be a
|
||||
# remote image from one of these remotes. You can specify the images as follows:
|
||||
# Example:
|
||||
#
|
||||
# * ubuntu:20.04
|
||||
# * ubuntu_daily:20.04
|
||||
# * images:centos/8/cloud
|
||||
#
|
||||
# Ubuntu images come pre-installed with cloud-init which we use to set up the runner
|
||||
# automatically and customize the runner. For non Ubuntu images, you need to use the
|
||||
# variant that has "/cloud" in the name. Those images come with cloud-init.
|
||||
[image_remotes.ubuntu]
|
||||
addr = "https://cloud-images.ubuntu.com/releases"
|
||||
public = true
|
||||
protocol = "simplestreams"
|
||||
skip_verify = false
|
||||
[image_remotes.ubuntu_daily]
|
||||
addr = "https://cloud-images.ubuntu.com/daily"
|
||||
public = true
|
||||
protocol = "simplestreams"
|
||||
skip_verify = false
|
||||
[image_remotes.images]
|
||||
addr = "https://images.lxd.canonical.com"
|
||||
public = true
|
||||
protocol = "simplestreams"
|
||||
skip_verify = false
|
||||
EOF
|
||||
```
|
||||
|
||||
Start the containers:
|
||||
|
||||
```bash
|
||||
docker compose -f $HOME/compose.yaml up --force-recreate --build
|
||||
```
|
||||
|
||||
Create a gitea user:
|
||||
|
||||
```bash
|
||||
docker exec -u=1000 gitea \
|
||||
gitea admin user create \
|
||||
--username testing \
|
||||
--password superSecretPasswordThatYouMustAbsolutelyChange \
|
||||
--email admin@example.com \
|
||||
--admin \
|
||||
--must-change-password=false
|
||||
```
|
||||
|
||||
Feel free to log into Gitea and create an org or repo. We'll need one to configure in GARM later to spin up runners. For the purpose of this document, I'll assume you careated an org called `testorg` and a repo inside that org called `testrepo`.
|
||||
|
||||
### Initialize GARM
|
||||
|
||||
Before GARM can be used, you need to [create the admin user](/doc/quickstart.md#initializing-garm). If you deployed GARM using docker, you can copy the client from the image:
|
||||
|
||||
```bash
|
||||
sudo docker cp garm:/bin/garm-cli /usr/local/bin/garm-cli
|
||||
```
|
||||
|
||||
Make sure it's executable:
|
||||
|
||||
```bash
|
||||
chmod +x /usr/local/bin/garm-cli
|
||||
```
|
||||
|
||||
Now you can follow [the rest of the steps from the quickstart](/doc/quickstart.md#initializing-garm). Given that this is gitea and everything is local, instead of `http://garm.example.com` you can use one of the IP addresses available on your system to initialize GARM and possibly [set the controller URLs](/doc/using_garm.md#controller-operations). For the purpose of this example, I'll assume that your local IP address is: `10.0.9.5`, and both GARM (port 9997) and Gitea (port 80) are accessible on that IP address.
|
||||
|
||||
## Adding a Gitea endpoint
|
||||
|
||||
We now have GARM and Gitea installed. Time to add a Gitea endpoint to GARM.
|
||||
|
||||
```bash
|
||||
garm-cli gitea endpoint create \
|
||||
--api-base-url http://10.0.9.5/ \
|
||||
--base-url http://10.0.9.5/ \
|
||||
--description "My first Gitea endpoint" \
|
||||
--name local-gitea
|
||||
```
|
||||
|
||||
An `endpoint` tells GARM how it can access a particular forge (github.com, a self hosted GHES or Gitea). Credentials are tied to endpoints and in turn, entities (repos, orgs, enterprises) are tied to credentials.
|
||||
|
||||
## Adding a Gitea credential
|
||||
|
||||
GARM needs to be able to fetch runner registration tokens, delete runners and set webhooks. We need to create a token that allows these operations on orgs and repos:
|
||||
|
||||
```bash
|
||||
LOGIN=$(curl -s -X POST http://localhost/api/v1/users/testing/tokens \
|
||||
-u 'testing:superSecretPasswordThatYouMustAbsolutelyChange' \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "autotoken", "scopes": ["write:repository", "write:organization"]}')
|
||||
```
|
||||
|
||||
If you echo the resulting token, you should see something like:
|
||||
|
||||
```bash
|
||||
ubuntu@gitea-garm:~$ echo $LOGIN
|
||||
{"id":2,"name":"autotoken","sha1":"34b01d497501c40bde7d4a6052d883b86387ed45","token_last_eight":"6387ed45","scopes":["write:organization","write:repository"]}
|
||||
```
|
||||
|
||||
Now we can create a credential in GARM that uses this token:
|
||||
|
||||
```bash
|
||||
TOKEN=$(echo $LOGIN | jq -r '.sha1')
|
||||
garm-cli gitea credentials add \
|
||||
--endpoint local-gitea \
|
||||
--auth-type pat \
|
||||
--pat-oauth-token $TOKEN \
|
||||
--name autotoken \
|
||||
--description "Gitea token"
|
||||
```
|
||||
|
||||
## Adding a repository
|
||||
|
||||
If you've created a new repository called `testorg/testrepo` in your gitea for the user `testing`, you can add it to GARM as follows:
|
||||
|
||||
```bash
|
||||
garm-cli repo add \
|
||||
--credentials autotoken \
|
||||
--name testrepo \
|
||||
--owner testorg \
|
||||
--random-webhook-secret \
|
||||
--install-webhook \
|
||||
--forge-type gitea
|
||||
```
|
||||
|
||||
Make a note of the repo UUID. You will need it when adding a pool.
|
||||
|
||||
This will add the repo to GARM as an entity, and automatically install a webhook that will send `workflow_job` webhooks to GARM. GARM uses these webhooks to know when a runner needs to be spun up or when a runner must be removed from the provider (LXD in this case), because it has finished running the job.
|
||||
|
||||
The URL that is used by GARM to configure the webhook in gitea is dictated by the `Controller Webhook URL` field in:
|
||||
|
||||
```bash
|
||||
garm-cli controller show
|
||||
```
|
||||
|
||||
You can manually update the controller urls using `garm-cli controller update`, but unless you're using a reverse proxy in front of GARM or want to make it accessible from the internet, you won't need to do this. Consult the [using garm](/doc/using_garm.md) and the [quickstart](/doc/quickstart.md) documents for more information on how to set up GARM and the controller.
|
||||
|
||||
## Adding a pool to your Gitea repo
|
||||
|
||||
Pools will maintain your runners. Each pool is tied to a provider. You can define as many pools as you want, each using a different provider.
|
||||
|
||||
We have the LXD provider configured, so we can use that. You can get a list of configured providers by doing:
|
||||
|
||||
```bash
|
||||
garm-cli provider list
|
||||
```
|
||||
|
||||
The one we configured is called `local_lxd`.
|
||||
|
||||
Before we add a pool, there is one more important detail to know. Right now, the default runner installation script is tailored for github. But most providers offer a way to override the runner install template via an opaque JSON field called `extra_specs`. We can set this field when creating the pool or update it any time later.
|
||||
|
||||
There is a sample extra specs file [in this github gist](https://gist.github.com/gabriel-samfira/d132169ec41d990bbe17e6097af94c4c). We can fetch it and use it when definig the pool:
|
||||
|
||||
```bash
|
||||
curl -L -o $HOME/gitea-pool-specs.json https://gist.githubusercontent.com/gabriel-samfira/d132169ec41d990bbe17e6097af94c4c/raw/67d226d9115eca5e10b69eac5ecb04be91a48991/gitea-extra-specs.json
|
||||
```
|
||||
|
||||
Now, add the pool:
|
||||
|
||||
```bash
|
||||
garm-cli pool add \
|
||||
--repo theUUIDOfTheRepoAddedAbove \
|
||||
--provider-name local_lxd \
|
||||
--image ubuntu:24.04 \
|
||||
--tags ubuntu-latest \
|
||||
--flavor default \
|
||||
--enabled=true \
|
||||
--min-idle-runners=1 \
|
||||
--max-runners=5 \
|
||||
--extra-specs-file=$HOME/gitea-pool-specs.json
|
||||
```
|
||||
|
||||
You should now see 1 runner being spun up in LXD. You can check the status of the pool by doing:
|
||||
|
||||
```bash
|
||||
garm-cli runner ls -a
|
||||
```
|
||||
|
||||
To get more details about the runner, run:
|
||||
|
||||
```bash
|
||||
garm-cli runner show RUNNER_NAME_GOES_HERE
|
||||
```
|
||||
|
||||
That's it! You can now use GARM with Gitea. You can add more pools, more repos, more orgs, more endpoints and more providers.
|
||||
Loading…
Add table
Add a link
Reference in a new issue