github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/fleetmanager/hypervisors/fsstorer/load.go (about) 1 package fsstorer 2 3 import ( 4 "bufio" 5 "errors" 6 "io" 7 "net" 8 "os" 9 "path/filepath" 10 "strconv" 11 12 "github.com/Cloud-Foundations/Dominator/lib/fsutil" 13 "github.com/Cloud-Foundations/Dominator/lib/tags" 14 ) 15 16 var zeroIP = IP{} 17 18 func readIpList(filename string) ([]IP, error) { 19 if file, err := os.Open(filename); err != nil { 20 if os.IsNotExist(err) { 21 return nil, nil 22 } 23 return nil, err 24 } else { 25 defer file.Close() 26 reader := bufio.NewReader(file) 27 var ipList []IP 28 for { 29 var ip IP 30 if nRead, err := reader.Read(ip[:]); err != nil { 31 if err == io.EOF { 32 break 33 } 34 return nil, err 35 } else if nRead != len(ip) { 36 return nil, errors.New("incomplete read of IP address") 37 } 38 ipList = append(ipList, ip) 39 } 40 return ipList, nil 41 } 42 } 43 44 func (s *Storer) load() error { 45 if err := s.readDirectory(nil, s.topDir); err != nil { 46 return err 47 } 48 for hypervisor, ipAddrs := range s.hypervisorToIPs { 49 for _, ipAddr := range ipAddrs { 50 s.ipToHypervisor[ipAddr] = hypervisor 51 } 52 } 53 return nil 54 } 55 56 func (s *Storer) readDirectory(partialIP []byte, dirname string) error { 57 if len(partialIP) == len(zeroIP) { 58 filename := filepath.Join(dirname, "ip-list.raw") 59 if ipList, err := readIpList(filename); err != nil { 60 return err 61 } else { 62 var hyperAddr IP 63 copy(hyperAddr[:], partialIP) 64 s.hypervisorToIPs[hyperAddr] = ipList 65 } 66 return nil 67 } 68 names, err := fsutil.ReadDirnames(dirname, true) 69 if err != nil { 70 return err 71 } 72 for _, name := range names { 73 if val, err := strconv.ParseUint(name, 10, 8); err != nil { 74 continue 75 } else { 76 moreIP := make([]byte, len(partialIP), len(partialIP)+1) 77 copy(moreIP, partialIP) 78 moreIP = append(moreIP, byte(val)) 79 subdir := filepath.Join(dirname, name) 80 if err := s.readDirectory(moreIP, subdir); err != nil { 81 return err 82 } 83 } 84 } 85 return nil 86 } 87 88 func (s *Storer) readMachineSerialNumber(hypervisor net.IP) (string, error) { 89 hypervisorIP, err := netIpToIp(hypervisor) 90 if err != nil { 91 return "", err 92 } 93 dirname := s.getHypervisorDirectory(hypervisorIP) 94 filename := filepath.Join(dirname, "serial-number") 95 if file, err := os.Open(filename); err != nil { 96 if !os.IsNotExist(err) { 97 return "", err 98 } 99 return "", nil 100 } else { 101 defer file.Close() 102 reader := bufio.NewReader(file) 103 if line, err := reader.ReadString('\n'); err != nil { 104 return "", err 105 } else { 106 return line[:len(line)-1], nil 107 } 108 } 109 } 110 111 func (s *Storer) readMachineTags(hypervisor net.IP) (tags.Tags, error) { 112 hypervisorIP, err := netIpToIp(hypervisor) 113 if err != nil { 114 return nil, err 115 } 116 dirname := s.getHypervisorDirectory(hypervisorIP) 117 filename := filepath.Join(dirname, "tags.raw") 118 if file, err := os.Open(filename); err != nil { 119 if !os.IsNotExist(err) { 120 return nil, err 121 } 122 return nil, nil 123 } else { 124 defer file.Close() 125 reader := bufio.NewReader(file) 126 var lastKey string 127 tgs := make(tags.Tags) 128 for { 129 if line, err := reader.ReadString('\n'); err != nil { 130 if err != io.EOF { 131 return nil, err 132 } 133 if lastKey != "" { 134 return nil, errors.New("missing value for key: " + lastKey) 135 } 136 break 137 } else { 138 line = line[:len(line)-1] 139 if lastKey == "" { 140 lastKey = line 141 } else { 142 tgs[lastKey] = line 143 lastKey = "" 144 } 145 } 146 } 147 return tgs, nil 148 } 149 }