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  }