From 08ee31dfcc39f21c8068fd90a7adcb4bfb245d28 Mon Sep 17 00:00:00 2001 From: Richard Gooch Date: Thu, 17 May 2018 07:06:03 -0700 Subject: [PATCH 1/3] Add proto/hypervisor.{Subnet.DomainName,VmInfo.Hostname} fields. --- proto/hypervisor/messages.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/hypervisor/messages.go b/proto/hypervisor/messages.go index 1222e284..908e93fb 100644 --- a/proto/hypervisor/messages.go +++ b/proto/hypervisor/messages.go @@ -223,6 +223,7 @@ type Subnet struct { Id string IpGateway net.IP IpMask net.IP // net.IPMask can't be JSON {en,de}coded. + DomainName string `json:",omitempty"` DomainNameServers []net.IP } @@ -236,6 +237,7 @@ type TraceVmMetadataResponse struct { type VmInfo struct { Address Address + Hostname string `json:",omitempty"` ImageName string `json:",omitempty"` ImageURL string `json:",omitempty"` MemoryInMiB uint64 From 5b4aa07cbc761e020b6b342160af2b44199d6baa Mon Sep 17 00:00:00 2001 From: Richard Gooch Date: Thu, 17 May 2018 07:58:10 -0700 Subject: [PATCH 2/3] Support specifying domain and host name in Hypervisor DHCP leases. --- hypervisor/dhcpd/api.go | 11 +++++--- hypervisor/dhcpd/impl.go | 55 ++++++++++++++++++++------------------ hypervisor/httpd/showVM.go | 3 +++ hypervisor/manager/api.go | 2 +- hypervisor/manager/vm.go | 3 ++- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/hypervisor/dhcpd/api.go b/hypervisor/dhcpd/api.go index 654dd279..66374055 100644 --- a/hypervisor/dhcpd/api.go +++ b/hypervisor/dhcpd/api.go @@ -14,17 +14,22 @@ type DhcpServer struct { mutex sync.RWMutex ackChannels map[string]chan struct{} // Key: IPaddr. ipAddrToMacAddr map[string]string // Key: IPaddr, V: MACaddr. - leases map[string]proto.Address // Key: MACaddr, V: Address. + leases map[string]leaseType // Key: MACaddr. requestChannels map[string]chan net.IP // Key: MACaddr. subnets []proto.Subnet } +type leaseType struct { + proto.Address + Hostname string +} + func New(bridges []string, logger log.DebugLogger) (*DhcpServer, error) { return newServer(bridges, logger) } -func (s *DhcpServer) AddLease(address proto.Address) { - s.addLease(address) +func (s *DhcpServer) AddLease(address proto.Address, hostname string) { + s.addLease(address, hostname) } func (s *DhcpServer) AddSubnet(subnet proto.Subnet) { diff --git a/hypervisor/dhcpd/impl.go b/hypervisor/dhcpd/impl.go index 6b998620..045408f1 100644 --- a/hypervisor/dhcpd/impl.go +++ b/hypervisor/dhcpd/impl.go @@ -13,12 +13,31 @@ import ( const sysClassNet = "/sys/class/net" const leaseTime = time.Hour * 48 +func makeOptions(subnet *proto.Subnet, lease *leaseType) dhcp.Options { + dnsServers := make([]byte, 0) + for _, dnsServer := range subnet.DomainNameServers { + dnsServers = append(dnsServers, dnsServer...) + } + leaseOptions := dhcp.Options{ + dhcp.OptionSubnetMask: subnet.IpMask, + dhcp.OptionRouter: subnet.IpGateway, + dhcp.OptionDomainNameServer: dnsServers, + } + if subnet.DomainName != "" { + leaseOptions[dhcp.OptionDomainName] = []byte(subnet.DomainName) + } + if lease.Hostname != "" { + leaseOptions[dhcp.OptionHostName] = []byte(lease.Hostname) + } + return leaseOptions +} + func newServer(bridges []string, logger log.DebugLogger) (*DhcpServer, error) { dhcpServer := &DhcpServer{ logger: logger, ackChannels: make(map[string]chan struct{}), ipAddrToMacAddr: make(map[string]string), - leases: make(map[string]proto.Address), + leases: make(map[string]leaseType), requestChannels: make(map[string]chan net.IP), } if myIP, err := util.GetMyIP(); err != nil { @@ -60,7 +79,7 @@ func (s *DhcpServer) acknowledgeLease(ipAddr net.IP) { } } -func (s *DhcpServer) addLease(address proto.Address) { +func (s *DhcpServer) addLease(address proto.Address, hostname string) { address.Shrink() if len(address.IpAddress) < 1 { return @@ -69,7 +88,7 @@ func (s *DhcpServer) addLease(address proto.Address) { s.mutex.Lock() defer s.mutex.Unlock() s.ipAddrToMacAddr[ipAddr] = address.MacAddress - s.leases[address.MacAddress] = address + s.leases[address.MacAddress] = leaseType{address, hostname} } func (s *DhcpServer) addSubnet(subnet proto.Subnet) { @@ -78,20 +97,20 @@ func (s *DhcpServer) addSubnet(subnet proto.Subnet) { s.subnets = append(s.subnets, subnet) } -func (s *DhcpServer) findLease(macAddr string) (*proto.Address, *proto.Subnet) { +func (s *DhcpServer) findLease(macAddr string) (*leaseType, *proto.Subnet) { s.mutex.RLock() defer s.mutex.RUnlock() - if address, ok := s.leases[macAddr]; !ok { + if lease, ok := s.leases[macAddr]; !ok { return nil, nil } else { for _, subnet := range s.subnets { subnetMask := net.IPMask(subnet.IpMask) subnetAddr := subnet.IpGateway.Mask(subnetMask) - if address.IpAddress.Mask(subnetMask).Equal(subnetAddr) { - return &address, &subnet + if lease.IpAddress.Mask(subnetMask).Equal(subnetAddr) { + return &lease, &subnet } } - return &address, nil + return &lease, nil } } @@ -158,15 +177,7 @@ func (s *DhcpServer) ServeDHCP(req dhcp.Packet, msgType dhcp.MessageType, } s.logger.Debugf(0, "DHCP Offer: %s for: %s, server: %s\n", lease.IpAddress, macAddr, s.myIP) - dnsServers := make([]byte, 0) - for _, dnsServer := range subnet.DomainNameServers { - dnsServers = append(dnsServers, dnsServer...) - } - leaseOptions := dhcp.Options{ - dhcp.OptionSubnetMask: subnet.IpMask, - dhcp.OptionRouter: subnet.IpGateway, - dhcp.OptionDomainNameServer: dnsServers, - } + leaseOptions := makeOptions(subnet, lease) return dhcp.ReplyPacket(req, dhcp.Offer, s.myIP, lease.IpAddress, leaseTime, leaseOptions.SelectOrderOrAll( @@ -201,15 +212,7 @@ func (s *DhcpServer) ServeDHCP(req dhcp.Packet, msgType dhcp.MessageType, return nil } if reqIP.Equal(lease.IpAddress) { - dnsServers := make([]byte, 0) - for _, dnsServer := range subnet.DomainNameServers { - dnsServers = append(dnsServers, dnsServer...) - } - leaseOptions := dhcp.Options{ - dhcp.OptionSubnetMask: subnet.IpMask, - dhcp.OptionRouter: subnet.IpGateway, - dhcp.OptionDomainNameServer: dnsServers, - } + leaseOptions := makeOptions(subnet, lease) s.logger.Debugf(0, "DHCP ACK for: %s to: %s\n", reqIP, macAddr) s.acknowledgeLease(lease.IpAddress) return dhcp.ReplyPacket(req, dhcp.ACK, s.myIP, reqIP, leaseTime, diff --git a/hypervisor/httpd/showVM.go b/hypervisor/httpd/showVM.go index 8985f2d6..0e93c374 100644 --- a/hypervisor/httpd/showVM.go +++ b/hypervisor/httpd/showVM.go @@ -61,6 +61,9 @@ func (s state) showVMHandler(w http.ResponseWriter, req *http.Request) { } else { writeString(writer, "IP Address", ipAddr) } + if vm.Hostname != "" { + writeString(writer, "Hostname", vm.Hostname) + } writeString(writer, "MAC Address", vm.Address.MacAddress) if vm.ImageName != "" { image := fmt.Sprintf("%s", diff --git a/hypervisor/manager/api.go b/hypervisor/manager/api.go index 262392db..6eb5cccb 100644 --- a/hypervisor/manager/api.go +++ b/hypervisor/manager/api.go @@ -18,7 +18,7 @@ type addressPoolType struct { } type DhcpServer interface { - AddLease(address proto.Address) + AddLease(address proto.Address, hostname string) AddSubnet(subnet proto.Subnet) MakeAcknowledgmentChannel(ipAddr net.IP) <-chan struct{} MakeRequestChannel(macAddr string) <-chan net.IP diff --git a/hypervisor/manager/vm.go b/hypervisor/manager/vm.go index ac9109d4..e62db412 100644 --- a/hypervisor/manager/vm.go +++ b/hypervisor/manager/vm.go @@ -178,6 +178,7 @@ func (m *Manager) allocateVm(req proto.CreateVmRequest) (*vmInfoType, error) { vm := &vmInfoType{ VmInfo: proto.VmInfo{ Address: address, + Hostname: req.Hostname, ImageName: req.ImageName, ImageURL: req.ImageURL, MemoryInMiB: req.MemoryInMiB, @@ -1116,7 +1117,7 @@ func (vm *vmInfoType) startManaging(dhcpTimeout time.Duration) (bool, error) { vm.logger.Println("unknown state: " + vm.State.String()) return false, nil } - vm.manager.DhcpServer.AddLease(vm.Address) + vm.manager.DhcpServer.AddLease(vm.Address, vm.Hostname) monitorSock, err := net.Dial("unix", vm.monitorSockname) if err != nil { vm.logger.Debugf(0, "error connecting to: %s: %s\n", From df2ca8213ed127c998fb5661f4e369bbd13552a9 Mon Sep 17 00:00:00 2001 From: Richard Gooch Date: Thu, 17 May 2018 08:03:26 -0700 Subject: [PATCH 3/3] Add -vmHostname option to vm-control tool. --- cmd/vm-control/createVm.go | 1 + cmd/vm-control/main.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/vm-control/createVm.go b/cmd/vm-control/createVm.go index e2f80da7..266d091b 100644 --- a/cmd/vm-control/createVm.go +++ b/cmd/vm-control/createVm.go @@ -85,6 +85,7 @@ func createVmOnHypervisor(hypervisor string, logger log.DebugLogger) error { request := proto.CreateVmRequest{ DhcpTimeout: *dhcpTimeout, VmInfo: proto.VmInfo{ + Hostname: *vmHostname, MemoryInMiB: *memory, MilliCPUs: *milliCPUs, OwnerGroups: ownerGroups, diff --git a/cmd/vm-control/main.go b/cmd/vm-control/main.go index e7b73ffa..4b18870b 100644 --- a/cmd/vm-control/main.go +++ b/cmd/vm-control/main.go @@ -51,7 +51,8 @@ var ( "If true, trace metadata calls until interrupted") userDataFile = flag.String("userDataFile", "", "Name file containing user-data accessible from the metadata server") - vmTags tags.Tags + vmHostname = flag.String("vmHostname", "", "Hostname for VM") + vmTags tags.Tags logger log.DebugLogger )