Commit graph

256 commits

Author SHA1 Message Date
Gabriel Adrian Samfira
61e674e1fd Add workflow job URL and some logging improvements
Record the workflow job run URL for both scaleset and workflow jobs and
add some logging fixes.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-15 09:52:17 +02:00
Benoit Sigoure
3acbee4582 Auto-derive AgentURL from MetadataURL or CallbackURL if not set
When AgentURL is not explicitly configured, derive it automatically
from MetadataURL (or CallbackURL as fallback) by taking the base URL
and setting the path to /agent.

This makes AgentURL effectively optional for users who use the standard
URL structure, reducing configuration burden when upgrading to versions
that require agent mode support.
2026-02-12 21:54:24 +02:00
Gabriel Adrian Samfira
c7d34e0f0e Force transition instances in inconsistent state
If GARM is killed or restarted while creating a runner, there is a chance
that runners remain in creating or deleting state. We've started checking
state transitions in GARM and allow a transition when the new state makes
sense in normal circumstances. However, when recovering from a crash, we
may be in an inconsisten state from which we need to recover.

This change added a ForceUpdateInstance() function that ignores state
transition inconsistencies. For now, we only use it when spinning up a
scale set and check for instance states.

This change also fixes a locking issue.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-11 20:51:32 +02:00
Gabriel Adrian Samfira
ec0fd6e3f8 Delete all inactionable jobs
GARM cares about jobs in queued state for anything that requires
decision making. Anything else is purely informational.

This change cleans up all inactionable jobs and refuses to record jobs
that are not already in the database, have an inactionable state and
which do not have a runner we own handling them.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-10 14:41:15 +02:00
Gabriel Adrian Samfira
80e042ee88 Add runner rotate ability to CLI
This change adds a new "generation" field to pools, scalesets and
runners. The generation field is inherited by runners from scale sets
or pools at the time of creation.

The generation field on scalesets and pools is incremented when the
pool or scale set is updated in a way that might influence how runners
are created (flavor, image, specs, runner groups, etc).

Using this new field, we can determine if existing runners have diverged
from the settings of the pool/scale set that spawned them.

In the CLI we now have a new set of commands available for both
pools and scalesets that lists runners, with an optional --outdated
flag and a new "rotate" flag that removes all idle runners. Optionally
the --outdated flag can be passed to the rotate command to only remove
outdated runners.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-09 00:30:57 +02:00
Gabriel Adrian Samfira
090fabda9d Fix tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-08 00:27:47 +02:00
Gabriel Adrian Samfira
def4b4aaf1 Handle garm-agent tools upload/sync
This change adds the ability to manage garm-agent tools downloads. Users
can:

* Set an upstream releases page (github releases api)
* Enable sync from upstream. In this case, GARM will automatically download
  garm-agent tools from the releases page and save them in the internal
  object store
* Manually upload tools. Manually uploaded tools for an OS/arch combination
  will never be overwritten by auto-sync. Usrs will need to delete manually
  uploaded tools to enable sync for that os/arch release.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-08 00:27:47 +02:00
Gabriel Adrian Samfira
c29e8d4459 Add some tests, move some code around
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-08 00:27:47 +02:00
Gabriel Adrian Samfira
42cfd1b3c6 Add agent mode
This change adds a new "agent mode" to GARM. The agent enables GARM to
set up a persistent websocket connection between the garm server and the
runners it spawns. The goal is to be able to easier keep track of state,
even without subsequent webhooks from the forge.

The Agent will report via websockets when the runner is actually online,
when it started a job and when it finished a job.

Additionally, the agent allows us to enable optional remote shell between
the user and any runner that is spun up using agent mode. The remote shell
is multiplexed over the same persistent websocket connection the agent
sets up with the server (the agent never listens on a port).

Enablement has also been done in the web UI for this functionality.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2026-02-08 00:27:47 +02:00
Gabriel Adrian Samfira
6361e19821 Disable the web UI tests for now
fixes for the tests will be added in a later PR

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-08 22:22:58 +03:00
Gabriel Adrian Samfira
73b330467b Use tmp storage while uploading, use tx where needed
Use temporary storage while the client is streaming the file to GARM.
This ensures that while uploading, we don't lock the blob database. On slow
connections this would mean that no readers would be able to access the db
while data was being written to it via the upload process.

