mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(site): add a provisioner warning to workspace builds (#15686)
This PR adds warnings about provisioner health to workspace build pages. It closes https://github.com/coder/coder/issues/15048  
This commit is contained in:
@@ -1120,6 +1120,14 @@ func (q *FakeQuerier) getWorkspaceAgentScriptsByAgentIDsNoLock(ids []uuid.UUID)
|
||||
return scripts, nil
|
||||
}
|
||||
|
||||
// getOwnerFromTags returns the lowercase owner from tags, matching SQL's COALESCE(tags ->> 'owner', ”)
|
||||
func getOwnerFromTags(tags map[string]string) string {
|
||||
if owner, ok := tags["owner"]; ok {
|
||||
return strings.ToLower(owner)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (*FakeQuerier) AcquireLock(_ context.Context, _ int64) error {
|
||||
return xerrors.New("AcquireLock must only be called within a transaction")
|
||||
}
|
||||
@@ -2773,6 +2781,63 @@ func (q *FakeQuerier) GetDeploymentWorkspaceStats(ctx context.Context) (database
|
||||
return stat, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetEligibleProvisionerDaemonsByProvisionerJobIDs(_ context.Context, provisionerJobIds []uuid.UUID) ([]database.GetEligibleProvisionerDaemonsByProvisionerJobIDsRow, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
results := make([]database.GetEligibleProvisionerDaemonsByProvisionerJobIDsRow, 0)
|
||||
seen := make(map[string]struct{}) // Track unique combinations
|
||||
|
||||
for _, jobID := range provisionerJobIds {
|
||||
var job database.ProvisionerJob
|
||||
found := false
|
||||
for _, j := range q.provisionerJobs {
|
||||
if j.ID == jobID {
|
||||
job = j
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, daemon := range q.provisionerDaemons {
|
||||
if daemon.OrganizationID != job.OrganizationID {
|
||||
continue
|
||||
}
|
||||
|
||||
if !tagsSubset(job.Tags, daemon.Tags) {
|
||||
continue
|
||||
}
|
||||
|
||||
provisionerMatches := false
|
||||
for _, p := range daemon.Provisioners {
|
||||
if p == job.Provisioner {
|
||||
provisionerMatches = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !provisionerMatches {
|
||||
continue
|
||||
}
|
||||
|
||||
key := jobID.String() + "-" + daemon.ID.String()
|
||||
if _, exists := seen[key]; exists {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
|
||||
results = append(results, database.GetEligibleProvisionerDaemonsByProvisionerJobIDsRow{
|
||||
JobID: jobID,
|
||||
ProvisionerDaemon: daemon,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetExternalAuthLink(_ context.Context, arg database.GetExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.ExternalAuthLink{}, err
|
||||
@@ -10344,25 +10409,26 @@ func (q *FakeQuerier) UpsertOAuthSigningKey(_ context.Context, value string) err
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpsertProvisionerDaemon(_ context.Context, arg database.UpsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.ProvisionerDaemon{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
for _, d := range q.provisionerDaemons {
|
||||
if d.Name == arg.Name {
|
||||
if d.Tags[provisionersdk.TagScope] == provisionersdk.ScopeOrganization && arg.Tags[provisionersdk.TagOwner] != "" {
|
||||
continue
|
||||
}
|
||||
if d.Tags[provisionersdk.TagScope] == provisionersdk.ScopeUser && arg.Tags[provisionersdk.TagOwner] != d.Tags[provisionersdk.TagOwner] {
|
||||
continue
|
||||
}
|
||||
|
||||
// Look for existing daemon using the same composite key as SQL
|
||||
for i, d := range q.provisionerDaemons {
|
||||
if d.OrganizationID == arg.OrganizationID &&
|
||||
d.Name == arg.Name &&
|
||||
getOwnerFromTags(d.Tags) == getOwnerFromTags(arg.Tags) {
|
||||
d.Provisioners = arg.Provisioners
|
||||
d.Tags = maps.Clone(arg.Tags)
|
||||
d.Version = arg.Version
|
||||
d.LastSeenAt = arg.LastSeenAt
|
||||
d.Version = arg.Version
|
||||
d.APIVersion = arg.APIVersion
|
||||
d.OrganizationID = arg.OrganizationID
|
||||
d.KeyID = arg.KeyID
|
||||
q.provisionerDaemons[i] = d
|
||||
return d, nil
|
||||
}
|
||||
}
|
||||
@@ -10372,7 +10438,6 @@ func (q *FakeQuerier) UpsertProvisionerDaemon(_ context.Context, arg database.Up
|
||||
Name: arg.Name,
|
||||
Provisioners: arg.Provisioners,
|
||||
Tags: maps.Clone(arg.Tags),
|
||||
ReplicaID: uuid.NullUUID{},
|
||||
LastSeenAt: arg.LastSeenAt,
|
||||
Version: arg.Version,
|
||||
APIVersion: arg.APIVersion,
|
||||
|
||||
Reference in New Issue
Block a user