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