Files
worker/internal/distworker/state.go
Gleb Tv b8c7596fc5
Некоторые проверки не удались
CI / test (push) Successful in 7m31s
Docker / Build and publish worker image (push) Successful in 13m54s
SSH Source-Install E2E / Alpine/Ubuntu/Arch source-install E2E (push) Failing after 30s
feat(worker): enforce durable trust state
2026-08-13 22:52:12 +03:00

99 строки
2.3 KiB
Go

package distworker
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
type workerState struct {
Token string `json:"token"`
WorkerID string `json:"worker_id"`
VerificationKey string `json:"verification_key"`
SigningKeyID string `json:"signing_key_id"`
AccountID int64 `json:"account_id"`
ConfigVersion int64 `json:"config_version"`
ConfigPayload string `json:"config_payload"`
}
func loadWorkerState(path string) (workerState, error) {
if path == "" {
return workerState{}, nil
}
if !filepath.IsAbs(path) {
return workerState{}, fmt.Errorf("worker state file must be absolute")
}
if info, err := os.Stat(filepath.Dir(path)); err != nil || !info.IsDir() || info.Mode().Perm() != 0o700 {
return workerState{}, fmt.Errorf("worker state directory must have mode 0700")
}
info, err := os.Stat(path)
if os.IsNotExist(err) {
return workerState{}, nil
}
if err != nil {
return workerState{}, err
}
if info.Mode().Perm() != 0o600 {
return workerState{}, fmt.Errorf("worker state file must have mode 0600")
}
data, err := os.ReadFile(path)
if err != nil {
return workerState{}, err
}
var state workerState
if err := json.Unmarshal(data, &state); err != nil {
return workerState{}, err
}
return state, nil
}
func saveWorkerState(path string, state workerState) error {
if path == "" {
return nil
}
if !filepath.IsAbs(path) {
return fmt.Errorf("worker state file must be absolute")
}
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return err
}
if info, err := os.Stat(filepath.Dir(path)); err != nil || !info.IsDir() || info.Mode().Perm() != 0o700 {
return fmt.Errorf("worker state directory must have mode 0700")
}
data, err := json.Marshal(state)
if err != nil {
return err
}
tmp, err := os.CreateTemp(filepath.Dir(path), ".state-")
if err != nil {
return err
}
tmpName := tmp.Name()
defer os.Remove(tmpName)
if err := tmp.Chmod(0o600); err != nil {
_ = tmp.Close()
return err
}
if _, err := tmp.Write(data); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Sync(); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Close(); err != nil {
return err
}
if err := os.Rename(tmpName, path); err != nil {
return err
}
dir, err := os.Open(filepath.Dir(path))
if err != nil {
return err
}
defer dir.Close()
return dir.Sync()
}