By saving the file to a temporary location and only after we receive the
entire thing, add it to the DB, we significantly reduce the time we need to
keep the DB locked.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-08 22:22:58 +03:00
Gabriel Adrian Samfira
db2b908605 Use a sepatare GORM connection for blobs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-08 22:22:58 +03:00
Gabriel Adrian Samfira
6c46cf9be1 Add API, CLI and web UI integration for objects
This change adds the API endpoints, the CLI commands and the web UI elements
needed to manage objects in GARMs internal storage.

This storage system is meant to be used to distribute the garm-agent and as a
single source of truth for provider binaries, when we will add the ability for GARM
to scale out.

Potentially, we can also use this in air gapped systems to distribute the runner binaries
for forges that don't have their own internal storage system (like GHES).

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-08 22:22:58 +03:00
Gabriel Adrian Samfira
f66f95baff Fix database tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-07 21:01:40 +03:00
Gabriel Adrian Samfira
5a93761af7 Make tag searches case insensitive
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-07 21:01:40 +03:00
Gabriel Adrian Samfira
9adb872985 Improve pagination
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-07 21:01:40 +03:00
Gabriel Adrian Samfira
7d53ce79b7 Add database models and functions for file objects
This commit adds the DB models and functions needed to create, read,
search through, update and delete files within sqlite3.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-07 21:01:40 +03:00
Gabriel Adrian Samfira
a36d01afd5 Cache jobs in pool manager
This change caches jobs meant for an entity in the pool manager. This
allows us to avoid querying the db as much and allows us to better determine
when we should scale down.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-10-05 00:49:41 +03:00
Gabriel Adrian Samfira
5fdb69ac18 Add the ability to set tools download source (Gitea)
This change adds 2 new options to gitea forge endpoints:

* Tools metadata URL
* Use internal tools URLs

By default, GARM looks in the releases page of the gitea arc_runner
to determine where it can download the runner binary from for a particular
OS/arch. The tools metadata URL option can be set on an endpoint and can point
to a mirror of the upstream repo. The requirement is that the asset names
exactly mirror upstream naming conventions.

The second option disables GARM calling out to the tools metadata URL entirely.
GARM has some hardcoded values for nightly binaries. If this option is checked,
GARM will use those values, without making any kind of outgoing API call to
determine availability. This is useful in air-gapped environments.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-09-26 18:59:15 +03:00
Gabriel
23f92bc335
Add runner install template management (#525)
* Add template api endpoints

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Added template bypass

Pools and scale sets will automatically migrate to the new template
system for runner install scripts. If a pool or a scale set cannot be
migrate, it is left alone. It is expected that users set a runner install
template manually for scenarios we don't yet have a template for (windows
on gitea for example).

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Integrate templates with pool create/update

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Add webapp integration with templates

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Add unit tests

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Populate all relevant context fields

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Update dependencies

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Fix lint

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Validate uint

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Add CLI template management

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Some editor improvements and bugfixes

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Fix scale set return values post create

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

* Fix template websocket events filter

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>

---------

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-09-23 13:46:27 +03:00
Gabriel Adrian Samfira
66fd0d51a6 Cache improvements, db list improvements, cleanup
This change adds some more cache helper functions, additional tests,
vastly improves memory usage when loading instances and cleans up some
code.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-09-09 20:52:01 +00:00
Gabriel Adrian Samfira
9ef4566cae Preload more info for entity pools
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-27 09:14:45 +00:00
Gabriel Adrian Samfira
6fee10c737 Fix double creation of pools
This change fixes the creation of pools though the UI. Both the modal and
the page were sending a request to create the pool, leading to double pool.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-25 16:12:01 +00:00
Gabriel Adrian Samfira
39003f006a Ensure scale set exists
Github will remove inactive scale sets after 7 days. This change
ensures the scale set exists in github before spinning up the listener.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-23 18:55:08 +00:00
Gabriel Adrian Samfira
8d5c6b6738 Bump go version to 1.24.6 and run go generate
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-21 20:36:50 +00:00
Gabriel Adrian Samfira
4341b4869c Fix erroneous calls to Job related functions
Some functions were left behind when we added WorkflowJobID.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-21 18:57:42 +00:00
igrikus
8bda81d6cc fix(jobs): Correctly handle workflow job IDs from webhooks 2025-08-21 14:54:38 +02:00
Gabriel Adrian Samfira
31ad45eeb6 Allow referencing runners by ID
Although runner names are unique, we still have an ID on the model
which is used as a primary key. We should allow using that ID to
reference a runner in the API.

