Skip to content

Commit

Permalink
Merge branch 'local_feature'
Browse files Browse the repository at this point in the history
  • Loading branch information
farnasirim committed Jan 23, 2016
2 parents b61e8e5 + 135899c commit 3ae5659
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 17 deletions.
19 changes: 10 additions & 9 deletions blacksmith.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ var (
listenIFFlag = flag.String("if", "0.0.0.0", "Interface name for DHCP and PXE to listen on")
workspacePathFlag = flag.String("workspace", "/workspace", workspacePathHelp)
etcdFlag = flag.String("etcd", "", "Etcd endpoints")
etcdDirFlag = flag.String("etcd-dir", "blacksmith", "The etcd directory prefix")
clusterNameFlag = flag.String("cluster-name", "blacksmith", "The name of this cluster. Will be used as etcd path prefixes.")

leaseStartFlag = flag.String("lease-start", "", "Begining of lease starting IP")
leaseRangeFlag = flag.Int("lease-range", 0, "Lease range")
leaseSubnetFlag = flag.String("lease-subnet", "", "Subnet of specified lease")
leaseRouterFlag = flag.String("router", "", "Default router that assigned to DHCP clients")
leaseDNSFlag = flag.String("dns", "", "Default DNS that assigned to DHCP clients")
leaseDNSFlag = flag.String("dns", "8.8.8.8", "comma separated IPs which will be used as default nameservers for skydns.")

version string
commit string
Expand Down Expand Up @@ -106,7 +106,7 @@ func main() {
}

// etcd config
if etcdFlag == nil || etcdDirFlag == nil {
if etcdFlag == nil || clusterNameFlag == nil {
fmt.Fprint(os.Stderr, "\nPlease specify the etcd endpoints\n")
os.Exit(1)
}
Expand All @@ -116,7 +116,7 @@ func main() {
if *listenIFFlag != "" {
dhcpIF, err = net.InterfaceByName(*listenIFFlag)
if err != nil {
fmt.Fprint(os.Stderr, "\nError while trying to get the interface: %s\n")
fmt.Fprint(os.Stderr, "\nError while trying to get the interface")
os.Exit(1)
}
} else {
Expand All @@ -126,7 +126,7 @@ func main() {

serverIP, err := interfaceIP(dhcpIF)
if err != nil {
fmt.Fprint(os.Stderr, "\nError while trying to get the ip from the interface: %s\n")
fmt.Fprint(os.Stderr, "\nError while trying to get the ip from the interface")
os.Exit(1)
}

Expand All @@ -146,7 +146,7 @@ func main() {
leaseRange := *leaseRangeFlag
leaseSubnet := net.ParseIP(*leaseSubnetFlag)
leaseRouter := net.ParseIP(*leaseRouterFlag)
leaseDNS := net.ParseIP(*leaseDNSFlag)
dnsIPStrings := strings.Split(*leaseDNSFlag, ",")

if leaseStart == nil {
fmt.Fprint(os.Stderr, "\nPlease specify the lease start ip\n")
Expand All @@ -164,7 +164,7 @@ func main() {
fmt.Fprint(os.Stderr, "\nPlease specify the IP address of network router\n")
os.Exit(1)
}
if leaseDNS == nil {
if len(dnsIPStrings) == 0 {
fmt.Fprint(os.Stderr, "\nPlease specify an DNS server\n")
os.Exit(1)
}
Expand All @@ -183,7 +183,8 @@ func main() {
}
kapi := etcd.NewKeysAPI(etcdClient)

etcdDataSource, err := datasource.NewEtcdDataSource(kapi, etcdClient, leaseStart, leaseRange, *etcdDirFlag, *workspacePathFlag)
etcdDataSource, err := datasource.NewEtcdDataSource(kapi, etcdClient, leaseStart,
leaseRange, *clusterNameFlag, *workspacePathFlag, serverIP, dnsIPStrings)
if err != nil {
fmt.Fprintf(os.Stderr, "\nCouldn't create runtime configuration: %s\n", err)
os.Exit(1)
Expand Down Expand Up @@ -244,7 +245,7 @@ func main() {
ServerIP: serverIP,
RouterAddr: leaseRouter,
SubnetMask: leaseSubnet,
DNSAddr: leaseDNS,
DNSAddr: net.ParseIP(dnsIPStrings[0]),
}, etcdDataSource)
log.Fatalf("\nError while serving dhcp: %s\n", err)
}()
Expand Down
60 changes: 55 additions & 5 deletions datasource/etcd_datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ type EtcdDataSource struct {
client etcd.Client
leaseStart net.IP
leaseRange int
etcdDir string
clusterName string
workspacePath string
initialCoreOSVersion string
dhcpAssignLock *sync.Mutex
dhcpDataLock *sync.Mutex
instancesEtcdDir string // HA
serverIP net.IP
}

// WorkspacePath is self explanatory
Expand Down Expand Up @@ -137,6 +138,11 @@ func (ds *EtcdDataSource) CreateMachine(mac net.HardwareAddr, ip net.IP) (Machin
defer cancel3()
ds.keysAPI.Set(ctx3, ds.prefixify("machines/"+machine.Name()+"/_first_seen"),
strconv.FormatInt(time.Now().UnixNano(), 10), &etcd.SetOptions{})

ctx4, cancel4 := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel4()
ds.keysAPI.Set(ctx4, "skydns/"+ds.clusterName+"/"+machine.Name(), fmt.Sprintf(`{"host":"%s"}`, ip.String()), nil)

machine.CheckIn()
machine.SetFlag("state", "unknown")
return machine, true
Expand All @@ -163,7 +169,7 @@ func (ds *EtcdDataSource) CoreOSVersion() (string, error) {
}

func (ds *EtcdDataSource) prefixify(key string) string {
return path.Join(ds.etcdDir, key)
return path.Join(ds.clusterName, key)
}

// Get parses the etcd key and returns it's value
Expand Down Expand Up @@ -407,6 +413,30 @@ func (ds *EtcdDataSource) LeaseRange() int {
return ds.leaseRange
}

func ipStringToBytes(ip string) []byte {
return net.ParseIP(ip).To4()
}

// DNSAddresses returns the ip addresses of the present skydns servers in the
// network, marshalled as specified in rfc2132 (option 6)
// part of DHCPDataSource ineterface implementation
func (ds *EtcdDataSource) DNSAddresses() ([]byte, error) {
ret := make([]byte, 0)

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
response, err := ds.keysAPI.Get(ctx, ds.prefixify(instancesEtcdDir), &etcd.GetOptions{Recursive: false})
if err != nil {
return ret, err
}
for _, ent := range response.Node.Nodes {
ipString := ent.Value

ret = append(ret, ipStringToBytes(ipString)...)
}
return ret, nil
}

func (ds *EtcdDataSource) lockDHCPAssign() {
ds.dhcpAssignLock.Lock()
}
Expand Down Expand Up @@ -519,7 +549,7 @@ func (ds *EtcdDataSource) Request(nic string, currentIP net.IP) (net.IP, error)
// NewEtcdDataSource gives blacksmith the ability to use an etcd endpoint as
// a MasterDataSource
func NewEtcdDataSource(kapi etcd.KeysAPI, client etcd.Client, leaseStart net.IP,
leaseRange int, etcdDir, workspacePath string) (MasterDataSource, error) {
leaseRange int, clusterName, workspacePath string, serverIP net.IP, defaultNameServers []string) (MasterDataSource, error) {

data, err := ioutil.ReadFile(filepath.Join(workspacePath, "initial.yaml"))
if err != nil {
Expand All @@ -540,14 +570,15 @@ func NewEtcdDataSource(kapi etcd.KeysAPI, client etcd.Client, leaseStart net.IP,
instance := &EtcdDataSource{
keysAPI: kapi,
client: client,
etcdDir: etcdDir,
clusterName: clusterName,
leaseStart: leaseStart,
leaseRange: leaseRange,
workspacePath: workspacePath,
initialCoreOSVersion: iVals.CoreOSVersion,
dhcpAssignLock: &sync.Mutex{},
dhcpDataLock: &sync.Mutex{},
instancesEtcdDir: invalidEtcdKey,
serverIP: serverIP,
}

_, err = instance.CoreOSVersion()
Expand All @@ -561,7 +592,7 @@ func NewEtcdDataSource(kapi etcd.KeysAPI, client etcd.Client, leaseStart net.IP,
if err != nil {
return nil, fmt.Errorf("Error while initializing etcd tree: %s", err)
}
fmt.Printf("Initialized etcd tree (%s)", etcdDir)
fmt.Printf("Initialized etcd tree (%s)", clusterName)
} else {
return nil, fmt.Errorf("Error while checking GetCoreOSVersion: %s", err)
}
Expand All @@ -571,5 +602,24 @@ func NewEtcdDataSource(kapi etcd.KeysAPI, client etcd.Client, leaseStart net.IP,
defer cancel()
instance.keysAPI.Set(ctx, instance.prefixify("machines"), "", &etcd.SetOptions{Dir: true})

ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel2()
instance.keysAPI.Set(ctx2, "skydns", "", &etcd.SetOptions{Dir: true})

ctx3, cancel3 := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel3()
instance.keysAPI.Set(ctx3, "skydns/"+instance.clusterName, "", &etcd.SetOptions{Dir: true})
quoteEnclosedNameservers := make([]string, 0)
for _, v := range defaultNameServers {
quoteEnclosedNameservers = append(quoteEnclosedNameservers, fmt.Sprintf(`"%s"`, v))
}
commaSeparatedQouteEnclosedNameservers := strings.Join(quoteEnclosedNameservers, ",")

skydnsconfig := fmt.Sprintf(`{"dns_addr":"%s:53","nameservers":[%s],"domain":"%s."}`,
instance.serverIP.String(), commaSeparatedQouteEnclosedNameservers, clusterName)
ctx4, cancel4 := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel4()
instance.keysAPI.Set(ctx4, "skydns/config", skydnsconfig, nil)

return instance, nil
}
4 changes: 2 additions & 2 deletions datasource/hacluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (ds *EtcdDataSource) registerOnEtcd() error {
masterOrderOption := etcd.CreateInOrderOptions{
TTL: MasterTtlTime,
}
resp, err := ds.keysAPI.CreateInOrder(ctx, ds.prefixify(instancesEtcdDir), "", &masterOrderOption)
resp, err := ds.keysAPI.CreateInOrder(ctx, ds.prefixify(instancesEtcdDir), ds.serverIP.String(), &masterOrderOption)
if err != nil {
return err
}
Expand All @@ -41,7 +41,7 @@ func (ds *EtcdDataSource) etcdHeartbeat() error {
PrevExist: etcd.PrevExist,
TTL: MasterTtlTime,
}
_, err := ds.keysAPI.Set(ctx, ds.instancesEtcdDir, "", &masterSetOption)
_, err := ds.keysAPI.Set(ctx, ds.instancesEtcdDir, ds.serverIP.String(), &masterSetOption)
return err
}

Expand Down
6 changes: 6 additions & 0 deletions datasource/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ type DHCPDataSource interface {

// Request is how to client requests to use the Ip address
Request(nic string, currentIP net.IP) (net.IP, error)

// DNSAddresses returns addresses of the dns servers present in the network which
// can answer "what is the ip address of nodeX ?"
// a byte slice is returned to be used as option 6 (rfc2132) in a dhcp Request
// reply packet
DNSAddresses() ([]byte, error)
}

// RestServer defines the interface that a rest server has to implement to work
Expand Down
5 changes: 4 additions & 1 deletion dhcp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ func (h *DHCPHandler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, optio
logging.Log("DHCP", "dhcp request - CHADDR %s - Requested IP %s - ACCEPTED", p.CHAddr().String(), requestedIP.String())
}
packet.AddOption(12, []byte("node"+macAddress)) // host name option

dns, err := h.datasource.DNSAddresses()
if err == nil {
packet.AddOption(6, dns)
}
return packet
case dhcp4.Release, dhcp4.Decline:

Expand Down

0 comments on commit 3ae5659

Please sign in to comment.