Skip to content

Commit 8ce50a4

Browse files
author
root
committed
fix settings
1 parent 4360d6a commit 8ce50a4

126 files changed

Lines changed: 8556 additions & 2926 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ make openapi-sync
5353

5454
Available commands:
5555

56-
- `make openapi-gen` — regenerate `ext-api.yaml` from custom route source (generated custom-route spec for `/api/ext/*`, `/api/servers/*`, `/api/apps*`, `/api/actions*`, `/api/pipelines*`, `/api/components*`)
56+
- `make openapi-gen` — regenerate `ext-api.yaml` from custom route source (generated custom-route spec for `/api/ext/*`, `/api/servers/*`, `/api/apps*`, `/api/actions*`, `/api/pipelines*`, `/api/software/local*`)
5757
- `make openapi-merge` — merge `ext-api.yaml` + `native-api.yaml` into `api.yaml`
5858
- `make openapi-check` — fail when custom route/spec drift or duplicate YAML keys exist
5959
- `make openapi-sync` — run generate + merge + check in order

backend/cmd/appos/bootstrap/cron.go

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ package bootstrap
33
import (
44
"errors"
55
"fmt"
6+
"time"
67

78
"github.com/hibiken/asynq"
8-
comp "github.com/websoft9/appos/backend/domain/components"
9+
"github.com/websoft9/appos/backend/domain/monitor"
10+
swcatalog "github.com/websoft9/appos/backend/domain/software/catalog"
11+
swinventory "github.com/websoft9/appos/backend/domain/software/inventory"
912
"github.com/websoft9/appos/backend/domain/worker"
1013
"github.com/websoft9/appos/backend/infra/cronutil"
1114

@@ -26,7 +29,7 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
2629
componentsInventoryCronJobID,
2730
"*/15 * * * *",
2831
cronutil.Wrap(app, componentsInventoryCronJobID, func() {
29-
if err := runComponentsInventoryProbe(); err != nil {
32+
if err := runComponentsInventoryProbe(app); err != nil {
3033
panic(err)
3134
}
3235
}),
@@ -40,6 +43,9 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
4043
monitorReachabilityCronJobID,
4144
"*/1 * * * *",
4245
cronutil.Wrap(app, monitorReachabilityCronJobID, func() {
46+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).ReachabilityIntervalMinutes) {
47+
return
48+
}
4349
if err := worker.EnqueueMonitorReachabilitySweep(asynqClient); err != nil {
4450
panic(err)
4551
}
@@ -50,6 +56,9 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
5056
monitorMetricsFreshnessCronJobID,
5157
"*/1 * * * *",
5258
cronutil.Wrap(app, monitorMetricsFreshnessCronJobID, func() {
59+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).MetricsFreshnessIntervalMinutes) {
60+
return
61+
}
5362
if err := worker.EnqueueMonitorMetricsFreshness(asynqClient); err != nil {
5463
panic(err)
5564
}
@@ -60,6 +69,9 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
6069
monitorControlReachabilityCronJobID,
6170
"*/1 * * * *",
6271
cronutil.Wrap(app, monitorControlReachabilityCronJobID, func() {
72+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).ControlReachabilityIntervalMinutes) {
73+
return
74+
}
6375
if err := worker.EnqueueMonitorControlReachability(asynqClient); err != nil {
6476
panic(err)
6577
}
@@ -68,8 +80,11 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
6880

6981
app.Cron().MustAdd(
7082
monitorFactsPullCronJobID,
71-
"*/15 * * * *",
83+
"*/1 * * * *",
7284
cronutil.Wrap(app, monitorFactsPullCronJobID, func() {
85+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).FactsPullIntervalMinutes) {
86+
return
87+
}
7388
if err := worker.EnqueueMonitorFactsPull(asynqClient); err != nil {
7489
panic(err)
7590
}
@@ -80,6 +95,9 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
8095
monitorRuntimeSnapshotPullCronJobID,
8196
"*/1 * * * *",
8297
cronutil.Wrap(app, monitorRuntimeSnapshotPullCronJobID, func() {
98+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).RuntimeSnapshotIntervalMinutes) {
99+
return
100+
}
83101
if err := worker.EnqueueMonitorRuntimeSnapshotPull(asynqClient); err != nil {
84102
panic(err)
85103
}
@@ -88,8 +106,11 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
88106

89107
app.Cron().MustAdd(
90108
monitorCredentialCronJobID,
91-
"*/5 * * * *",
109+
"*/1 * * * *",
92110
cronutil.Wrap(app, monitorCredentialCronJobID, func() {
111+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).CredentialSweepIntervalMinutes) {
112+
return
113+
}
93114
if err := worker.EnqueueMonitorCredentialSweep(asynqClient); err != nil {
94115
panic(err)
95116
}
@@ -100,28 +121,40 @@ func registerCronHooks(app *pocketbase.PocketBase, asynqClient *asynq.Client) {
100121
monitorAppHealthCronJobID,
101122
"*/1 * * * *",
102123
cronutil.Wrap(app, monitorAppHealthCronJobID, func() {
124+
if !shouldRunMonitorInterval(time.Now().UTC(), monitor.LoadSchedulingSettings(app).AppHealthIntervalMinutes) {
125+
return
126+
}
103127
if err := worker.EnqueueMonitorAppHealthSweep(asynqClient); err != nil {
104128
panic(err)
105129
}
106130
}),
107131
)
108132
}
109133

110-
func runComponentsInventoryProbe() error {
111-
registry, err := comp.LoadRegistry()
134+
func shouldRunMonitorInterval(now time.Time, intervalMinutes int) bool {
135+
if intervalMinutes <= 1 {
136+
return true
137+
}
138+
now = now.UTC()
139+
totalMinutes := now.Hour()*60 + now.Minute()
140+
return totalMinutes%intervalMinutes == 0
141+
}
142+
143+
func runComponentsInventoryProbe(app *pocketbase.PocketBase) error {
144+
registry, err := swcatalog.LoadLocalRegistry()
112145
if err != nil {
113146
return err
114147
}
115148

116149
var probeErrors []error
117150
for _, component := range registry.EnabledComponents() {
118-
if _, err := comp.DetectVersion(component.VersionProbe); err != nil {
151+
if _, err := swinventory.DetectVersion(app, component.VersionProbe); err != nil {
119152
probeErrors = append(probeErrors, fmt.Errorf("%s version probe: %w", component.ID, err))
120153
}
121-
if _, err := comp.CheckAvailability(component.AvailabilityProbe); err != nil {
154+
if _, err := swinventory.CheckAvailability(app, component.AvailabilityProbe); err != nil {
122155
probeErrors = append(probeErrors, fmt.Errorf("%s availability probe: %w", component.ID, err))
123156
}
124-
_ = comp.DetectUpdateTime(component.UpdateProbe)
157+
_ = swinventory.DetectUpdateTime(component.UpdateProbe)
125158
}
126159

127160
return errors.Join(probeErrors...)

backend/cmd/appos/bootstrap/cron_test.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import (
55
"path/filepath"
66
"strings"
77
"testing"
8+
"time"
89

9-
comp "github.com/websoft9/appos/backend/domain/components"
10+
swcatalog "github.com/websoft9/appos/backend/domain/software/catalog"
1011
)
1112

1213
func TestRunComponentsInventoryProbeSuccess(t *testing.T) {
@@ -33,10 +34,10 @@ components:
3334
services: []
3435
`)
3536

36-
restore := comp.SetRegistryPathForTesting(registryPath)
37+
restore := swcatalog.SetLocalRegistryPathForTesting(registryPath)
3738
defer restore()
3839

39-
if err := runComponentsInventoryProbe(); err != nil {
40+
if err := runComponentsInventoryProbe(nil); err != nil {
4041
t.Fatalf("expected probe to succeed, got %v", err)
4142
}
4243
}
@@ -60,10 +61,10 @@ components:
6061
services: []
6162
`)
6263

63-
restore := comp.SetRegistryPathForTesting(registryPath)
64+
restore := swcatalog.SetLocalRegistryPathForTesting(registryPath)
6465
defer restore()
6566

66-
err := runComponentsInventoryProbe()
67+
err := runComponentsInventoryProbe(nil)
6768
if err == nil {
6869
t.Fatal("expected probe to fail")
6970
}
@@ -82,3 +83,16 @@ func writeTestFile(t *testing.T, path string, content string) {
8283
t.Fatal(err)
8384
}
8485
}
86+
87+
func TestShouldRunMonitorInterval(t *testing.T) {
88+
now := time.Date(2026, time.May, 25, 10, 15, 0, 0, time.UTC)
89+
if !shouldRunMonitorInterval(now, 1) {
90+
t.Fatal("expected 1-minute interval to run")
91+
}
92+
if !shouldRunMonitorInterval(now, 5) {
93+
t.Fatal("expected 5-minute interval to run at minute 15")
94+
}
95+
if shouldRunMonitorInterval(now, 7) {
96+
t.Fatal("expected 7-minute interval not to run at minute 15")
97+
}
98+
}

backend/cmd/appos/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func main() {
3838
snap := w.Snapshot()
3939
return monitorplatform.RuntimeSnapshot{
4040
StartedAt: snap.StartedAt,
41+
ServerRunning: snap.ServerRunning,
4142
WorkerRunning: snap.ServerRunning,
4243
SchedulerRunning: snap.SchedulerRunning,
4344
SchedulerLastTick: snap.SchedulerLastTick,

backend/cmd/openapi/gen.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,6 @@ func scanFile(filePath string, seeds map[string]functionSeed, metadata handlerMe
171171
if strings.HasPrefix(filepath.Base(filePath), "terminal") {
172172
defaultG = "/api/terminal"
173173
}
174-
if filepath.Base(filePath) == "components.go" {
175-
defaultG = "/api/components"
176-
}
177174
if filepath.Base(filePath) == "deploy.go" || filepath.Base(filePath) == "apps.go" || filepath.Base(filePath) == "lifecycle_resources.go" || filepath.Base(filePath) == "catalog.go" {
178175
defaultG = "/api"
179176
}

backend/config/embed.go

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)