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