feat(worker): enforce durable trust state
Некоторые проверки не удались
CI / test (push) Successful in 7m31s
SSH Source-Install E2E / Alpine/Ubuntu/Arch source-install E2E (push) Failing after 30s
Docker / Build and publish worker image (push) Successful in 41m0s
Некоторые проверки не удались
CI / test (push) Successful in 7m31s
SSH Source-Install E2E / Alpine/Ubuntu/Arch source-install E2E (push) Failing after 30s
Docker / Build and publish worker image (push) Successful in 41m0s
Этот коммит содержится в:
98
internal/distworker/state.go
Обычный файл
98
internal/distworker/state.go
Обычный файл
@@ -0,0 +1,98 @@
|
||||
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()
|
||||
}
|
||||
Ссылка в новой задаче
Block a user