Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion cache/credentials_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,30 @@ func (g *CredentialCache) SetCredentialsRateLimit(credsID uint, rateLimit params
}
}

func (g *CredentialCache) SetCredentials(credentials params.ForgeCredentials) {
func (g *CredentialCache) UpdateCredentialsUsingEndpoint(ep params.ForgeEndpoint) {
g.mux.Lock()
defer g.mux.Unlock()

for _, creds := range g.cache {
if creds.Endpoint.Name == ep.Name {
creds.Endpoint = ep
g.setCredentialsAndUpdateEntities(creds)
}
}
}

func (g *CredentialCache) setCredentialsAndUpdateEntities(credentials params.ForgeCredentials) {
g.cache[credentials.ID] = credentials
UpdateCredentialsInAffectedEntities(credentials)
}

func (g *CredentialCache) SetCredentials(credentials params.ForgeCredentials) {
g.mux.Lock()
defer g.mux.Unlock()

g.setCredentialsAndUpdateEntities(credentials)
}

func (g *CredentialCache) GetCredentials(id uint) (params.ForgeCredentials, bool) {
g.mux.Lock()
defer g.mux.Unlock()
Expand Down Expand Up @@ -146,3 +162,7 @@ func GetAllGiteaCredentials() []params.ForgeCredentials {
func GetAllGiteaCredentialsAsMap() map[uint]params.ForgeCredentials {
return giteaCredentialsCache.GetAllCredentialsAsMap()
}

func UpdateCredentialsUsingEndpoint(ep params.ForgeEndpoint) {
giteaCredentialsCache.UpdateCredentialsUsingEndpoint(ep)
}
72 changes: 72 additions & 0 deletions cache/endpoint_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache

import (
"sync"

"github.com/cloudbase/garm/params"
)

var endpointCache *EndpointCache

func init() {
epCache := &EndpointCache{
endpoints: make(map[string]params.ForgeEndpoint),
}
endpointCache = epCache
}

type EndpointCache struct {
endpoints map[string]params.ForgeEndpoint
mux sync.Mutex
}

func (e *EndpointCache) SetEndpoint(ep params.ForgeEndpoint) {
e.mux.Lock()
defer e.mux.Unlock()

e.endpoints[ep.Name] = ep
UpdateCredentialsUsingEndpoint(ep)
}

func (e *EndpointCache) GetEndpoint(epName string) (params.ForgeEndpoint, bool) {
e.mux.Lock()
defer e.mux.Unlock()

ep, ok := e.endpoints[epName]
if ok {
return ep, true
}
return params.ForgeEndpoint{}, false
}

func (e *EndpointCache) RemoveEndpoint(epName string) {
e.mux.Lock()
defer e.mux.Unlock()

delete(e.endpoints, epName)
}

func SetEndpoint(ep params.ForgeEndpoint) {
endpointCache.SetEndpoint(ep)
}

func GetEndpoint(epName string) (params.ForgeEndpoint, bool) {
return endpointCache.GetEndpoint(epName)
}

func RemoveEndpoint(epName string) {
endpointCache.RemoveEndpoint(epName)
}
19 changes: 19 additions & 0 deletions cache/entity_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,21 @@ func (e *EntityCache) GetEntityScaleSets(entityID string) []params.ScaleSet {
return nil
}

func (e *EntityCache) GetEntitiesUsingEndpoint(endpoint params.ForgeEndpoint) []params.ForgeEntity {
e.mux.Lock()
defer e.mux.Unlock()

var entities []params.ForgeEntity
for _, cache := range e.entities {
if cache.Entity.Credentials.Endpoint.Name != endpoint.Name {
continue
}
entities = append(entities, cache.Entity)
}
sortByCreationDate(entities)
return entities
}

func (e *EntityCache) GetEntitiesUsingCredentials(creds params.ForgeCredentials) []params.ForgeEntity {
e.mux.Lock()
defer e.mux.Unlock()
Expand Down Expand Up @@ -544,3 +559,7 @@ func GetPoolByID(poolID string) (params.Pool, bool) {
func GetScaleSetByID(scaleSetID uint) (params.ScaleSet, bool) {
return entityCache.GetScaleSetByID(scaleSetID)
}

func GetEntitiesUsingEndpoint(endpoint params.ForgeEndpoint) []params.ForgeEntity {
return entityCache.GetEntitiesUsingEndpoint(endpoint)
}
42 changes: 36 additions & 6 deletions cmd/garm-cli/cmd/gitea_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ import (

apiClientEndpoints "github.com/cloudbase/garm/client/endpoints"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/util/appdefaults"
)

var (
toolsMetadataURL string
useInternalMetadata bool
)

var giteaEndpointCmd = &cobra.Command{
Expand Down Expand Up @@ -151,25 +157,43 @@ var giteaEndpointUpdateCmd = &cobra.Command{
}

updateParams := params.UpdateGiteaEndpointParams{}

var hasChanges bool
if cmd.Flags().Changed("ca-cert-path") {
cert, err := parseAndReadCABundle()
if err != nil {
return err
}
updateParams.CACertBundle = cert
hasChanges = true
}

if cmd.Flags().Changed("tools-metadata-url") {
updateParams.ToolsMetadataURL = toolsMetadataURL
hasChanges = true
}

if cmd.Flags().Changed("use-internal-tools-metadata") {
updateParams.UseInternalToolsMetadata = &useInternalMetadata
hasChanges = true
}

if cmd.Flags().Changed("description") {
updateParams.Description = &endpointDescription
hasChanges = true
}

if cmd.Flags().Changed("base-url") {
updateParams.BaseURL = &endpointBaseURL
hasChanges = true
}

if cmd.Flags().Changed("api-base-url") {
updateParams.APIBaseURL = &endpointAPIBaseURL
hasChanges = true
}
if !hasChanges {
fmt.Println("no changes made")
return nil
}

newEndpointUpdateReq := apiClientEndpoints.NewUpdateGiteaEndpointParams()
Expand All @@ -191,6 +215,8 @@ func init() {
giteaEndpointCreateCmd.Flags().StringVar(&endpointBaseURL, "base-url", "", "Base URL of the Gitea endpoint")
giteaEndpointCreateCmd.Flags().StringVar(&endpointAPIBaseURL, "api-base-url", "", "API Base URL of the Gitea endpoint")
giteaEndpointCreateCmd.Flags().StringVar(&endpointCACertPath, "ca-cert-path", "", "CA Cert Path of the Gitea endpoint")
giteaEndpointCreateCmd.Flags().StringVar(&toolsMetadataURL, "tools-metadata-url", appdefaults.GiteaRunnerReleasesURL, "URL to the releases page of the ACT runner.")
giteaEndpointCreateCmd.Flags().BoolVar(&useInternalMetadata, "use-internal-tools-metadata", false, "Use the static tools information (nightly) and do not attempt to fetch from metadata URL.")

giteaEndpointListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.")

Expand All @@ -202,6 +228,8 @@ func init() {
giteaEndpointUpdateCmd.Flags().StringVar(&endpointBaseURL, "base-url", "", "Base URL of the Gitea endpoint")
giteaEndpointUpdateCmd.Flags().StringVar(&endpointAPIBaseURL, "api-base-url", "", "API Base URL of the Gitea endpoint")
giteaEndpointUpdateCmd.Flags().StringVar(&endpointCACertPath, "ca-cert-path", "", "CA Cert Path of the Gitea endpoint")
giteaEndpointUpdateCmd.Flags().StringVar(&toolsMetadataURL, "tools-metadata-url", appdefaults.GiteaRunnerReleasesURL, "URL to the releases page of the ACT runner.")
giteaEndpointUpdateCmd.Flags().BoolVar(&useInternalMetadata, "use-internal-tools-metadata", false, "Use the static tools information (nightly) and do not attempt to fetch from metadata URL.")

giteaEndpointCmd.AddCommand(
giteaEndpointListCmd,
Expand All @@ -221,11 +249,13 @@ func parseGiteaCreateParams() (params.CreateGiteaEndpointParams, error) {
}

ret := params.CreateGiteaEndpointParams{
Name: endpointName,
BaseURL: endpointBaseURL,
APIBaseURL: endpointAPIBaseURL,
Description: endpointDescription,
CACertBundle: certBundleBytes,
Name: endpointName,
BaseURL: endpointBaseURL,
APIBaseURL: endpointAPIBaseURL,
Description: endpointDescription,
CACertBundle: certBundleBytes,
ToolsMetadataURL: toolsMetadataURL,
UseInternalToolsMetadata: &useInternalMetadata,
}
return ret, nil
}
14 changes: 14 additions & 0 deletions cmd/garm-cli/cmd/github_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
apiClientEndpoints "github.com/cloudbase/garm/client/endpoints"
"github.com/cloudbase/garm/cmd/garm-cli/common"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/util/appdefaults"
)

var githubEndpointCmd = &cobra.Command{
Expand Down Expand Up @@ -303,6 +304,19 @@ func formatOneEndpoint(endpoint params.ForgeEndpoint) {
if endpoint.UploadBaseURL != "" {
t.AppendRow([]interface{}{"Upload URL", endpoint.UploadBaseURL})
}

if endpoint.EndpointType == params.GiteaEndpointType {
metadataURL := appdefaults.GiteaRunnerReleasesURL
if endpoint.ToolsMetadataURL != "" {
metadataURL = endpoint.ToolsMetadataURL
}
var useInternal bool
if endpoint.UseInternalToolsMetadata != nil {
useInternal = *endpoint.UseInternalToolsMetadata
}
t.AppendRow([]interface{}{"Tools metadata URL", metadataURL})
t.AppendRow([]interface{}{"Use internal tools metadata URL", useInternal})
}
t.AppendRow([]interface{}{"API Base URL", endpoint.APIBaseURL})
if len(endpoint.CACertBundle) > 0 {
t.AppendRow([]interface{}{"CA Cert Bundle", string(endpoint.CACertBundle)})
Expand Down
26 changes: 20 additions & 6 deletions database/sql/gitea.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ import (
"github.com/cloudbase/garm/auth"
"github.com/cloudbase/garm/database/common"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/util/appdefaults"
)

func (s *sqlDatabase) CreateGiteaEndpoint(_ context.Context, param params.CreateGiteaEndpointParams) (ghEndpoint params.ForgeEndpoint, err error) {
if param.ToolsMetadataURL == "" {
param.ToolsMetadataURL = appdefaults.GiteaRunnerReleasesURL
}
defer func() {
if err == nil {
s.sendNotify(common.GithubEndpointEntityType, common.CreateOperation, ghEndpoint)
Expand All @@ -40,12 +44,16 @@ func (s *sqlDatabase) CreateGiteaEndpoint(_ context.Context, param params.Create
return fmt.Errorf("gitea endpoint already exists: %w", runnerErrors.ErrDuplicateEntity)
}
endpoint = GithubEndpoint{
Name: param.Name,
Description: param.Description,
APIBaseURL: param.APIBaseURL,
BaseURL: param.BaseURL,
CACertBundle: param.CACertBundle,
EndpointType: params.GiteaEndpointType,
Name: param.Name,
Description: param.Description,
APIBaseURL: param.APIBaseURL,
BaseURL: param.BaseURL,
CACertBundle: param.CACertBundle,
EndpointType: params.GiteaEndpointType,
ToolsMetadataURL: param.ToolsMetadataURL,
}
if param.UseInternalToolsMetadata != nil {
endpoint.UseInternalToolsMetadata = *param.UseInternalToolsMetadata
}

if err := tx.Create(&endpoint).Error; err != nil {
Expand Down Expand Up @@ -121,6 +129,12 @@ func (s *sqlDatabase) UpdateGiteaEndpoint(_ context.Context, name string, param
if param.Description != nil {
endpoint.Description = *param.Description
}
if param.UseInternalToolsMetadata != nil {
endpoint.UseInternalToolsMetadata = *param.UseInternalToolsMetadata
}
if param.ToolsMetadataURL != "" {
endpoint.ToolsMetadataURL = param.ToolsMetadataURL
}

if err := tx.Save(&endpoint).Error; err != nil {
return fmt.Errorf("error updating gitea endpoint: %w", err)
Expand Down
4 changes: 3 additions & 1 deletion database/sql/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,9 @@ type GithubEndpoint struct {
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`

EndpointType params.EndpointType `gorm:"index:idx_endpoint_type"`
EndpointType params.EndpointType `gorm:"index:idx_endpoint_type"`
ToolsMetadataURL string `gorm:"type:text collate nocase"`
UseInternalToolsMetadata bool

Description string `gorm:"type:text"`
APIBaseURL string `gorm:"type:text collate nocase"`
Expand Down
14 changes: 12 additions & 2 deletions database/sql/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/cloudbase/garm/auth"
dbCommon "github.com/cloudbase/garm/database/common"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/util/appdefaults"
)

func (s *sqlDatabase) sqlToParamsInstance(instance Instance) (params.Instance, error) {
Expand Down Expand Up @@ -952,7 +953,7 @@ func (s *sqlDatabase) sqlGiteaToCommonForgeCredentials(creds GiteaCredentials) (
}

func (s *sqlDatabase) sqlToCommonGithubEndpoint(ep GithubEndpoint) (params.ForgeEndpoint, error) {
return params.ForgeEndpoint{
ret := params.ForgeEndpoint{
Name: ep.Name,
Description: ep.Description,
APIBaseURL: ep.APIBaseURL,
Expand All @@ -962,7 +963,16 @@ func (s *sqlDatabase) sqlToCommonGithubEndpoint(ep GithubEndpoint) (params.Forge
CreatedAt: ep.CreatedAt,
EndpointType: ep.EndpointType,
UpdatedAt: ep.UpdatedAt,
}, nil
}
if ep.EndpointType == params.GiteaEndpointType {
ret.UseInternalToolsMetadata = &ep.UseInternalToolsMetadata
if ep.ToolsMetadataURL == "" {
ret.ToolsMetadataURL = appdefaults.GiteaRunnerReleasesURL
} else {
ret.ToolsMetadataURL = ep.ToolsMetadataURL
}
}
return ret, nil
}

func getUIDFromContext(ctx context.Context) (uuid.UUID, error) {
Expand Down
Loading
Loading