Index node database for daemon to make lookups always instantaneous
This commit is contained in:
@@ -83,6 +83,34 @@ func DaemonStatus() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func DaemonReload() error {
|
||||
if util.IsFile(WAREWULFD_PIDFILE) == false {
|
||||
wwlog.Printf(wwlog.INFO, "Warewulf daemon process not running (%s)\n", WAREWULFD_PIDFILE)
|
||||
return nil
|
||||
}
|
||||
|
||||
dat, err := ioutil.ReadFile(WAREWULFD_PIDFILE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, _ := strconv.Atoi(string(dat))
|
||||
process, err := os.FindProcess(pid)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to find process: %s\n", err)
|
||||
return err
|
||||
} else {
|
||||
err := process.Signal(syscall.Signal(syscall.SIGHUP))
|
||||
if err != nil {
|
||||
fmt.Printf("SIGCONT on pid %d returned: %v\n", pid, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DaemonStop() error {
|
||||
|
||||
if util.IsFile(WAREWULFD_PIDFILE) == false {
|
||||
|
||||
@@ -30,19 +30,14 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
url := strings.Split(req.URL.Path, "/")
|
||||
var unconfiguredNode bool
|
||||
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
log.Printf("Could not read node configuration file: %s\n", err)
|
||||
w.WriteHeader(503)
|
||||
return
|
||||
}
|
||||
|
||||
if url[2] == "" {
|
||||
log.Printf("ERROR: Bad iPXE request from %s\n", req.RemoteAddr)
|
||||
w.WriteHeader(404)
|
||||
return
|
||||
}
|
||||
|
||||
hwaddr := strings.ReplaceAll(url[2], "-", ":")
|
||||
|
||||
conf, err := warewulfconf.New()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
@@ -50,16 +45,22 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
hwaddr := strings.ReplaceAll(url[2], "-", ":")
|
||||
nodeobj, err := GetNode(hwaddr)
|
||||
|
||||
n, err := nodeDB.FindByHwaddr(hwaddr)
|
||||
if err != nil {
|
||||
// If we failed to find a node, let's see if we can add one...
|
||||
var netdev string
|
||||
|
||||
nodeDB, err := node.New()
|
||||
if err != nil {
|
||||
log.Printf("Could not read node configuration file: %s\n", err)
|
||||
w.WriteHeader(503)
|
||||
return
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node was not found, looking for discoverable nodes...\n")
|
||||
|
||||
n, netdev, err = nodeDB.FindDiscoverableNode()
|
||||
n, netdev, err := nodeDB.FindDiscoverableNode()
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.WARN, "No nodes are set as discoverable...\n")
|
||||
unconfiguredNode = true
|
||||
@@ -79,6 +80,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
wwlog.Printf(wwlog.ERROR, "Could not persist new node configuration while adding node: %s\n", n.Id.Get())
|
||||
unconfiguredNode = true
|
||||
} else {
|
||||
nodeobj = n
|
||||
wwlog.Printf(wwlog.INFO, "Building System Overlay:\n")
|
||||
_ = overlay.BuildSystemOverlay([]node.NodeInfo{n})
|
||||
wwlog.Printf(wwlog.INFO, "Building Runtime Overlay:\n")
|
||||
@@ -110,9 +112,10 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
|
||||
} else {
|
||||
log.Printf("IPXE: %15s: %s\n", n.Id.Get(), req.URL.Path)
|
||||
|
||||
ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/%s.ipxe", n.Ipxe.Get())
|
||||
log.Printf("IPXE: %15s: %s\n", nodeobj.Id.Get(), req.URL.Path)
|
||||
|
||||
ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/%s.ipxe", nodeobj.Ipxe.Get())
|
||||
|
||||
tmpl, err := template.ParseFiles(ipxeTemplate)
|
||||
if err != nil {
|
||||
@@ -122,14 +125,14 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
var replace iPxeTemplate
|
||||
|
||||
replace.Fqdn = n.Id.Get()
|
||||
replace.Fqdn = nodeobj.Id.Get()
|
||||
replace.Ipaddr = conf.Ipaddr
|
||||
replace.Port = strconv.Itoa(conf.Warewulf.Port)
|
||||
replace.Hostname = n.Id.Get()
|
||||
replace.Hostname = nodeobj.Id.Get()
|
||||
replace.Hwaddr = url[2]
|
||||
replace.ContainerName = n.ContainerName.Get()
|
||||
replace.KernelArgs = n.KernelArgs.Get()
|
||||
replace.KernelVersion = n.KernelVersion.Get()
|
||||
replace.ContainerName = nodeobj.ContainerName.Get()
|
||||
replace.KernelArgs = nodeobj.KernelArgs.Get()
|
||||
replace.KernelVersion = nodeobj.KernelVersion.Get()
|
||||
|
||||
err = tmpl.Execute(w, replace)
|
||||
if err != nil {
|
||||
@@ -137,7 +140,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("SEND: %15s: %s\n", n.Id.Get(), ipxeTemplate)
|
||||
log.Printf("SEND: %15s: %s\n", nodeobj.Id.Get(), ipxeTemplate)
|
||||
|
||||
}
|
||||
return
|
||||
|
||||
64
internal/pkg/warewulfd/nodedb.go
Normal file
64
internal/pkg/warewulfd/nodedb.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package warewulfd
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type nodeDB struct {
|
||||
lock sync.RWMutex
|
||||
NodeInfo map[string]node.NodeInfo
|
||||
}
|
||||
|
||||
var (
|
||||
db nodeDB
|
||||
)
|
||||
|
||||
func LoadNodeDB() error {
|
||||
|
||||
var TmpMap map[string]node.NodeInfo
|
||||
TmpMap = make(map[string]node.NodeInfo)
|
||||
|
||||
wwlog.Printf(wwlog.INFO, "Loading the node Database\n")
|
||||
|
||||
DB, err := node.New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodes, err := DB.FindAllNodes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, n := range nodes {
|
||||
for _, netdev := range n.NetDevs {
|
||||
wwlog.Printf(wwlog.DEBUG, "Caching node entry: '%s' -> %s\n", netdev.Hwaddr.Get(), n.Id.Get())
|
||||
|
||||
TmpMap[netdev.Hwaddr.Get()] = n
|
||||
}
|
||||
}
|
||||
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
db.NodeInfo = TmpMap
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetNode(val string) (node.NodeInfo, error) {
|
||||
db.lock.RLock()
|
||||
defer db.lock.RUnlock()
|
||||
|
||||
if _, ok := db.NodeInfo[val]; ok {
|
||||
wwlog.Printf(wwlog.DEBUG, "Found node:\n%+v\n", db.NodeInfo[val])
|
||||
|
||||
return db.NodeInfo[val], nil
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Node not found in DB: %s\n", val)
|
||||
var empty node.NodeInfo
|
||||
return empty, errors.New("No node found")
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package warewulfd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||
"io"
|
||||
@@ -14,22 +13,18 @@ import (
|
||||
|
||||
func getSanity(req *http.Request) (node.NodeInfo, error) {
|
||||
url := strings.Split(req.URL.Path, "/")
|
||||
var ret node.NodeInfo
|
||||
|
||||
nodes, err := node.New()
|
||||
if err != nil {
|
||||
return ret, errors.New(fmt.Sprintf("%s", err))
|
||||
}
|
||||
|
||||
hwaddr := strings.ReplaceAll(url[2], "-", ":")
|
||||
ret, err = nodes.FindByHwaddr(hwaddr)
|
||||
|
||||
nodeobj, err := GetNode(hwaddr)
|
||||
if err != nil {
|
||||
var ret node.NodeInfo
|
||||
return ret, errors.New("Could not find node by HW address")
|
||||
}
|
||||
|
||||
log.Printf("REQ: %15s: %s\n", ret.Id.Get(), req.URL.Path)
|
||||
log.Printf("REQ: %15s: %s\n", nodeobj.Id.Get(), req.URL.Path)
|
||||
|
||||
return ret, nil
|
||||
return nodeobj, nil
|
||||
}
|
||||
|
||||
func sendFile(w http.ResponseWriter, filename string, sendto string) error {
|
||||
|
||||
Reference in New Issue
Block a user