This change allows users to specify ID or runner name.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 23:00:55 +00:00
Gabriel Adrian Samfira
118319c7c1 Switch to fmt.Errorf
Replace all instances of errors.Wrap() with fmt.Errorf.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 22:19:05 +00:00
Gabriel Adrian Samfira
eec158b32c Add SPA UI for GARM
This change adds a single page application front-end to GARM. It uses
a generated REST client, built from the swagger definitions, the websocket
interface for live updates of entities and eager loading of everything
except runners, as users may have many runners and we don't want to load
hundreds of runners in memory.

Proper pagination should be implemented in the API, in future commits,
to avoid loading lots of elements for no reason.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 09:09:13 +00:00
Gabriel Adrian Samfira
b2dee1d844 Preload missing resources
There are some inconsistencies in the way the API returns some
values for pools and scale sets. This is due to not preloading
the appropriate relations.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-12 12:48:48 +00:00
Gabriel Adrian Samfira
a984782fd7 Handle new jobID for scale sets
There seems to be a change in the scale set message. It now includes
a jobID and sets the runner request ID to 0. This change adds separate
job ID fields for workflow jobs and scaleset jobs.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-18 08:20:50 +00:00
Gabriel Adrian Samfira
69779a0a7d Fix scale set param
Do not look for a name when composing the scale set. Preload may not
have been called on an entity, but we still have the ID, which is the
only thing needed when GetEntity() is called.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-17 17:01:20 +00:00
Gabriel Adrian Samfira
499fbde60c Add a rudimentary filter option when listing entities
This change adds the ability to filter the list of entities returned
by the API by entity owner, name or endpoint, depending on the entity
type.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-18 21:23:34 +00:00
Gabriel Adrian Samfira
87055f23da Make the default github endpoint mutable
This change allows users to remove the default github endpoint
if no credentials are set on it.

A new protection is added on URLs of any endpoint that prevents their
update if the endpoint has credentials set.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-24 22:26:01 +00:00
Gabriel Adrian Samfira
9921a7bfc8 Fix AddInstanceEvent and expose events
* We were passing the wrong type to GORM for events
* We now expose entity events in the API and CLI

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-22 19:19:24 +00:00
Gabriel Adrian Samfira
1fc72ab5c8 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 16:12:45 +00:00
Gabriel Adrian Samfira
1fe09548bc Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 13:52:16 +00:00
Gabriel Adrian Samfira
b4268e6bab Fix tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 09:52:13 +00:00
Gabriel Adrian Samfira
6994c8ce05 Add copyright header
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 09:43:29 +00:00
Gabriel Adrian Samfira
f0753eeb22 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 09:22:55 +00:00
Gabriel Adrian Samfira
b2d5609352 Add some tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-19 19:45:45 +00:00
Gabriel Adrian Samfira
6a168ba813 Enable orgs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-16 23:02:01 +00:00
Gabriel Adrian Samfira
5dfcfc542e Implement webhooks install for gitea
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-16 20:24:11 +00:00
Gabriel Adrian Samfira
08511e2e7f Account for gitea credentials in cache and watchers
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-15 09:15:44 +00:00
Gabriel Adrian Samfira
b4e92a69c9 Fix existing tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 23:20:18 +00:00
Gabriel Adrian Samfira
0270117e8d Fix lint errors
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 22:01:11 +00:00
Gabriel Adrian Samfira
56be5eb698 Do not load scalesets and runners in parallel
Both functions read and write to the same map. We should switch
to sync.Map

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 15:36:53 +00:00
Gabriel Adrian Samfira
823a9e4b82 Add Gitea endpoints and credentials
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 00:34:54 +00:00
Gabriel Adrian Samfira
40e6581a75 Rename GitHub specific types
This change renames a lot of variables, types and functions to be more
generic. The goal is to allow GARM to add more forges in the future.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-12 21:47:13 +00:00