mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-04 15:06:37 +08:00
feat: add OperationSetting component and integrate into settings page
- Introduced OperationSetting component for managing agent configurations. - Updated settings page to include a new tab for operation settings. - Implemented functionality to fetch and update agent parameters such as heartbeat interval, sync interval, and auto-update settings. docs: enhance deployment documentation for agent installation - Added detailed instructions for agent installation using a script. - Included examples for using discovery and agent tokens. - Updated sections on global discovery tokens and agent auto-update features. docs: revise design and development guidelines for V3 - Updated design document to reflect the current state and goals for V3. - Clarified development guidelines to focus on operational experience improvements. ci: add GitHub Actions workflow for agent releases - Created a new workflow to automate the release of agent binaries on GitHub. - Configured the workflow to build binaries for multiple platforms and publish them as releases. feat: implement self-update mechanism for agent - Added updater module to handle checking for and applying updates from GitHub releases. - Implemented logic to restart the agent after a successful update. chore: create install script for agent deployment - Developed a bash script to facilitate the installation of the ATSFlare agent. - The script supports automatic configuration and systemd service creation.
This commit is contained in:
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
type HeartbeatService interface {
|
||||
Register(ctx context.Context, payload protocol.NodePayload) (*protocol.RegisterNodeResponse, error)
|
||||
Heartbeat(ctx context.Context, payload protocol.NodePayload) error
|
||||
Heartbeat(ctx context.Context, payload protocol.NodePayload) (*protocol.AgentSettings, error)
|
||||
SetToken(token string)
|
||||
}
|
||||
|
||||
@@ -23,11 +23,19 @@ type SyncService interface {
|
||||
SyncOnce(ctx context.Context) error
|
||||
}
|
||||
|
||||
type Updater interface {
|
||||
CheckAndUpdate(ctx context.Context, repo string) error
|
||||
}
|
||||
|
||||
type Runner struct {
|
||||
Config *config.Config
|
||||
StateStore *state.Store
|
||||
HeartbeatService HeartbeatService
|
||||
SyncService SyncService
|
||||
Updater Updater
|
||||
|
||||
autoUpdate bool
|
||||
updateRepo string
|
||||
}
|
||||
|
||||
func (r *Runner) Run(ctx context.Context) error {
|
||||
@@ -43,10 +51,12 @@ func (r *Runner) Run(ctx context.Context) error {
|
||||
} else {
|
||||
log.Printf("agent startup sync completed")
|
||||
}
|
||||
if err = r.HeartbeatService.Heartbeat(ctx, r.nodePayload(nodeID)); err != nil {
|
||||
log.Printf("agent startup heartbeat failed: %v", err)
|
||||
settings, hbErr := r.HeartbeatService.Heartbeat(ctx, r.nodePayload(nodeID))
|
||||
if hbErr != nil {
|
||||
log.Printf("agent startup heartbeat failed: %v", hbErr)
|
||||
} else {
|
||||
log.Printf("agent startup heartbeat succeeded: node_id=%s", nodeID)
|
||||
r.applySettings(settings)
|
||||
}
|
||||
} else if err = r.tryRegister(ctx, &nodeID); err != nil {
|
||||
log.Printf("agent initial discovery register failed: %v", err)
|
||||
@@ -69,8 +79,15 @@ func (r *Runner) Run(ctx context.Context) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err = r.HeartbeatService.Heartbeat(ctx, r.nodePayload(nodeID)); err != nil {
|
||||
log.Printf("agent heartbeat failed: %v", err)
|
||||
settings, hbErr := r.HeartbeatService.Heartbeat(ctx, r.nodePayload(nodeID))
|
||||
if hbErr != nil {
|
||||
log.Printf("agent heartbeat failed: %v", hbErr)
|
||||
} else {
|
||||
if changed := r.applySettings(settings); changed {
|
||||
heartbeatTicker.Reset(r.Config.HeartbeatInterval.Duration())
|
||||
syncTicker.Reset(r.Config.SyncInterval.Duration())
|
||||
}
|
||||
r.tryAutoUpdate(ctx)
|
||||
}
|
||||
case <-syncTicker.C:
|
||||
if !r.hasAgentToken() {
|
||||
@@ -91,6 +108,41 @@ func (r *Runner) hasAgentToken() bool {
|
||||
return strings.TrimSpace(r.Config.AgentToken) != ""
|
||||
}
|
||||
|
||||
func (r *Runner) applySettings(settings *protocol.AgentSettings) bool {
|
||||
if settings == nil {
|
||||
return false
|
||||
}
|
||||
changed := false
|
||||
if settings.HeartbeatInterval > 0 {
|
||||
newInterval := config.MillisecondDuration(time.Duration(settings.HeartbeatInterval) * time.Millisecond)
|
||||
if newInterval != r.Config.HeartbeatInterval {
|
||||
log.Printf("agent heartbeat interval updated: %s -> %s", r.Config.HeartbeatInterval, newInterval)
|
||||
r.Config.HeartbeatInterval = newInterval
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if settings.SyncInterval > 0 {
|
||||
newInterval := config.MillisecondDuration(time.Duration(settings.SyncInterval) * time.Millisecond)
|
||||
if newInterval != r.Config.SyncInterval {
|
||||
log.Printf("agent sync interval updated: %s -> %s", r.Config.SyncInterval, newInterval)
|
||||
r.Config.SyncInterval = newInterval
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
r.autoUpdate = settings.AutoUpdate
|
||||
r.updateRepo = settings.UpdateRepo
|
||||
return changed
|
||||
}
|
||||
|
||||
func (r *Runner) tryAutoUpdate(ctx context.Context) {
|
||||
if !r.autoUpdate || r.Updater == nil || r.updateRepo == "" {
|
||||
return
|
||||
}
|
||||
if err := r.Updater.CheckAndUpdate(ctx, r.updateRepo); err != nil {
|
||||
log.Printf("agent auto-update check failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) tryRegister(ctx context.Context, nodeID *string) error {
|
||||
if strings.TrimSpace(r.Config.DiscoveryToken) == "" {
|
||||
return errors.New("agent_token 为空且未配置 discovery_token")
|
||||
|
||||
@@ -32,7 +32,7 @@ func (f *fakeHeartbeatService) Register(ctx context.Context, payload protocol.No
|
||||
return f.registerResp, f.registerErr
|
||||
}
|
||||
|
||||
func (f *fakeHeartbeatService) Heartbeat(ctx context.Context, payload protocol.NodePayload) error {
|
||||
func (f *fakeHeartbeatService) Heartbeat(ctx context.Context, payload protocol.NodePayload) (*protocol.AgentSettings, error) {
|
||||
f.mu.Lock()
|
||||
f.heartbeatCalls++
|
||||
callIndex := f.heartbeatCalls
|
||||
@@ -45,7 +45,7 @@ func (f *fakeHeartbeatService) Heartbeat(ctx context.Context, payload protocol.N
|
||||
if onHeartbeat != nil {
|
||||
onHeartbeat(callIndex)
|
||||
}
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (f *fakeHeartbeatService) SetToken(token string) {
|
||||
|
||||
Reference in New Issue
Block a user