Skip to content

Commit

Permalink
Merge pull request #443 from rgooch/master
Browse files Browse the repository at this point in the history
Support specifying domain and host name in Hypervisor DHCP leases.
  • Loading branch information
rgooch authored May 17, 2018
2 parents 94d12a2 + df2ca82 commit 5304687
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 32 deletions.
1 change: 1 addition & 0 deletions cmd/vm-control/createVm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion cmd/vm-control/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
11 changes: 8 additions & 3 deletions hypervisor/dhcpd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
55 changes: 29 additions & 26 deletions hypervisor/dhcpd/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -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
}
}

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions hypervisor/httpd/showVM.go
Original file line number Diff line number Diff line change
Expand Up @@ -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("<a href=\"http://%s/showImage?%s\">%s</a>",
Expand Down
2 changes: 1 addition & 1 deletion hypervisor/manager/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion hypervisor/manager/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions proto/hypervisor/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
Expand Down

0 comments on commit 5304687

Please sign in to comment.