mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-06 15:46:37 +08:00
fix lint
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// Package config loads and persists flared daemon configuration.
|
||||
package config
|
||||
|
||||
import (
|
||||
@@ -11,8 +12,17 @@ import (
|
||||
edgeconfig "github.com/Rain-kl/Wavelet/internal/apps/edge/config"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultHeartbeatInterval = 10 * time.Second
|
||||
defaultSyncInterval = 30 * time.Second
|
||||
defaultRequestTimeout = 10 * time.Second
|
||||
configFilePerm = 0o644
|
||||
)
|
||||
|
||||
// MillisecondDuration is a JSON-friendly duration type shared with edge config.
|
||||
type MillisecondDuration = edgeconfig.MillisecondDuration
|
||||
|
||||
// Config holds flared daemon settings loaded from file and environment.
|
||||
type Config struct {
|
||||
ServerURL string `json:"server_url"`
|
||||
TunnelToken string `json:"tunnel_token"`
|
||||
@@ -25,8 +35,9 @@ type Config struct {
|
||||
configPath string
|
||||
}
|
||||
|
||||
// Load reads configuration from path, applying environment overrides and defaults.
|
||||
func Load(path string) (*Config, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
data, err := os.ReadFile(path) //nolint:gosec // path is the flared config file location from startup configuration
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
@@ -89,13 +100,13 @@ func applyDefaults(cfg *Config, baseDir string) {
|
||||
cfg.StatePath = filepath.Join(cfg.DataDir, "flared-state.json")
|
||||
}
|
||||
if cfg.HeartbeatInterval <= 0 {
|
||||
cfg.HeartbeatInterval = MillisecondDuration(10 * time.Second)
|
||||
cfg.HeartbeatInterval = MillisecondDuration(defaultHeartbeatInterval)
|
||||
}
|
||||
if cfg.SyncInterval <= 0 {
|
||||
cfg.SyncInterval = MillisecondDuration(30 * time.Second)
|
||||
cfg.SyncInterval = MillisecondDuration(defaultSyncInterval)
|
||||
}
|
||||
if cfg.RequestTimeout <= 0 {
|
||||
cfg.RequestTimeout = MillisecondDuration(10 * time.Second)
|
||||
cfg.RequestTimeout = MillisecondDuration(defaultRequestTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +120,7 @@ func validate(cfg *Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitialAuthToken returns the tunnel token used for initial authentication.
|
||||
func (cfg *Config) InitialAuthToken() string {
|
||||
if cfg == nil {
|
||||
return ""
|
||||
@@ -116,6 +128,7 @@ func (cfg *Config) InitialAuthToken() string {
|
||||
return strings.TrimSpace(cfg.TunnelToken)
|
||||
}
|
||||
|
||||
// Save writes the current configuration back to the loaded config path.
|
||||
func (cfg *Config) Save() error {
|
||||
if cfg == nil {
|
||||
return errors.New("config 不能为空")
|
||||
@@ -127,5 +140,5 @@ func (cfg *Config) Save() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(cfg.configPath, data, 0o644)
|
||||
return os.WriteFile(cfg.configPath, data, configFilePerm)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
package config
|
||||
|
||||
// Version is the flared daemon build version string.
|
||||
var Version = "dev"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package flared implements the tunnel client daemon runtime loop.
|
||||
package flared
|
||||
|
||||
import (
|
||||
@@ -13,15 +14,19 @@ import (
|
||||
"github.com/Rain-kl/Wavelet/internal/apps/flared/wsclient"
|
||||
)
|
||||
|
||||
// Runner is the top-level orchestrator for the flared agent. It wires together
|
||||
// heartbeat, sync, frpc management, and the WebSocket control-plane connection.
|
||||
type Runner struct {
|
||||
Config *config.Config
|
||||
HeartbeatService *heartbeat.Service
|
||||
FrpcManager *frpc.Manager
|
||||
SyncService *sync.Service
|
||||
WebSocketService *wsclient.Client
|
||||
HttpClient *httpclient.Client
|
||||
HTTPClient *httpclient.Client
|
||||
}
|
||||
|
||||
// Run starts all background services and enters the WebSocket reconnect loop.
|
||||
// It blocks until ctx is cancelled or an unrecoverable error occurs.
|
||||
func (r *Runner) Run(ctx context.Context) error {
|
||||
go r.HeartbeatService.Run(ctx)
|
||||
go r.SyncService.Run(ctx)
|
||||
@@ -40,11 +45,11 @@ type flaredWSHandler struct {
|
||||
runner *Runner
|
||||
}
|
||||
|
||||
func (h *flaredWSHandler) OnConnect(ctx context.Context) error {
|
||||
func (h *flaredWSHandler) OnConnect(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *flaredWSHandler) HandleMessage(ctx context.Context, msg wsclient.WSMessage) error {
|
||||
func (h *flaredWSHandler) HandleMessage(_ context.Context, msg wsclient.WSMessage) error {
|
||||
switch msg.Type {
|
||||
case "active_config":
|
||||
slog.Info("received config update notification from server")
|
||||
@@ -66,4 +71,4 @@ func (r *Runner) handleConnection(ctx context.Context, conn edgerunner.WSConnect
|
||||
return
|
||||
}
|
||||
_ = wsConn.RunReceiveLoop(ctx, &flaredWSHandler{runner: r})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package frpc manages frpc child processes for tunnel relay connections.
|
||||
package frpc
|
||||
|
||||
import (
|
||||
@@ -18,6 +19,13 @@ import (
|
||||
service "github.com/Rain-kl/Wavelet/pkg/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
dataDirPerm = 0o750
|
||||
frpcConfigFilePerm = 0o644
|
||||
orphanProcessKillDelay = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
// Manager supervises frpc processes for each active relay node.
|
||||
type Manager struct {
|
||||
cfg *config.Config
|
||||
processes map[string]*Process
|
||||
@@ -27,6 +35,7 @@ type Manager struct {
|
||||
currentChecksum string
|
||||
}
|
||||
|
||||
// Process tracks a single frpc child process and its runtime state.
|
||||
type Process struct {
|
||||
RelayID string
|
||||
Cmd *exec.Cmd
|
||||
@@ -36,6 +45,7 @@ type Process struct {
|
||||
LastError string
|
||||
}
|
||||
|
||||
// NewManager creates a Manager using the given flared configuration.
|
||||
func NewManager(cfg *config.Config) *Manager {
|
||||
return &Manager{
|
||||
cfg: cfg,
|
||||
@@ -43,8 +53,9 @@ func NewManager(cfg *config.Config) *Manager {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) GetVersion() string {
|
||||
cmd := exec.Command(m.cfg.FrpcPath, "-v")
|
||||
// GetVersion returns the installed frpc binary version string.
|
||||
func (m *Manager) GetVersion(ctx context.Context) string {
|
||||
cmd := exec.CommandContext(ctx, m.cfg.FrpcPath, "-v") //nolint:gosec // FrpcPath is the configured trusted frpc binary location
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "unknown"
|
||||
@@ -52,6 +63,7 @@ func (m *Manager) GetVersion() string {
|
||||
return strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
// GetConnectedRelays reports the relay nodes with active or managed frpc processes.
|
||||
func (m *Manager) GetConnectedRelays() []service.FlaredConnectedRelay {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
@@ -66,18 +78,21 @@ func (m *Manager) GetConnectedRelays() []service.FlaredConnectedRelay {
|
||||
return result
|
||||
}
|
||||
|
||||
// GetCurrentConfigVersion returns the version of the applied tunnel configuration.
|
||||
func (m *Manager) GetCurrentConfigVersion() string {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
return m.currentVersion
|
||||
}
|
||||
|
||||
// GetCurrentConfigChecksum returns the checksum of the applied tunnel configuration.
|
||||
func (m *Manager) GetCurrentConfigChecksum() string {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
return m.currentChecksum
|
||||
}
|
||||
|
||||
// UpdateConfig reconciles running frpc processes with the latest tunnel configuration.
|
||||
func (m *Manager) UpdateConfig(ctx context.Context, newConfig *service.FlaredTunnelConfigResponse) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@@ -93,7 +108,7 @@ func (m *Manager) UpdateConfig(ctx context.Context, newConfig *service.FlaredTun
|
||||
slog.Debug("tunnel config version unchanged, ensuring processes are running", "version", newConfig.Version)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(m.cfg.DataDir, 0o755); err != nil {
|
||||
if err := os.MkdirAll(m.cfg.DataDir, dataDirPerm); err != nil {
|
||||
return fmt.Errorf("create data dir failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -105,14 +120,14 @@ func (m *Manager) UpdateConfig(ctx context.Context, newConfig *service.FlaredTun
|
||||
configPath := filepath.Join(m.cfg.DataDir, fmt.Sprintf("frpc_%s.toml", relay.RelayNodeID))
|
||||
|
||||
needsRestart := false
|
||||
existingData, err := os.ReadFile(configPath)
|
||||
existingData, err := os.ReadFile(configPath) //nolint:gosec // configPath is under managed DataDir
|
||||
if err != nil || string(existingData) != tomlContent {
|
||||
// 配置文件不存在或内容有变化,需要写入并重启
|
||||
needsRestart = true
|
||||
}
|
||||
|
||||
if needsRestart {
|
||||
if err := os.WriteFile(configPath, []byte(tomlContent), 0o644); err != nil {
|
||||
if err := os.WriteFile(configPath, []byte(tomlContent), frpcConfigFilePerm); err != nil {
|
||||
slog.Error("failed to write frpc config", "relay_id", relay.RelayNodeID, "error", err)
|
||||
continue
|
||||
}
|
||||
@@ -150,10 +165,7 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
||||
_ = os.Remove(pidPath)
|
||||
}
|
||||
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
procCtx, cancel := context.WithCancel(ctx)
|
||||
procCtx, cancel := context.WithCancel(context.WithoutCancel(ctx))
|
||||
proc := &Process{
|
||||
RelayID: relayID,
|
||||
Cancel: cancel,
|
||||
@@ -176,7 +188,7 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
||||
|
||||
ensureNoOrphanProcess(pidPath)
|
||||
|
||||
cmd := exec.CommandContext(procCtx, m.cfg.FrpcPath, "-c", configPath)
|
||||
cmd := exec.CommandContext(procCtx, m.cfg.FrpcPath, "-c", configPath) //nolint:gosec // FrpcPath and configPath are managed trusted locations
|
||||
|
||||
m.mu.Lock()
|
||||
proc.Cmd = cmd
|
||||
@@ -186,7 +198,7 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
||||
startedAt := time.Now()
|
||||
err := cmd.Start()
|
||||
if err == nil {
|
||||
_ = os.WriteFile(pidPath, []byte(fmt.Sprintf("%d", cmd.Process.Pid)), 0o644)
|
||||
_ = os.WriteFile(pidPath, []byte(fmt.Sprintf("%d", cmd.Process.Pid)), frpcConfigFilePerm)
|
||||
err = cmd.Wait()
|
||||
}
|
||||
_ = os.Remove(pidPath)
|
||||
@@ -217,7 +229,7 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
||||
case <-procCtx.Done():
|
||||
return
|
||||
case <-time.After(backoff):
|
||||
backoff = backoff * 2
|
||||
backoff *= 2
|
||||
if backoff > maxBackoff {
|
||||
backoff = maxBackoff
|
||||
}
|
||||
@@ -226,6 +238,7 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop cancels and removes all managed frpc processes.
|
||||
func (m *Manager) Stop() {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@@ -245,28 +258,23 @@ func buildFrpcToml(relay service.FlaredRelayInfo, proxies []service.FlaredProxyE
|
||||
|
||||
host, port := parseAddr(relay.Address)
|
||||
|
||||
buf.WriteString(fmt.Sprintf(`serverAddr = "%s"
|
||||
serverPort = %s
|
||||
`, host, port))
|
||||
fmt.Fprintf(&buf, "serverAddr = \"%s\"\nserverPort = %s\n", host, port)
|
||||
|
||||
if relay.AuthToken != "" {
|
||||
buf.WriteString(fmt.Sprintf(`auth.method = "token"
|
||||
auth.token = "%s"
|
||||
`, relay.AuthToken))
|
||||
fmt.Fprintf(&buf, "auth.method = \"token\"\nauth.token = \"%s\"\n", relay.AuthToken)
|
||||
}
|
||||
|
||||
if relay.ProxyURL != "" {
|
||||
buf.WriteString(fmt.Sprintf(`transport.proxyURL = "%s"
|
||||
`, relay.ProxyURL))
|
||||
fmt.Fprintf(&buf, "transport.proxyURL = \"%s\"\n", relay.ProxyURL)
|
||||
}
|
||||
|
||||
buf.WriteString("\n")
|
||||
|
||||
for _, proxy := range proxies {
|
||||
buf.WriteString(fmt.Sprintf("[[proxies]]\nname = \"%s\"\ntype = \"%s\"\nlocalIP = \"%s\"\nlocalPort = %d\n",
|
||||
proxy.Name, proxy.Type, proxy.LocalAddr, proxy.LocalPort))
|
||||
fmt.Fprintf(&buf, "[[proxies]]\nname = \"%s\"\ntype = \"%s\"\nlocalIP = \"%s\"\nlocalPort = %d\n",
|
||||
proxy.Name, proxy.Type, proxy.LocalAddr, proxy.LocalPort)
|
||||
if len(proxy.CustomDomains) > 0 {
|
||||
buf.WriteString(fmt.Sprintf("customDomains = [\"%s\"]\n", strings.Join(proxy.CustomDomains, "\", \"")))
|
||||
fmt.Fprintf(&buf, "customDomains = [\"%s\"]\n", strings.Join(proxy.CustomDomains, "\", \""))
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
@@ -290,7 +298,7 @@ func parseAddr(addr string) (string, string) {
|
||||
return addr, "7000"
|
||||
}
|
||||
|
||||
// State persistence
|
||||
// ManagerState persists the last applied tunnel configuration version and checksum.
|
||||
type ManagerState struct {
|
||||
Version string
|
||||
Checksum string
|
||||
@@ -305,9 +313,10 @@ func (m *Manager) saveState() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(m.cfg.StatePath, data, 0o644)
|
||||
return os.WriteFile(m.cfg.StatePath, data, frpcConfigFilePerm)
|
||||
}
|
||||
|
||||
// LoadState restores the last applied configuration version and checksum from disk.
|
||||
func (m *Manager) LoadState() error {
|
||||
data, err := os.ReadFile(m.cfg.StatePath)
|
||||
if err != nil {
|
||||
@@ -328,7 +337,7 @@ func (m *Manager) LoadState() error {
|
||||
}
|
||||
|
||||
func ensureNoOrphanProcess(pidPath string) {
|
||||
data, err := os.ReadFile(pidPath)
|
||||
data, err := os.ReadFile(pidPath) //nolint:gosec // pidPath is under managed DataDir
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -344,7 +353,7 @@ func ensureNoOrphanProcess(pidPath string) {
|
||||
slog.Warn("attempting to kill potentially orphan process", "pid", pid, "pid_path", pidPath)
|
||||
_ = process.Kill()
|
||||
// Wait a little bit to ensure the OS has reclaimed ports
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
time.Sleep(orphanProcessKillDelay)
|
||||
}
|
||||
_ = os.Remove(pidPath)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package heartbeat runs the periodic flared heartbeat loop against the control plane.
|
||||
package heartbeat
|
||||
|
||||
import (
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
service "github.com/Rain-kl/Wavelet/pkg/protocol"
|
||||
)
|
||||
|
||||
// Service sends periodic heartbeat payloads and applies tunnel settings from responses.
|
||||
type Service struct {
|
||||
client *httpclient.Client
|
||||
frpcManager *frpc.Manager
|
||||
@@ -20,6 +22,7 @@ type Service struct {
|
||||
updater *updater.Service
|
||||
}
|
||||
|
||||
// New creates a heartbeat service with the given client, frpc manager, and config.
|
||||
func New(client *httpclient.Client, manager *frpc.Manager, cfg *config.Config) *Service {
|
||||
return &Service{
|
||||
client: client,
|
||||
@@ -29,6 +32,7 @@ func New(client *httpclient.Client, manager *frpc.Manager, cfg *config.Config) *
|
||||
}
|
||||
}
|
||||
|
||||
// Run starts the heartbeat loop until ctx is canceled.
|
||||
func (s *Service) Run(ctx context.Context) {
|
||||
edgeheartbeat.RunLoop(ctx, s.config.HeartbeatInterval.Duration(), s.doHeartbeat)
|
||||
}
|
||||
@@ -38,8 +42,8 @@ func (s *Service) doHeartbeat(ctx context.Context) {
|
||||
|
||||
payload := service.FlaredHeartbeatPayload{
|
||||
ClientVersion: config.Version,
|
||||
FrpVersion: s.frpcManager.GetVersion(),
|
||||
IP: nodeip.Detect(),
|
||||
FrpVersion: s.frpcManager.GetVersion(ctx),
|
||||
IP: nodeip.DetectWithContext(ctx),
|
||||
TunnelStatus: "running",
|
||||
ConnectedRelays: s.frpcManager.GetConnectedRelays(),
|
||||
CurrentVersion: s.frpcManager.GetCurrentConfigVersion(),
|
||||
@@ -69,4 +73,4 @@ func tunnelSettingsToAutoUpdate(settings *service.RelaySettings) *edgeheartbeat.
|
||||
UpdateChannel: settings.UpdateChannel,
|
||||
UpdateTag: settings.UpdateTag,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package httpclient provides the HTTP client used by the flared agent to communicate with the Wavelet server.
|
||||
package httpclient
|
||||
|
||||
import (
|
||||
@@ -8,21 +9,25 @@ import (
|
||||
service "github.com/Rain-kl/Wavelet/pkg/protocol"
|
||||
)
|
||||
|
||||
// APIResponse is the standard JSON envelope returned by the Wavelet API.
|
||||
type APIResponse[T any] struct {
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
Data T `json:"data"`
|
||||
}
|
||||
|
||||
// Client is the HTTP client for the flared tunnel API.
|
||||
type Client struct {
|
||||
base *edgehttp.Client
|
||||
}
|
||||
|
||||
// New creates a new Client configured with the given base URL, authentication token, and request timeout.
|
||||
func New(baseURL string, token string, timeout time.Duration) *Client {
|
||||
return &Client{
|
||||
base: edgehttp.New(baseURL, token, timeout, "X-Tunnel-Token"),
|
||||
}
|
||||
}
|
||||
|
||||
// Heartbeat sends a tunnel heartbeat payload and returns the server response.
|
||||
func (c *Client) Heartbeat(ctx context.Context, payload service.FlaredHeartbeatPayload) (*service.FlaredHeartbeatResponse, error) {
|
||||
resp := APIResponse[service.FlaredHeartbeatResponse]{}
|
||||
if err := c.base.PostJSON(ctx, "/api/v1/tunnel/heartbeat", payload, &resp); err != nil {
|
||||
@@ -34,6 +39,7 @@ func (c *Client) Heartbeat(ctx context.Context, payload service.FlaredHeartbeatP
|
||||
return &resp.Data, nil
|
||||
}
|
||||
|
||||
// GetActiveConfig fetches the currently active tunnel configuration from the server.
|
||||
func (c *Client) GetActiveConfig(ctx context.Context) (*service.FlaredTunnelConfigResponse, error) {
|
||||
resp := APIResponse[service.FlaredTunnelConfigResponse]{}
|
||||
if err := c.base.GetJSON(ctx, "/api/v1/tunnel/config/active", &resp); err != nil {
|
||||
@@ -45,6 +51,7 @@ func (c *Client) GetActiveConfig(ctx context.Context) (*service.FlaredTunnelConf
|
||||
return &resp.Data, nil
|
||||
}
|
||||
|
||||
// ReportApplyLog submits a configuration apply-log entry to the server.
|
||||
func (c *Client) ReportApplyLog(ctx context.Context, payload service.ApplyLogPayload) error {
|
||||
resp := APIResponse[any]{}
|
||||
if err := c.base.PostJSON(ctx, "/api/v1/tunnel/apply-log", payload, &resp); err != nil {
|
||||
@@ -53,6 +60,7 @@ func (c *Client) ReportApplyLog(ctx context.Context, payload service.ApplyLogPay
|
||||
return edgehttp.APIError(resp.ErrorMsg)
|
||||
}
|
||||
|
||||
// SetToken updates the authentication token used by the client.
|
||||
func (c *Client) SetToken(token string) {
|
||||
c.base.SetToken(token)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package sync periodically fetches and applies the active tunnel configuration.
|
||||
package sync
|
||||
|
||||
import (
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
service "github.com/Rain-kl/Wavelet/pkg/protocol"
|
||||
)
|
||||
|
||||
// Service synchronizes tunnel configuration from the control plane to the local frpc manager.
|
||||
type Service struct {
|
||||
client *httpclient.Client
|
||||
frpcManager *frpc.Manager
|
||||
@@ -18,6 +20,7 @@ type Service struct {
|
||||
triggerCh chan struct{}
|
||||
}
|
||||
|
||||
// New creates a sync service with the given client, frpc manager, and config.
|
||||
func New(client *httpclient.Client, manager *frpc.Manager, cfg *config.Config) *Service {
|
||||
return &Service{
|
||||
client: client,
|
||||
@@ -27,6 +30,7 @@ func New(client *httpclient.Client, manager *frpc.Manager, cfg *config.Config) *
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger requests an immediate configuration sync without waiting for the next interval.
|
||||
func (s *Service) Trigger() {
|
||||
select {
|
||||
case s.triggerCh <- struct{}{}:
|
||||
@@ -34,6 +38,7 @@ func (s *Service) Trigger() {
|
||||
}
|
||||
}
|
||||
|
||||
// Run starts the sync loop until ctx is canceled.
|
||||
func (s *Service) Run(ctx context.Context) {
|
||||
ticker := time.NewTicker(s.config.SyncInterval.Duration())
|
||||
defer ticker.Stop()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package updater provides update service capabilities for flared.
|
||||
package updater
|
||||
|
||||
import (
|
||||
@@ -5,13 +6,17 @@ import (
|
||||
"github.com/Rain-kl/Wavelet/internal/apps/flared/config"
|
||||
)
|
||||
|
||||
// Service is an alias for the edge updater Service.
|
||||
type Service = edgeupdater.Service
|
||||
|
||||
// UpdateOptions is an alias for the edge updater UpdateOptions.
|
||||
type UpdateOptions = edgeupdater.UpdateOptions
|
||||
|
||||
// New creates a new updater Service instance.
|
||||
func New() *Service {
|
||||
return edgeupdater.New(edgeupdater.Config{
|
||||
LocalVersion: config.Version,
|
||||
AssetPrefix: "openflared",
|
||||
LogLabel: "flared",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package wsclient provides a WebSocket client for flared control-plane communication.
|
||||
package wsclient
|
||||
|
||||
import (
|
||||
@@ -7,24 +8,33 @@ import (
|
||||
edgews "github.com/Rain-kl/Wavelet/internal/apps/edge/wsclient"
|
||||
)
|
||||
|
||||
// WSMessage is a WebSocket message exchanged with the control plane.
|
||||
type WSMessage = edgews.WSMessage
|
||||
|
||||
// MessageHandler processes incoming WebSocket messages.
|
||||
type MessageHandler = edgews.MessageHandler
|
||||
|
||||
// Connection represents an active WebSocket connection.
|
||||
type Connection = edgews.Connection
|
||||
|
||||
// Client connects to the flared WebSocket endpoint on the control plane.
|
||||
type Client struct {
|
||||
inner *edgews.Client
|
||||
}
|
||||
|
||||
// New creates a WebSocket client for the flared control-plane endpoint.
|
||||
func New(baseURL, token string, timeout time.Duration) *Client {
|
||||
return &Client{
|
||||
inner: edgews.New(edgews.PresetFlared, baseURL, token, timeout),
|
||||
}
|
||||
}
|
||||
|
||||
// SetToken updates the authentication token used for the WebSocket connection.
|
||||
func (c *Client) SetToken(token string) {
|
||||
c.inner.SetToken(token)
|
||||
}
|
||||
|
||||
// Connect establishes a WebSocket connection to the control plane.
|
||||
func (c *Client) Connect(ctx context.Context) (*Connection, error) {
|
||||
return c.inner.Connect(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user