utils.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package cluster // import "github.com/docker/docker/daemon/cluster"
  2. import (
  3. "encoding/json"
  4. "os"
  5. "path/filepath"
  6. "github.com/docker/docker/pkg/ioutils"
  7. )
  8. func loadPersistentState(root string) (*nodeStartConfig, error) {
  9. dt, err := os.ReadFile(filepath.Join(root, stateFile))
  10. if err != nil {
  11. return nil, err
  12. }
  13. // missing certificate means no actual state to restore from
  14. if _, err := os.Stat(filepath.Join(root, "certificates/swarm-node.crt")); err != nil {
  15. if os.IsNotExist(err) {
  16. clearPersistentState(root)
  17. }
  18. return nil, err
  19. }
  20. var st nodeStartConfig
  21. if err := json.Unmarshal(dt, &st); err != nil {
  22. return nil, err
  23. }
  24. return &st, nil
  25. }
  26. func savePersistentState(root string, config nodeStartConfig) error {
  27. dt, err := json.Marshal(config)
  28. if err != nil {
  29. return err
  30. }
  31. return ioutils.AtomicWriteFile(filepath.Join(root, stateFile), dt, 0o600)
  32. }
  33. func clearPersistentState(root string) error {
  34. // todo: backup this data instead of removing?
  35. // rather than delete the entire swarm directory, delete the contents in order to preserve the inode
  36. // (for example, allowing it to be bind-mounted)
  37. files, err := os.ReadDir(root)
  38. if err != nil {
  39. return err
  40. }
  41. for _, f := range files {
  42. if err := os.RemoveAll(filepath.Join(root, f.Name())); err != nil {
  43. return err
  44. }
  45. }
  46. return nil
  47. }
  48. func removingManagerCausesLossOfQuorum(reachable, unreachable int) bool {
  49. return reachable-2 <= unreachable
  50. }
  51. func isLastManager(reachable, unreachable int) bool {
  52. return reachable == 1 && unreachable == 0
  53. }