mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: improve resources_monitoring for OOM & OOD monitoring (#16241)
As requested for [this issue](https://github.com/coder/internal/issues/245) we need to have a new resource `resources_monitoring` in the agent. It needs to be parsed from the provisioner and inserted into a new db table.
This commit is contained in:
Generated
+2
@@ -13475,6 +13475,7 @@ const docTemplate = `{
|
||||
"template",
|
||||
"user",
|
||||
"workspace",
|
||||
"workspace_agent_resource_monitor",
|
||||
"workspace_dormant",
|
||||
"workspace_proxy"
|
||||
],
|
||||
@@ -13510,6 +13511,7 @@ const docTemplate = `{
|
||||
"ResourceTemplate",
|
||||
"ResourceUser",
|
||||
"ResourceWorkspace",
|
||||
"ResourceWorkspaceAgentResourceMonitor",
|
||||
"ResourceWorkspaceDormant",
|
||||
"ResourceWorkspaceProxy"
|
||||
]
|
||||
|
||||
Generated
+2
@@ -12178,6 +12178,7 @@
|
||||
"template",
|
||||
"user",
|
||||
"workspace",
|
||||
"workspace_agent_resource_monitor",
|
||||
"workspace_dormant",
|
||||
"workspace_proxy"
|
||||
],
|
||||
@@ -12213,6 +12214,7 @@
|
||||
"ResourceTemplate",
|
||||
"ResourceUser",
|
||||
"ResourceWorkspace",
|
||||
"ResourceWorkspaceAgentResourceMonitor",
|
||||
"ResourceWorkspaceDormant",
|
||||
"ResourceWorkspaceProxy"
|
||||
]
|
||||
|
||||
@@ -1391,6 +1391,14 @@ func (q *querier) FavoriteWorkspace(ctx context.Context, id uuid.UUID) error {
|
||||
return update(q.log, q.auth, fetch, q.db.FavoriteWorkspace)(ctx, id)
|
||||
}
|
||||
|
||||
func (q *querier) FetchMemoryResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspaceAgentResourceMonitor); err != nil {
|
||||
return database.WorkspaceAgentMemoryResourceMonitor{}, err
|
||||
}
|
||||
|
||||
return q.db.FetchMemoryResourceMonitorsByAgentID(ctx, agentID)
|
||||
}
|
||||
|
||||
func (q *querier) FetchNewMessageMetadata(ctx context.Context, arg database.FetchNewMessageMetadataParams) (database.FetchNewMessageMetadataRow, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceNotificationMessage); err != nil {
|
||||
return database.FetchNewMessageMetadataRow{}, err
|
||||
@@ -1398,6 +1406,14 @@ func (q *querier) FetchNewMessageMetadata(ctx context.Context, arg database.Fetc
|
||||
return q.db.FetchNewMessageMetadata(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) FetchVolumesResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) ([]database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspaceAgentResourceMonitor); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return q.db.FetchVolumesResourceMonitorsByAgentID(ctx, agentID)
|
||||
}
|
||||
|
||||
func (q *querier) GetAPIKeyByID(ctx context.Context, id string) (database.APIKey, error) {
|
||||
return fetch(q.log, q.auth, q.db.GetAPIKeyByID)(ctx, id)
|
||||
}
|
||||
@@ -3003,6 +3019,14 @@ func (q *querier) InsertLicense(ctx context.Context, arg database.InsertLicenseP
|
||||
return q.db.InsertLicense(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertMemoryResourceMonitor(ctx context.Context, arg database.InsertMemoryResourceMonitorParams) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceWorkspaceAgentResourceMonitor); err != nil {
|
||||
return database.WorkspaceAgentMemoryResourceMonitor{}, err
|
||||
}
|
||||
|
||||
return q.db.InsertMemoryResourceMonitor(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertMissingGroups(ctx context.Context, arg database.InsertMissingGroupsParams) ([]database.Group, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
@@ -3195,6 +3219,14 @@ func (q *querier) InsertUserLink(ctx context.Context, arg database.InsertUserLin
|
||||
return q.db.InsertUserLink(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertVolumeResourceMonitor(ctx context.Context, arg database.InsertVolumeResourceMonitorParams) (database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceWorkspaceAgentResourceMonitor); err != nil {
|
||||
return database.WorkspaceAgentVolumeResourceMonitor{}, err
|
||||
}
|
||||
|
||||
return q.db.InsertVolumeResourceMonitor(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertWorkspace(ctx context.Context, arg database.InsertWorkspaceParams) (database.WorkspaceTable, error) {
|
||||
obj := rbac.ResourceWorkspace.WithOwner(arg.OwnerID.String()).InOrg(arg.OrganizationID)
|
||||
tpl, err := q.GetTemplateByID(ctx, arg.TemplateID)
|
||||
|
||||
@@ -4562,3 +4562,96 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppTokens() {
|
||||
}).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionDelete)
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestResourcesMonitor() {
|
||||
s.Run("InsertMemoryResourceMonitor", s.Subtest(func(db database.Store, check *expects) {
|
||||
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
|
||||
check.Args(database.InsertMemoryResourceMonitorParams{}).Asserts(rbac.ResourceWorkspaceAgentResourceMonitor, policy.ActionCreate)
|
||||
}))
|
||||
|
||||
s.Run("InsertVolumeResourceMonitor", s.Subtest(func(db database.Store, check *expects) {
|
||||
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
|
||||
check.Args(database.InsertVolumeResourceMonitorParams{}).Asserts(rbac.ResourceWorkspaceAgentResourceMonitor, policy.ActionCreate)
|
||||
}))
|
||||
|
||||
s.Run("FetchMemoryResourceMonitorsByAgentID", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
o := dbgen.Organization(s.T(), db, database.Organization{})
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{
|
||||
OrganizationID: o.ID,
|
||||
CreatedBy: u.ID,
|
||||
})
|
||||
tv := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true},
|
||||
OrganizationID: o.ID,
|
||||
CreatedBy: u.ID,
|
||||
})
|
||||
w := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
|
||||
TemplateID: tpl.ID,
|
||||
OrganizationID: o.ID,
|
||||
OwnerID: u.ID,
|
||||
})
|
||||
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
|
||||
Type: database.ProvisionerJobTypeWorkspaceBuild,
|
||||
})
|
||||
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
|
||||
JobID: j.ID,
|
||||
WorkspaceID: w.ID,
|
||||
TemplateVersionID: tv.ID,
|
||||
})
|
||||
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: b.JobID})
|
||||
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
|
||||
dbgen.WorkspaceAgentMemoryResourceMonitor(s.T(), db, database.WorkspaceAgentMemoryResourceMonitor{
|
||||
AgentID: agt.ID,
|
||||
Enabled: true,
|
||||
Threshold: 80,
|
||||
CreatedAt: dbtime.Now(),
|
||||
})
|
||||
|
||||
monitor, err := db.FetchMemoryResourceMonitorsByAgentID(context.Background(), agt.ID)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
check.Args(agt.ID).Asserts(rbac.ResourceWorkspaceAgentResourceMonitor, policy.ActionRead).Returns(monitor)
|
||||
}))
|
||||
|
||||
s.Run("FetchVolumesResourceMonitorsByAgentID", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
o := dbgen.Organization(s.T(), db, database.Organization{})
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{
|
||||
OrganizationID: o.ID,
|
||||
CreatedBy: u.ID,
|
||||
})
|
||||
tv := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true},
|
||||
OrganizationID: o.ID,
|
||||
CreatedBy: u.ID,
|
||||
})
|
||||
w := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
|
||||
TemplateID: tpl.ID,
|
||||
OrganizationID: o.ID,
|
||||
OwnerID: u.ID,
|
||||
})
|
||||
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
|
||||
Type: database.ProvisionerJobTypeWorkspaceBuild,
|
||||
})
|
||||
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
|
||||
JobID: j.ID,
|
||||
WorkspaceID: w.ID,
|
||||
TemplateVersionID: tv.ID,
|
||||
})
|
||||
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: b.JobID})
|
||||
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
|
||||
dbgen.WorkspaceAgentVolumeResourceMonitor(s.T(), db, database.WorkspaceAgentVolumeResourceMonitor{
|
||||
AgentID: agt.ID,
|
||||
Path: "/var/lib",
|
||||
Enabled: true,
|
||||
Threshold: 80,
|
||||
CreatedAt: dbtime.Now(),
|
||||
})
|
||||
|
||||
monitors, err := db.FetchVolumesResourceMonitorsByAgentID(context.Background(), agt.ID)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
check.Args(agt.ID).Asserts(rbac.ResourceWorkspaceAgentResourceMonitor, policy.ActionRead).Returns(monitors)
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1032,6 +1032,29 @@ func OAuth2ProviderAppToken(t testing.TB, db database.Store, seed database.OAuth
|
||||
return token
|
||||
}
|
||||
|
||||
func WorkspaceAgentMemoryResourceMonitor(t testing.TB, db database.Store, seed database.WorkspaceAgentMemoryResourceMonitor) database.WorkspaceAgentMemoryResourceMonitor {
|
||||
monitor, err := db.InsertMemoryResourceMonitor(genCtx, database.InsertMemoryResourceMonitorParams{
|
||||
AgentID: takeFirst(seed.AgentID, uuid.New()),
|
||||
Enabled: takeFirst(seed.Enabled, true),
|
||||
Threshold: takeFirst(seed.Threshold, 100),
|
||||
CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
|
||||
})
|
||||
require.NoError(t, err, "insert workspace agent memory resource monitor")
|
||||
return monitor
|
||||
}
|
||||
|
||||
func WorkspaceAgentVolumeResourceMonitor(t testing.TB, db database.Store, seed database.WorkspaceAgentVolumeResourceMonitor) database.WorkspaceAgentVolumeResourceMonitor {
|
||||
monitor, err := db.InsertVolumeResourceMonitor(genCtx, database.InsertVolumeResourceMonitorParams{
|
||||
AgentID: takeFirst(seed.AgentID, uuid.New()),
|
||||
Path: takeFirst(seed.Path, "/"),
|
||||
Enabled: takeFirst(seed.Enabled, true),
|
||||
Threshold: takeFirst(seed.Threshold, 100),
|
||||
CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
|
||||
})
|
||||
require.NoError(t, err, "insert workspace agent volume resource monitor")
|
||||
return monitor
|
||||
}
|
||||
|
||||
func CustomRole(t testing.TB, db database.Store, seed database.CustomRole) database.CustomRole {
|
||||
role, err := db.InsertCustomRole(genCtx, database.InsertCustomRoleParams{
|
||||
Name: takeFirst(seed.Name, strings.ToLower(testutil.GetRandomName(t))),
|
||||
|
||||
+110
-50
@@ -191,56 +191,58 @@ type data struct {
|
||||
userLinks []database.UserLink
|
||||
|
||||
// New tables
|
||||
auditLogs []database.AuditLog
|
||||
cryptoKeys []database.CryptoKey
|
||||
dbcryptKeys []database.DBCryptKey
|
||||
files []database.File
|
||||
externalAuthLinks []database.ExternalAuthLink
|
||||
gitSSHKey []database.GitSSHKey
|
||||
groupMembers []database.GroupMemberTable
|
||||
groups []database.Group
|
||||
jfrogXRayScans []database.JfrogXrayScan
|
||||
licenses []database.License
|
||||
notificationMessages []database.NotificationMessage
|
||||
notificationPreferences []database.NotificationPreference
|
||||
notificationReportGeneratorLogs []database.NotificationReportGeneratorLog
|
||||
oauth2ProviderApps []database.OAuth2ProviderApp
|
||||
oauth2ProviderAppSecrets []database.OAuth2ProviderAppSecret
|
||||
oauth2ProviderAppCodes []database.OAuth2ProviderAppCode
|
||||
oauth2ProviderAppTokens []database.OAuth2ProviderAppToken
|
||||
parameterSchemas []database.ParameterSchema
|
||||
provisionerDaemons []database.ProvisionerDaemon
|
||||
provisionerJobLogs []database.ProvisionerJobLog
|
||||
provisionerJobs []database.ProvisionerJob
|
||||
provisionerKeys []database.ProvisionerKey
|
||||
replicas []database.Replica
|
||||
templateVersions []database.TemplateVersionTable
|
||||
templateVersionParameters []database.TemplateVersionParameter
|
||||
templateVersionVariables []database.TemplateVersionVariable
|
||||
templateVersionWorkspaceTags []database.TemplateVersionWorkspaceTag
|
||||
templates []database.TemplateTable
|
||||
templateUsageStats []database.TemplateUsageStat
|
||||
workspaceAgents []database.WorkspaceAgent
|
||||
workspaceAgentMetadata []database.WorkspaceAgentMetadatum
|
||||
workspaceAgentLogs []database.WorkspaceAgentLog
|
||||
workspaceAgentLogSources []database.WorkspaceAgentLogSource
|
||||
workspaceAgentPortShares []database.WorkspaceAgentPortShare
|
||||
workspaceAgentScriptTimings []database.WorkspaceAgentScriptTiming
|
||||
workspaceAgentScripts []database.WorkspaceAgentScript
|
||||
workspaceAgentStats []database.WorkspaceAgentStat
|
||||
workspaceApps []database.WorkspaceApp
|
||||
workspaceAppStatsLastInsertID int64
|
||||
workspaceAppStats []database.WorkspaceAppStat
|
||||
workspaceBuilds []database.WorkspaceBuild
|
||||
workspaceBuildParameters []database.WorkspaceBuildParameter
|
||||
workspaceResourceMetadata []database.WorkspaceResourceMetadatum
|
||||
workspaceResources []database.WorkspaceResource
|
||||
workspaceModules []database.WorkspaceModule
|
||||
workspaces []database.WorkspaceTable
|
||||
workspaceProxies []database.WorkspaceProxy
|
||||
customRoles []database.CustomRole
|
||||
provisionerJobTimings []database.ProvisionerJobTiming
|
||||
runtimeConfig map[string]string
|
||||
auditLogs []database.AuditLog
|
||||
cryptoKeys []database.CryptoKey
|
||||
dbcryptKeys []database.DBCryptKey
|
||||
files []database.File
|
||||
externalAuthLinks []database.ExternalAuthLink
|
||||
gitSSHKey []database.GitSSHKey
|
||||
groupMembers []database.GroupMemberTable
|
||||
groups []database.Group
|
||||
jfrogXRayScans []database.JfrogXrayScan
|
||||
licenses []database.License
|
||||
notificationMessages []database.NotificationMessage
|
||||
notificationPreferences []database.NotificationPreference
|
||||
notificationReportGeneratorLogs []database.NotificationReportGeneratorLog
|
||||
oauth2ProviderApps []database.OAuth2ProviderApp
|
||||
oauth2ProviderAppSecrets []database.OAuth2ProviderAppSecret
|
||||
oauth2ProviderAppCodes []database.OAuth2ProviderAppCode
|
||||
oauth2ProviderAppTokens []database.OAuth2ProviderAppToken
|
||||
parameterSchemas []database.ParameterSchema
|
||||
provisionerDaemons []database.ProvisionerDaemon
|
||||
provisionerJobLogs []database.ProvisionerJobLog
|
||||
provisionerJobs []database.ProvisionerJob
|
||||
provisionerKeys []database.ProvisionerKey
|
||||
replicas []database.Replica
|
||||
templateVersions []database.TemplateVersionTable
|
||||
templateVersionParameters []database.TemplateVersionParameter
|
||||
templateVersionVariables []database.TemplateVersionVariable
|
||||
templateVersionWorkspaceTags []database.TemplateVersionWorkspaceTag
|
||||
templates []database.TemplateTable
|
||||
templateUsageStats []database.TemplateUsageStat
|
||||
workspaceAgents []database.WorkspaceAgent
|
||||
workspaceAgentMetadata []database.WorkspaceAgentMetadatum
|
||||
workspaceAgentLogs []database.WorkspaceAgentLog
|
||||
workspaceAgentLogSources []database.WorkspaceAgentLogSource
|
||||
workspaceAgentPortShares []database.WorkspaceAgentPortShare
|
||||
workspaceAgentScriptTimings []database.WorkspaceAgentScriptTiming
|
||||
workspaceAgentScripts []database.WorkspaceAgentScript
|
||||
workspaceAgentStats []database.WorkspaceAgentStat
|
||||
workspaceAgentMemoryResourceMonitors []database.WorkspaceAgentMemoryResourceMonitor
|
||||
workspaceAgentVolumeResourceMonitors []database.WorkspaceAgentVolumeResourceMonitor
|
||||
workspaceApps []database.WorkspaceApp
|
||||
workspaceAppStatsLastInsertID int64
|
||||
workspaceAppStats []database.WorkspaceAppStat
|
||||
workspaceBuilds []database.WorkspaceBuild
|
||||
workspaceBuildParameters []database.WorkspaceBuildParameter
|
||||
workspaceResourceMetadata []database.WorkspaceResourceMetadatum
|
||||
workspaceResources []database.WorkspaceResource
|
||||
workspaceModules []database.WorkspaceModule
|
||||
workspaces []database.WorkspaceTable
|
||||
workspaceProxies []database.WorkspaceProxy
|
||||
customRoles []database.CustomRole
|
||||
provisionerJobTimings []database.ProvisionerJobTiming
|
||||
runtimeConfig map[string]string
|
||||
// Locks is a map of lock names. Any keys within the map are currently
|
||||
// locked.
|
||||
locks map[int64]struct{}
|
||||
@@ -2357,6 +2359,16 @@ func (q *FakeQuerier) FavoriteWorkspace(_ context.Context, arg uuid.UUID) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) FetchMemoryResourceMonitorsByAgentID(_ context.Context, agentID uuid.UUID) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
for _, monitor := range q.workspaceAgentMemoryResourceMonitors {
|
||||
if monitor.AgentID == agentID {
|
||||
return monitor, nil
|
||||
}
|
||||
}
|
||||
|
||||
return database.WorkspaceAgentMemoryResourceMonitor{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) FetchNewMessageMetadata(_ context.Context, arg database.FetchNewMessageMetadataParams) (database.FetchNewMessageMetadataRow, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
@@ -2389,6 +2401,18 @@ func (q *FakeQuerier) FetchNewMessageMetadata(_ context.Context, arg database.Fe
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) FetchVolumesResourceMonitorsByAgentID(_ context.Context, agentID uuid.UUID) ([]database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
monitors := []database.WorkspaceAgentVolumeResourceMonitor{}
|
||||
|
||||
for _, monitor := range q.workspaceAgentVolumeResourceMonitors {
|
||||
if monitor.AgentID == agentID {
|
||||
monitors = append(monitors, monitor)
|
||||
}
|
||||
}
|
||||
|
||||
return monitors, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetAPIKeyByID(_ context.Context, id string) (database.APIKey, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@@ -7795,6 +7819,21 @@ func (q *FakeQuerier) InsertLicense(
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) InsertMemoryResourceMonitor(_ context.Context, arg database.InsertMemoryResourceMonitorParams) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentMemoryResourceMonitor{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
monitor := database.WorkspaceAgentMemoryResourceMonitor(arg)
|
||||
|
||||
q.workspaceAgentMemoryResourceMonitors = append(q.workspaceAgentMemoryResourceMonitors, monitor)
|
||||
return monitor, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) InsertMissingGroups(_ context.Context, arg database.InsertMissingGroupsParams) ([]database.Group, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
@@ -8422,6 +8461,27 @@ func (q *FakeQuerier) InsertUserLink(_ context.Context, args database.InsertUser
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) InsertVolumeResourceMonitor(_ context.Context, arg database.InsertVolumeResourceMonitorParams) (database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentVolumeResourceMonitor{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
monitor := database.WorkspaceAgentVolumeResourceMonitor{
|
||||
AgentID: arg.AgentID,
|
||||
Path: arg.Path,
|
||||
Enabled: arg.Enabled,
|
||||
Threshold: arg.Threshold,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
}
|
||||
|
||||
q.workspaceAgentVolumeResourceMonitors = append(q.workspaceAgentVolumeResourceMonitors, monitor)
|
||||
return monitor, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) InsertWorkspace(_ context.Context, arg database.InsertWorkspaceParams) (database.WorkspaceTable, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.WorkspaceTable{}, err
|
||||
|
||||
@@ -434,6 +434,13 @@ func (m queryMetricsStore) FavoriteWorkspace(ctx context.Context, arg uuid.UUID)
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) FetchMemoryResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.FetchMemoryResourceMonitorsByAgentID(ctx, agentID)
|
||||
m.queryLatencies.WithLabelValues("FetchMemoryResourceMonitorsByAgentID").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) FetchNewMessageMetadata(ctx context.Context, arg database.FetchNewMessageMetadataParams) (database.FetchNewMessageMetadataRow, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.FetchNewMessageMetadata(ctx, arg)
|
||||
@@ -441,6 +448,13 @@ func (m queryMetricsStore) FetchNewMessageMetadata(ctx context.Context, arg data
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) FetchVolumesResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) ([]database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.FetchVolumesResourceMonitorsByAgentID(ctx, agentID)
|
||||
m.queryLatencies.WithLabelValues("FetchVolumesResourceMonitorsByAgentID").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetAPIKeyByID(ctx context.Context, id string) (database.APIKey, error) {
|
||||
start := time.Now()
|
||||
apiKey, err := m.s.GetAPIKeyByID(ctx, id)
|
||||
@@ -1841,6 +1855,13 @@ func (m queryMetricsStore) InsertLicense(ctx context.Context, arg database.Inser
|
||||
return license, err
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) InsertMemoryResourceMonitor(ctx context.Context, arg database.InsertMemoryResourceMonitorParams) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.InsertMemoryResourceMonitor(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("InsertMemoryResourceMonitor").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) InsertMissingGroups(ctx context.Context, arg database.InsertMissingGroupsParams) ([]database.Group, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.InsertMissingGroups(ctx, arg)
|
||||
@@ -1995,6 +2016,13 @@ func (m queryMetricsStore) InsertUserLink(ctx context.Context, arg database.Inse
|
||||
return link, err
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) InsertVolumeResourceMonitor(ctx context.Context, arg database.InsertVolumeResourceMonitorParams) (database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.InsertVolumeResourceMonitor(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("InsertVolumeResourceMonitor").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) InsertWorkspace(ctx context.Context, arg database.InsertWorkspaceParams) (database.WorkspaceTable, error) {
|
||||
start := time.Now()
|
||||
workspace, err := m.s.InsertWorkspace(ctx, arg)
|
||||
|
||||
@@ -771,6 +771,21 @@ func (mr *MockStoreMockRecorder) FavoriteWorkspace(ctx, id any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FavoriteWorkspace", reflect.TypeOf((*MockStore)(nil).FavoriteWorkspace), ctx, id)
|
||||
}
|
||||
|
||||
// FetchMemoryResourceMonitorsByAgentID mocks base method.
|
||||
func (m *MockStore) FetchMemoryResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "FetchMemoryResourceMonitorsByAgentID", ctx, agentID)
|
||||
ret0, _ := ret[0].(database.WorkspaceAgentMemoryResourceMonitor)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// FetchMemoryResourceMonitorsByAgentID indicates an expected call of FetchMemoryResourceMonitorsByAgentID.
|
||||
func (mr *MockStoreMockRecorder) FetchMemoryResourceMonitorsByAgentID(ctx, agentID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchMemoryResourceMonitorsByAgentID", reflect.TypeOf((*MockStore)(nil).FetchMemoryResourceMonitorsByAgentID), ctx, agentID)
|
||||
}
|
||||
|
||||
// FetchNewMessageMetadata mocks base method.
|
||||
func (m *MockStore) FetchNewMessageMetadata(ctx context.Context, arg database.FetchNewMessageMetadataParams) (database.FetchNewMessageMetadataRow, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -786,6 +801,21 @@ func (mr *MockStoreMockRecorder) FetchNewMessageMetadata(ctx, arg any) *gomock.C
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchNewMessageMetadata", reflect.TypeOf((*MockStore)(nil).FetchNewMessageMetadata), ctx, arg)
|
||||
}
|
||||
|
||||
// FetchVolumesResourceMonitorsByAgentID mocks base method.
|
||||
func (m *MockStore) FetchVolumesResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) ([]database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "FetchVolumesResourceMonitorsByAgentID", ctx, agentID)
|
||||
ret0, _ := ret[0].([]database.WorkspaceAgentVolumeResourceMonitor)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// FetchVolumesResourceMonitorsByAgentID indicates an expected call of FetchVolumesResourceMonitorsByAgentID.
|
||||
func (mr *MockStoreMockRecorder) FetchVolumesResourceMonitorsByAgentID(ctx, agentID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchVolumesResourceMonitorsByAgentID", reflect.TypeOf((*MockStore)(nil).FetchVolumesResourceMonitorsByAgentID), ctx, agentID)
|
||||
}
|
||||
|
||||
// GetAPIKeyByID mocks base method.
|
||||
func (m *MockStore) GetAPIKeyByID(ctx context.Context, id string) (database.APIKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -3901,6 +3931,21 @@ func (mr *MockStoreMockRecorder) InsertLicense(ctx, arg any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertLicense", reflect.TypeOf((*MockStore)(nil).InsertLicense), ctx, arg)
|
||||
}
|
||||
|
||||
// InsertMemoryResourceMonitor mocks base method.
|
||||
func (m *MockStore) InsertMemoryResourceMonitor(ctx context.Context, arg database.InsertMemoryResourceMonitorParams) (database.WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InsertMemoryResourceMonitor", ctx, arg)
|
||||
ret0, _ := ret[0].(database.WorkspaceAgentMemoryResourceMonitor)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// InsertMemoryResourceMonitor indicates an expected call of InsertMemoryResourceMonitor.
|
||||
func (mr *MockStoreMockRecorder) InsertMemoryResourceMonitor(ctx, arg any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertMemoryResourceMonitor", reflect.TypeOf((*MockStore)(nil).InsertMemoryResourceMonitor), ctx, arg)
|
||||
}
|
||||
|
||||
// InsertMissingGroups mocks base method.
|
||||
func (m *MockStore) InsertMissingGroups(ctx context.Context, arg database.InsertMissingGroupsParams) ([]database.Group, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -4227,6 +4272,21 @@ func (mr *MockStoreMockRecorder) InsertUserLink(ctx, arg any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertUserLink", reflect.TypeOf((*MockStore)(nil).InsertUserLink), ctx, arg)
|
||||
}
|
||||
|
||||
// InsertVolumeResourceMonitor mocks base method.
|
||||
func (m *MockStore) InsertVolumeResourceMonitor(ctx context.Context, arg database.InsertVolumeResourceMonitorParams) (database.WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InsertVolumeResourceMonitor", ctx, arg)
|
||||
ret0, _ := ret[0].(database.WorkspaceAgentVolumeResourceMonitor)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// InsertVolumeResourceMonitor indicates an expected call of InsertVolumeResourceMonitor.
|
||||
func (mr *MockStoreMockRecorder) InsertVolumeResourceMonitor(ctx, arg any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertVolumeResourceMonitor", reflect.TypeOf((*MockStore)(nil).InsertVolumeResourceMonitor), ctx, arg)
|
||||
}
|
||||
|
||||
// InsertWorkspace mocks base method.
|
||||
func (m *MockStore) InsertWorkspace(ctx context.Context, arg database.InsertWorkspaceParams) (database.WorkspaceTable, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Generated
+27
@@ -1486,6 +1486,13 @@ CREATE UNLOGGED TABLE workspace_agent_logs (
|
||||
log_source_id uuid DEFAULT '00000000-0000-0000-0000-000000000000'::uuid NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agent_memory_resource_monitors (
|
||||
agent_id uuid NOT NULL,
|
||||
enabled boolean NOT NULL,
|
||||
threshold integer NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNLOGGED TABLE workspace_agent_metadata (
|
||||
workspace_agent_id uuid NOT NULL,
|
||||
display_name character varying(127) NOT NULL,
|
||||
@@ -1563,6 +1570,14 @@ CREATE TABLE workspace_agent_stats (
|
||||
usage boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agent_volume_resource_monitors (
|
||||
agent_id uuid NOT NULL,
|
||||
enabled boolean NOT NULL,
|
||||
threshold integer NOT NULL,
|
||||
path text NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agents (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
@@ -2072,6 +2087,9 @@ ALTER TABLE ONLY users
|
||||
ALTER TABLE ONLY workspace_agent_log_sources
|
||||
ADD CONSTRAINT workspace_agent_log_sources_pkey PRIMARY KEY (workspace_agent_id, id);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_memory_resource_monitors
|
||||
ADD CONSTRAINT workspace_agent_memory_resource_monitors_pkey PRIMARY KEY (agent_id);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_metadata
|
||||
ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key);
|
||||
|
||||
@@ -2087,6 +2105,9 @@ ALTER TABLE ONLY workspace_agent_scripts
|
||||
ALTER TABLE ONLY workspace_agent_logs
|
||||
ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_volume_resource_monitors
|
||||
ADD CONSTRAINT workspace_agent_volume_resource_monitors_pkey PRIMARY KEY (agent_id, path);
|
||||
|
||||
ALTER TABLE ONLY workspace_agents
|
||||
ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id);
|
||||
|
||||
@@ -2465,6 +2486,9 @@ ALTER TABLE ONLY user_status_changes
|
||||
ALTER TABLE ONLY workspace_agent_log_sources
|
||||
ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_memory_resource_monitors
|
||||
ADD CONSTRAINT workspace_agent_memory_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_metadata
|
||||
ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
@@ -2480,6 +2504,9 @@ ALTER TABLE ONLY workspace_agent_scripts
|
||||
ALTER TABLE ONLY workspace_agent_logs
|
||||
ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_volume_resource_monitors
|
||||
ADD CONSTRAINT workspace_agent_volume_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agents
|
||||
ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
@@ -53,11 +53,13 @@ const (
|
||||
ForeignKeyUserLinksUserID ForeignKeyConstraint = "user_links_user_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserStatusChangesUserID ForeignKeyConstraint = "user_status_changes_user_id_fkey" // ALTER TABLE ONLY user_status_changes ADD CONSTRAINT user_status_changes_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentMemoryResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_memory_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_memory_resource_monitors ADD CONSTRAINT workspace_agent_memory_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentScriptTimingsScriptID ForeignKeyConstraint = "workspace_agent_script_timings_script_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentVolumeResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_volume_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_volume_resource_monitors ADD CONSTRAINT workspace_agent_volume_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
|
||||
ForeignKeyWorkspaceAppStatsAgentID ForeignKeyConstraint = "workspace_app_stats_agent_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id);
|
||||
ForeignKeyWorkspaceAppStatsUserID ForeignKeyConstraint = "workspace_app_stats_user_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS workspace_agent_memory_resource_monitors;
|
||||
DROP TABLE IF EXISTS workspace_agent_volume_resource_monitors;
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE workspace_agent_memory_resource_monitors (
|
||||
agent_id uuid NOT NULL REFERENCES workspace_agents(id) ON DELETE CASCADE,
|
||||
enabled boolean NOT NULL,
|
||||
threshold integer NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
PRIMARY KEY (agent_id)
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agent_volume_resource_monitors (
|
||||
agent_id uuid NOT NULL REFERENCES workspace_agents(id) ON DELETE CASCADE,
|
||||
enabled boolean NOT NULL,
|
||||
threshold integer NOT NULL,
|
||||
path text NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
PRIMARY KEY (agent_id, path)
|
||||
);
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
INSERT INTO
|
||||
workspace_agent_memory_resource_monitors (
|
||||
agent_id,
|
||||
enabled,
|
||||
threshold,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
'45e89705-e09d-4850-bcec-f9a937f5d78d', -- uuid
|
||||
true,
|
||||
90,
|
||||
'2024-01-01 00:00:00'
|
||||
);
|
||||
|
||||
INSERT INTO
|
||||
workspace_agent_volume_resource_monitors (
|
||||
agent_id,
|
||||
path,
|
||||
enabled,
|
||||
threshold,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
'45e89705-e09d-4850-bcec-f9a937f5d78d', -- uuid
|
||||
'/',
|
||||
true,
|
||||
90,
|
||||
'2024-01-01 00:00:00'
|
||||
);
|
||||
|
||||
@@ -3152,6 +3152,13 @@ type WorkspaceAgentLogSource struct {
|
||||
Icon string `db:"icon" json:"icon"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentMemoryResourceMonitor struct {
|
||||
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Threshold int32 `db:"threshold" json:"threshold"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentMetadatum struct {
|
||||
WorkspaceAgentID uuid.UUID `db:"workspace_agent_id" json:"workspace_agent_id"`
|
||||
DisplayName string `db:"display_name" json:"display_name"`
|
||||
@@ -3219,6 +3226,14 @@ type WorkspaceAgentStat struct {
|
||||
Usage bool `db:"usage" json:"usage"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentVolumeResourceMonitor struct {
|
||||
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Threshold int32 `db:"threshold" json:"threshold"`
|
||||
Path string `db:"path" json:"path"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
type WorkspaceApp struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
|
||||
@@ -112,8 +112,10 @@ type sqlcQuerier interface {
|
||||
DisableForeignKeysAndTriggers(ctx context.Context) error
|
||||
EnqueueNotificationMessage(ctx context.Context, arg EnqueueNotificationMessageParams) error
|
||||
FavoriteWorkspace(ctx context.Context, id uuid.UUID) error
|
||||
FetchMemoryResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) (WorkspaceAgentMemoryResourceMonitor, error)
|
||||
// This is used to build up the notification_message's JSON payload.
|
||||
FetchNewMessageMetadata(ctx context.Context, arg FetchNewMessageMetadataParams) (FetchNewMessageMetadataRow, error)
|
||||
FetchVolumesResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) ([]WorkspaceAgentVolumeResourceMonitor, error)
|
||||
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
|
||||
// there is no unique constraint on empty token names
|
||||
GetAPIKeyByName(ctx context.Context, arg GetAPIKeyByNameParams) (APIKey, error)
|
||||
@@ -390,6 +392,7 @@ type sqlcQuerier interface {
|
||||
InsertGroup(ctx context.Context, arg InsertGroupParams) (Group, error)
|
||||
InsertGroupMember(ctx context.Context, arg InsertGroupMemberParams) error
|
||||
InsertLicense(ctx context.Context, arg InsertLicenseParams) (License, error)
|
||||
InsertMemoryResourceMonitor(ctx context.Context, arg InsertMemoryResourceMonitorParams) (WorkspaceAgentMemoryResourceMonitor, error)
|
||||
// Inserts any group by name that does not exist. All new groups are given
|
||||
// a random uuid, are inserted into the same organization. They have the default
|
||||
// values for avatar, display name, and quota allowance (all zero values).
|
||||
@@ -419,6 +422,7 @@ type sqlcQuerier interface {
|
||||
// InsertUserGroupsByName adds a user to all provided groups, if they exist.
|
||||
InsertUserGroupsByName(ctx context.Context, arg InsertUserGroupsByNameParams) error
|
||||
InsertUserLink(ctx context.Context, arg InsertUserLinkParams) (UserLink, error)
|
||||
InsertVolumeResourceMonitor(ctx context.Context, arg InsertVolumeResourceMonitorParams) (WorkspaceAgentVolumeResourceMonitor, error)
|
||||
InsertWorkspace(ctx context.Context, arg InsertWorkspaceParams) (WorkspaceTable, error)
|
||||
InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error)
|
||||
InsertWorkspaceAgentLogSources(ctx context.Context, arg InsertWorkspaceAgentLogSourcesParams) ([]WorkspaceAgentLogSource, error)
|
||||
|
||||
@@ -11765,6 +11765,141 @@ func (q *sqlQuerier) UpsertWorkspaceAgentPortShare(ctx context.Context, arg Upse
|
||||
return i, err
|
||||
}
|
||||
|
||||
const fetchMemoryResourceMonitorsByAgentID = `-- name: FetchMemoryResourceMonitorsByAgentID :one
|
||||
SELECT
|
||||
agent_id, enabled, threshold, created_at
|
||||
FROM
|
||||
workspace_agent_memory_resource_monitors
|
||||
WHERE
|
||||
agent_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) FetchMemoryResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) (WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
row := q.db.QueryRowContext(ctx, fetchMemoryResourceMonitorsByAgentID, agentID)
|
||||
var i WorkspaceAgentMemoryResourceMonitor
|
||||
err := row.Scan(
|
||||
&i.AgentID,
|
||||
&i.Enabled,
|
||||
&i.Threshold,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const fetchVolumesResourceMonitorsByAgentID = `-- name: FetchVolumesResourceMonitorsByAgentID :many
|
||||
SELECT
|
||||
agent_id, enabled, threshold, path, created_at
|
||||
FROM
|
||||
workspace_agent_volume_resource_monitors
|
||||
WHERE
|
||||
agent_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) FetchVolumesResourceMonitorsByAgentID(ctx context.Context, agentID uuid.UUID) ([]WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
rows, err := q.db.QueryContext(ctx, fetchVolumesResourceMonitorsByAgentID, agentID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []WorkspaceAgentVolumeResourceMonitor
|
||||
for rows.Next() {
|
||||
var i WorkspaceAgentVolumeResourceMonitor
|
||||
if err := rows.Scan(
|
||||
&i.AgentID,
|
||||
&i.Enabled,
|
||||
&i.Threshold,
|
||||
&i.Path,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const insertMemoryResourceMonitor = `-- name: InsertMemoryResourceMonitor :one
|
||||
INSERT INTO
|
||||
workspace_agent_memory_resource_monitors (
|
||||
agent_id,
|
||||
enabled,
|
||||
threshold,
|
||||
created_at
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4) RETURNING agent_id, enabled, threshold, created_at
|
||||
`
|
||||
|
||||
type InsertMemoryResourceMonitorParams struct {
|
||||
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Threshold int32 `db:"threshold" json:"threshold"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertMemoryResourceMonitor(ctx context.Context, arg InsertMemoryResourceMonitorParams) (WorkspaceAgentMemoryResourceMonitor, error) {
|
||||
row := q.db.QueryRowContext(ctx, insertMemoryResourceMonitor,
|
||||
arg.AgentID,
|
||||
arg.Enabled,
|
||||
arg.Threshold,
|
||||
arg.CreatedAt,
|
||||
)
|
||||
var i WorkspaceAgentMemoryResourceMonitor
|
||||
err := row.Scan(
|
||||
&i.AgentID,
|
||||
&i.Enabled,
|
||||
&i.Threshold,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertVolumeResourceMonitor = `-- name: InsertVolumeResourceMonitor :one
|
||||
INSERT INTO
|
||||
workspace_agent_volume_resource_monitors (
|
||||
agent_id,
|
||||
path,
|
||||
enabled,
|
||||
threshold,
|
||||
created_at
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5) RETURNING agent_id, enabled, threshold, path, created_at
|
||||
`
|
||||
|
||||
type InsertVolumeResourceMonitorParams struct {
|
||||
AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
|
||||
Path string `db:"path" json:"path"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Threshold int32 `db:"threshold" json:"threshold"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertVolumeResourceMonitor(ctx context.Context, arg InsertVolumeResourceMonitorParams) (WorkspaceAgentVolumeResourceMonitor, error) {
|
||||
row := q.db.QueryRowContext(ctx, insertVolumeResourceMonitor,
|
||||
arg.AgentID,
|
||||
arg.Path,
|
||||
arg.Enabled,
|
||||
arg.Threshold,
|
||||
arg.CreatedAt,
|
||||
)
|
||||
var i WorkspaceAgentVolumeResourceMonitor
|
||||
err := row.Scan(
|
||||
&i.AgentID,
|
||||
&i.Enabled,
|
||||
&i.Threshold,
|
||||
&i.Path,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteOldWorkspaceAgentLogs = `-- name: DeleteOldWorkspaceAgentLogs :exec
|
||||
WITH
|
||||
latest_builds AS (
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
-- name: FetchMemoryResourceMonitorsByAgentID :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
workspace_agent_memory_resource_monitors
|
||||
WHERE
|
||||
agent_id = $1;
|
||||
|
||||
-- name: FetchVolumesResourceMonitorsByAgentID :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
workspace_agent_volume_resource_monitors
|
||||
WHERE
|
||||
agent_id = $1;
|
||||
|
||||
-- name: InsertMemoryResourceMonitor :one
|
||||
INSERT INTO
|
||||
workspace_agent_memory_resource_monitors (
|
||||
agent_id,
|
||||
enabled,
|
||||
threshold,
|
||||
created_at
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4) RETURNING *;
|
||||
|
||||
-- name: InsertVolumeResourceMonitor :one
|
||||
INSERT INTO
|
||||
workspace_agent_volume_resource_monitors (
|
||||
agent_id,
|
||||
path,
|
||||
enabled,
|
||||
threshold,
|
||||
created_at
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5) RETURNING *;
|
||||
@@ -68,11 +68,13 @@ const (
|
||||
UniqueUserStatusChangesPkey UniqueConstraint = "user_status_changes_pkey" // ALTER TABLE ONLY user_status_changes ADD CONSTRAINT user_status_changes_pkey PRIMARY KEY (id);
|
||||
UniqueUsersPkey UniqueConstraint = "users_pkey" // ALTER TABLE ONLY users ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAgentLogSourcesPkey UniqueConstraint = "workspace_agent_log_sources_pkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_pkey PRIMARY KEY (workspace_agent_id, id);
|
||||
UniqueWorkspaceAgentMemoryResourceMonitorsPkey UniqueConstraint = "workspace_agent_memory_resource_monitors_pkey" // ALTER TABLE ONLY workspace_agent_memory_resource_monitors ADD CONSTRAINT workspace_agent_memory_resource_monitors_pkey PRIMARY KEY (agent_id);
|
||||
UniqueWorkspaceAgentMetadataPkey UniqueConstraint = "workspace_agent_metadata_pkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key);
|
||||
UniqueWorkspaceAgentPortSharePkey UniqueConstraint = "workspace_agent_port_share_pkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port);
|
||||
UniqueWorkspaceAgentScriptTimingsScriptIDStartedAtKey UniqueConstraint = "workspace_agent_script_timings_script_id_started_at_key" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_started_at_key UNIQUE (script_id, started_at);
|
||||
UniqueWorkspaceAgentScriptsIDKey UniqueConstraint = "workspace_agent_scripts_id_key" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id);
|
||||
UniqueWorkspaceAgentStartupLogsPkey UniqueConstraint = "workspace_agent_startup_logs_pkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAgentVolumeResourceMonitorsPkey UniqueConstraint = "workspace_agent_volume_resource_monitors_pkey" // ALTER TABLE ONLY workspace_agent_volume_resource_monitors ADD CONSTRAINT workspace_agent_volume_resource_monitors_pkey PRIMARY KEY (agent_id, path);
|
||||
UniqueWorkspaceAgentsPkey UniqueConstraint = "workspace_agents_pkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAppStatsPkey UniqueConstraint = "workspace_app_stats_pkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAppStatsUserIDAgentIDSessionIDKey UniqueConstraint = "workspace_app_stats_user_id_agent_id_session_id_key" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_user_id_agent_id_session_id_key UNIQUE (user_id, agent_id, session_id);
|
||||
|
||||
@@ -1927,6 +1927,32 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
|
||||
}
|
||||
}
|
||||
|
||||
if prAgent.ResourcesMonitoring != nil {
|
||||
if prAgent.ResourcesMonitoring.Memory != nil {
|
||||
_, err = db.InsertMemoryResourceMonitor(ctx, database.InsertMemoryResourceMonitorParams{
|
||||
AgentID: agentID,
|
||||
Enabled: prAgent.ResourcesMonitoring.Memory.Enabled,
|
||||
Threshold: prAgent.ResourcesMonitoring.Memory.Threshold,
|
||||
CreatedAt: dbtime.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to insert agent memory resource monitor into db: %w", err)
|
||||
}
|
||||
}
|
||||
for _, volume := range prAgent.ResourcesMonitoring.Volumes {
|
||||
_, err = db.InsertVolumeResourceMonitor(ctx, database.InsertVolumeResourceMonitorParams{
|
||||
AgentID: agentID,
|
||||
Path: volume.Path,
|
||||
Enabled: volume.Enabled,
|
||||
Threshold: volume.Threshold,
|
||||
CreatedAt: dbtime.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to insert agent volume resource monitor into db: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logSourceIDs := make([]uuid.UUID, 0, len(prAgent.Scripts))
|
||||
logSourceDisplayNames := make([]string, 0, len(prAgent.Scripts))
|
||||
logSourceIcons := make([]string, 0, len(prAgent.Scripts))
|
||||
|
||||
@@ -1874,6 +1874,57 @@ func TestInsertWorkspaceResource(t *testing.T) {
|
||||
// that all apps are disabled.
|
||||
require.Equal(t, []database.DisplayApp{}, agent.DisplayApps)
|
||||
})
|
||||
|
||||
t.Run("ResourcesMonitoring", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbmem.New()
|
||||
job := uuid.New()
|
||||
err := insert(db, job, &sdkproto.Resource{
|
||||
Name: "something",
|
||||
Type: "aws_instance",
|
||||
Agents: []*sdkproto.Agent{{
|
||||
DisplayApps: &sdkproto.DisplayApps{},
|
||||
ResourcesMonitoring: &sdkproto.ResourcesMonitoring{
|
||||
Memory: &sdkproto.MemoryResourceMonitor{
|
||||
Enabled: true,
|
||||
Threshold: 80,
|
||||
},
|
||||
Volumes: []*sdkproto.VolumeResourceMonitor{
|
||||
{
|
||||
Path: "/volume1",
|
||||
Enabled: true,
|
||||
Threshold: 90,
|
||||
},
|
||||
{
|
||||
Path: "/volume2",
|
||||
Enabled: true,
|
||||
Threshold: 50,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
resources, err := db.GetWorkspaceResourcesByJobID(ctx, job)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, resources, 1)
|
||||
agents, err := db.GetWorkspaceAgentsByResourceIDs(ctx, []uuid.UUID{resources[0].ID})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, agents, 1)
|
||||
|
||||
agent := agents[0]
|
||||
memMonitor, err := db.FetchMemoryResourceMonitorsByAgentID(ctx, agent.ID)
|
||||
require.NoError(t, err)
|
||||
volMonitors, err := db.FetchVolumesResourceMonitorsByAgentID(ctx, agent.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, int32(80), memMonitor.Threshold)
|
||||
require.Len(t, volMonitors, 2)
|
||||
require.Equal(t, int32(90), volMonitors[0].Threshold)
|
||||
require.Equal(t, "/volume1", volMonitors[0].Path)
|
||||
require.Equal(t, int32(50), volMonitors[1].Threshold)
|
||||
require.Equal(t, "/volume2", volMonitors[1].Path)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNotifications(t *testing.T) {
|
||||
|
||||
@@ -295,6 +295,14 @@ var (
|
||||
Type: "workspace",
|
||||
}
|
||||
|
||||
// ResourceWorkspaceAgentResourceMonitor
|
||||
// Valid Actions
|
||||
// - "ActionCreate" :: create workspace agent resource monitor
|
||||
// - "ActionRead" :: read workspace agent resource monitor
|
||||
ResourceWorkspaceAgentResourceMonitor = Object{
|
||||
Type: "workspace_agent_resource_monitor",
|
||||
}
|
||||
|
||||
// ResourceWorkspaceDormant
|
||||
// Valid Actions
|
||||
// - "ActionApplicationConnect" :: connect to workspace apps via browser
|
||||
@@ -353,6 +361,7 @@ func AllResources() []Objecter {
|
||||
ResourceTemplate,
|
||||
ResourceUser,
|
||||
ResourceWorkspace,
|
||||
ResourceWorkspaceAgentResourceMonitor,
|
||||
ResourceWorkspaceDormant,
|
||||
ResourceWorkspaceProxy,
|
||||
}
|
||||
|
||||
@@ -302,4 +302,10 @@ var RBACPermissions = map[string]PermissionDefinition{
|
||||
ActionUpdate: actDef("update IdP sync settings"),
|
||||
},
|
||||
},
|
||||
"workspace_agent_resource_monitor": {
|
||||
Actions: map[Action]ActionDefinition{
|
||||
ActionRead: actDef("read workspace agent resource monitor"),
|
||||
ActionCreate: actDef("create workspace agent resource monitor"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -777,6 +777,21 @@ func TestRolePermissions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ResourceMonitor",
|
||||
Actions: []policy.Action{policy.ActionRead, policy.ActionCreate},
|
||||
Resource: rbac.ResourceWorkspaceAgentResourceMonitor,
|
||||
AuthorizeMap: map[bool][]hasAuthSubjects{
|
||||
true: {owner},
|
||||
false: {
|
||||
memberMe, orgMemberMe, otherOrgMember,
|
||||
orgAdmin, otherOrgAdmin,
|
||||
orgAuditor, otherOrgAuditor,
|
||||
templateAdmin, orgTemplateAdmin, otherOrgTemplateAdmin,
|
||||
userAdmin, orgUserAdmin, otherOrgUserAdmin,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// We expect every permission to be tested above.
|
||||
|
||||
Reference in New Issue
Block a user